AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein TImage in Runtime mit Maus verschieben
Thema durchsuchen
Ansicht
Themen-Optionen

TImage in Runtime mit Maus verschieben

Ein Thema von Antonov · begonnen am 11. Apr 2014 · letzter Beitrag vom 12. Apr 2014
Antwort Antwort
Antonov

Registriert seit: 11. Apr 2014
21 Beiträge
 
FreePascal / Lazarus
 
#1

TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 10:36
Hallo,
ich habe vor einigen Wochen mit Delphi programmieren angefangen und stecke noch buchstäblich in den Kinderschuhen.
Derzeit hangele ich mich von Programmbeispiel zu Programmbeispiel, um mir Kenntnisse anzueignen.

Ich plane derzeit eine Oberfläche (momentan Form oder später evtl. Panel) zu designen, wo ich Graphiken (TImage) verschieben möchte per OnMouseDown/Move/Up Events. Das sollte für mich erstmal reichen.
Dazu habe ich folgendes Beispiel im Internet gefunden:
http://delphi.about.com/library/weekly/aa102505a.htm
Funktioniert prima mit allen den dort vorgeführten Buttons. Selber habe ich schon einige andere Controls erschaffen und im Code angepasst, damit ich diese auch bewegen kann.
Leider funktioniert das mit TImage überhaupt nicht! <-- Da liegt genau das Problem.
Internetrecherchen haben nichts gebracht und in der Delphi Hilfe habe ich auch nichts Sinnvolles gefunden. Oder ich bin einfach zu blöd.
Hier brauche ich Hilfe um die Auflösung dieses Problems.


p.s. Falls es sinnvolle Alternativen gibt, Graphiken in Runtime an beliebige Positionen mit der Maus zu bewegen, nennt mir sie bitte!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 10:45
Zitat:
SetCapture(TWinControl(Sender).Handle);
TImage, TLabel, TShape usw. sind keine "eigentständigen" Window-Controls. (TStaticText ist seitens Windows das eigentlich "TLabel")

Diese haben kein eigenes Handle (HWND und vorallem kein eigenes Canvas) und sie zeichnen sich direkt auf ihrem Parent, wo sie sich sich "hinterhältig" reingehäckt haben.


Sooooo, und beim Debuggen, was mal am wirklich lernen sollte, wäre dir aufgefallen, dass dieses TImage kein TWinControl ist und somit der Code in OnMouseDown garnicht ausgeführt wird.
> Denn die Genannten sind alles Nachfahren von TGraphicControl


[edit]
Versuch es mal so:
Delphi-Quellcode:
procedure TForm1.ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if chkPositionRunTime.Checked then
  begin
    inReposition := True;
    GetCursorPos(oldPos);
    if Sender is TWinControl then
      SetCapture(TWinControl(Sender).Handle);
  end;
end;
Und was im OnMouseMove geändert werden muß, weiß ich jetzt nicht direkt, aber tausch dort mal das TWinControl gegen ein TControl aus und schau was von dem code dann nicht mehr geht.

PS: Vorallem als Anfänger würde ich dir empfehlen lieber weiche Castes/Konvertierungen wie (Sender as TWinControl) zu verwenden, anstatt den harten Castes ala TWinControl(Sender) .
Diese lassen sich problemlos austauschen, aber bei den harten Casts ist keine automatisch Typprüfung vorhanden.
Im ControlMouseDown wurde zwar vorher via IS geprüft, aber im ControlMouseMove würde es nun womöglich "ungeprüft" knallen (eine Exception), nach meinen Änderungen im ControlMouseDown.
$2B or not $2B

Geändert von himitsu (11. Apr 2014 um 11:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 11:05
eine Möglichkeit wäre
Delphi-Quellcode:
var
DownPoint:TPoint;

procedure TForm5.ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   DownPoint.X := X;
   DownPoint.Y := Y;
end;

procedure TForm5.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if ssLeft in Shift then
     begin
       TControl(Sender).Left := TControl(Sender).Left - (DownPoint.X - X);
       TControl(Sender).Top := TControl(Sender).Top - (DownPoint.Y - Y);
     end;
end;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Antonov

Registriert seit: 11. Apr 2014
21 Beiträge
 
FreePascal / Lazarus
 
#4

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 19:30
Vielen Dank für die Antworten schonmal!

Das Problem hat sich leider nicht aufgelöst.

@himitsu:
Den Quellcode habe ich eingefügt und statt TWinControl TControl ersetzt. Es hat sich leider nichts geändert.
Als ich rumexperimentierte und statt TWinControl TGraphicControl einfügte, wurde alles compiliert aber ein Exception Fehler trat auf, wodurch das Problem letztendlich nicht gelöst wurde.
Gibt es einen Weg, diese nicht-eigenständigen Controls die nötigen Eigenschaften zu geben?

@Bummi:
Den Quellcode habe ich kopiert (bis auf TForm5, denn ich nutze TForm1) und als Fehlermeldung bekam ich "TForm1 enthält kein Element namens "ImageMouseDown" " .
Außerdem stand dazu noch: "Überladene Prozedur: TForm1.ImageMouseDown muss mit der Direktive 'overload' markiert sein."
So am Rande: Ist dein Code vollständig? Oder funktioniert er eigenständig nicht? Wie gesagt, ich bin noch neu.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 20:04
Sein Code ist für den Anfang erstmal eine einfache Minimalversion zum Testen.
Die müsste dann noch etwas ausgebaut werden.

OnMouseDown des Images: hier rien der Code von ImageMouseDown
OnMouseMove des Images: hier rein der Code von ImageMouseMove

Und zusätzlich nich, denn OnMouseMove arbeites ja immer, egal ob man gedrückt hat, oder nicht.

Entweder im OnMouseMove abfragen, ob die Maustaste gedrückt ist und nur dann den Code ausführen.

Oder im OnMouseDown eine Variable auf True setzen, im OnMouseUp wieder auf False und im OnMouseMove den Code nur ausführen, wenn die Variable True ist.



Es gibt sehr viele mögliche Exceptions, da kann es nie schaden, wenn man etwas genauer wird.
PS: Mit Strg+C kann man direkt aus den Fehlerdialogen die Texte kopieren, genauso wie aus dem Compiler-/Debuggerlog.
$2B or not $2B

Geändert von himitsu (11. Apr 2014 um 20:08 Uhr)
  Mit Zitat antworten Zitat
Antonov

Registriert seit: 11. Apr 2014
21 Beiträge
 
FreePascal / Lazarus
 
#6

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 21:55
[...]

OnMouseDown des Images: hier rien der Code von ImageMouseDown
OnMouseMove des Images: hier rein der Code von ImageMouseMove


[...]

Es gibt sehr viele mögliche Exceptions, da kann es nie schaden, wenn man etwas genauer wird.
Sorry, ich verstehe nicht, was du mit den Aussagen meinst. Soweit der Compiler meint, existiert ImageMouseDown nicht ... oder nicht in dem Kontext. Keine Ahnung.
Die Exception kann ich nicht reproduzieren, keine Ahnung. Ich weiß nicht mehr, was genau ich verändert hatte.

Ich habe den Code jetzt soweit runtergestutzt, wie ich ihn benötige. Also keine Resize mehr und kein Abspeichern der Buttonpositionen nach dem Bewegen. Simples Verschieben mit Checkbox:

Delphi-Quellcode:
unit Unit1;

interface

uses
  IniFiles,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Panel1: TPanel;
    Button2: TButton;
    chkPositionRunTime: TCheckBox;
    Image1: TImage;
    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
  private
    inReposition : boolean;
    oldPos: TPoint;
  end;

var
  Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.ControlMouseDown(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState;
  X, Y: Integer);
begin
  if (chkPositionRunTime.Checked) AND (Sender is TWinControl) then
  begin
    inReposition:=True;
    SetCapture(TWinControl(Sender).Handle);
    GetCursorPos(oldPos);
  end;
end;

procedure TForm1.ControlMouseMove(
  Sender: TObject;
  Shift: TShiftState;
  X, Y: Integer);
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
  if inReposition then
  begin
    with TWinControl(Sender) do
    begin
      GetCursorPos(newPos);
      begin
        Screen.Cursor := crSize;
        Left := Left - oldPos.X + newPos.X;
        Top := Top - oldPos.Y + newPos.Y;
        oldPos := newPos;
      end;
    end;
  end;
end;

procedure TForm1.ControlMouseUp(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if inReposition then
  begin
    Screen.Cursor := crDefault;
    ReleaseCapture;
    inReposition := False;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
Begin

  Button1.OnMouseDown := ControlMouseDown;
  Button1.OnMouseMove := ControlMouseMove;
  Button1.OnMouseUp := ControlMouseUp;

  Edit1.OnMouseDown := ControlMouseDown;
  Edit1.OnMouseMove := ControlMouseMove;
  Edit1.OnMouseUp := ControlMouseUp;

  Panel1.OnMouseDown := ControlMouseDown;
  Panel1.OnMouseMove := ControlMouseMove;
  Panel1.OnMouseUp := ControlMouseUp;

  Button2.OnMouseDown := ControlMouseDown;
  Button2.OnMouseMove := ControlMouseMove;
  Button2.OnMouseUp := ControlMouseUp;

  Image1.OnMouseDown := ControlMouseDown;
  Image1.OnMouseMove := ControlMouseMove;
  Image1.OnMouseUp := ControlMouseUp;
end;

end.
Soweit funktioniert alles. Leider nur nicht die Graphik. Falls jemand Zeit und Lust hat, kann er noch den Teil mit TForm1.OnCreater erklären. Ich verstehe überhaupt nicht, was man da deklariert und was die Bezeichnungen sollen.
Den Rest des Codes verstehe ich einigermaßen, nur nicht wie man Graphiken zum Bewegen bringt.
  Mit Zitat antworten Zitat
DateTimeError
(Gast)

n/a Beiträge
 
#7

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 22:09
Unter gewissen Umständen (und falls es dir nicht allzu viel Mühe macht) wäre es eventuell hilfreich zu wissen, welche Version von Delphi du verwendest
  Mit Zitat antworten Zitat
Antonov

Registriert seit: 11. Apr 2014
21 Beiträge
 
FreePascal / Lazarus
 
#8

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 22:26
Ah, verdammt! Das war es, was ich vergessen hab zu erwähnen!

Ich verwende TurboDelphi 2006, Version 10.0.2288.42451. Die kostenlose Lizenz.
  Mit Zitat antworten Zitat
DateTimeError
(Gast)

n/a Beiträge
 
#9

AW: TImage in Runtime mit Maus verschieben

  Alt 11. Apr 2014, 22:50
Ah, verdammt! Das war es, was ich vergessen hab zu erwähnen!

Ich verwende TurboDelphi 2006, Version 10.0.2288.42451. Die kostenlose Lizenz.
Echt blöd, dass man das nicht ins Benutzerprofil eintragen kann, gell?
  Mit Zitat antworten Zitat
Antonov

Registriert seit: 11. Apr 2014
21 Beiträge
 
FreePascal / Lazarus
 
#10

AW: TImage in Runtime mit Maus verschieben

  Alt 12. Apr 2014, 18:35
@DateTimeError: Ich liebe deinen Humor! Danke für die Infos.

So, das Problem habe ich erledigt.
Nach einigen Tagen intensivem Rumbasteln habe ich den ersten Dreh raus.
Mein Code ist vielleicht nicht hübsch oder effizient, aber er funktioniert!

Hier zum Abschluss nochmal der Quellcode, den ich selbst geschrieben hab.
Prinzipiell schiebe ich das Bild hin und her, solange ich die Maus gedrückt halte. Nebenbei noch eine Checkbox eingefügt:

Delphi-Quellcode:
procedure TForm1.CheckBox1MouseActivate(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y, HitTest: Integer;
  var MouseActivate: TMouseActivate);
begin
     if CheckBox1.checked = false then
     begin
     CheckBox1.Caption := 'Move Mode (click for Static Mode)' ;
     end
     else if CheckBox1.Checked = true then
          begin
           CheckBox1.Caption := 'Static Mode (click for Move Mode)' ;
          end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     CheckBox1.Checked := false ;
     MouseMoveDown := false ;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
      if CheckBox1.checked = true then
      begin
        MouseMoveDown := true;
        GetCursorPos(OldPos);
        DiffX := OldPos.X - Image1.Left ;
        DiffY := OldPos.Y - Image1.Top ;
      end;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
      GetCursorPos(OldPos);
     if MouseMoveDown = true then
     begin
         Image1.Top := OldPos.Y - DiffY;
         Image1.Left := OldPos.X - DiffX ;
     end;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
        MouseMoveDown := false;
end;

end.
Damit ist das Thema erstmal erledigt. Kann geschlossen werden. Vielen Dank an alle!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz