AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Move eines TImage

Ein Thema von Satyr · begonnen am 27. Jun 2013 · letzter Beitrag vom 27. Jun 2013
Antwort Antwort
Satyr

Registriert seit: 8. Feb 2012
Ort: Essen
305 Beiträge
 
Delphi 10.4 Sydney
 
#1

Move eines TImage

  Alt 27. Jun 2013, 19:30
Guten Abend,

ich werkel gerade an einem kleinem Programm das aus mehreren Bildern eine Art Collage erstellt. Vom Grundgerüst recht einfach.
Eine PaintBox, darauf ein gleichgroßes TImage als optionaler Hintergrund. Darauf erzeuge ich dann wieder TImages mit beliebigen Bildinhalten. Das Canvas der PaintBox wird zum Schluss abgespeichert und ich habe das Bild.
Klappt bis dahin auch wunderbar.
Jetzt wollte ich einbauen das man die oberen TImages verschieben kann.
Erst ein einfaches Drag&Drop versucht, welches aber nicht so funktioniert hat wie es sollte. Das Drop war nicht 100% auf den richtigen Koordinaten und der Mauszeiger nicht das TImage.
Also versuche ich momentan schlicht die Komponente zu bewegen. Mit folgendem Code:

Delphi-Quellcode:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 SetCapture(TWinControl(Sender).Handle);
 GetCursorPos(oldPos);
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
    with TImage(Sender) do
    begin
        GetCursorPos(newPos);
        //Screen.Cursor := crSize;
        Left := Left - oldPos.X + newPos.X;
        Top := Top - oldPos.Y + newPos.Y;
        oldPos := newPos;
    end;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    Screen.Cursor := crDefault;
    ReleaseCapture;
end;
Das Problem ist, ich kann es nicht mal versuchen zu testen. Sobald der Mauszeiger über dem betreffenden TImage ist, verschwindet dieses. Komplett. Nichts mehr da.
Ich verstehe einfach nicht wieso.

Jemand eine Idee?

Gruß,
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#2

AW: Move eines TImage

  Alt 27. Jun 2013, 21:01
Delphi-Quellcode:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
    with TImage(Sender) do
    begin
        GetCursorPos(newPos);
        //Screen.Cursor := crSize;
        Left := Left - oldPos.X + newPos.X; // <---
        Top := Top - oldPos.Y + newPos.Y; // <---
        oldPos := newPos;
    end;
end;
Wenn, wie du sagst, der Fehler auftritt, sobald du mit der Maus über dem TImage bist, vermute ich dass es die MouseMove Methode ist die Probleme bereitet. Weißt du deiner Variable oldPos denn irgend eine Anfangsposition zu ? Vielleicht greift er sonst auf eine Stelle zu die gerade im Speicher lag - und dein TImage landet im Nirvana
  Mit Zitat antworten Zitat
Satyr

Registriert seit: 8. Feb 2012
Ort: Essen
305 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Move eines TImage

  Alt 27. Jun 2013, 21:10
Ich habs grade noch mal durchgeguckt. Das wirds sein, das hab ich tatsächlich vergessen. Müsste in den MouseDown, oder?
  Mit Zitat antworten Zitat
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#4

AW: Move eines TImage

  Alt 27. Jun 2013, 22:10
im MouseDown weißt du ihm ja schon die Position zu.
 GetCursorPos(oldPos) Aber den Wert hat er noch nicht wenn du bloß mit der Maus auf dem Image bist - allerdings noch nicht geklickt hast.
Du könntest einfach in deiner OnMouseMove Methode überprüfen ob eine Taste gedrückt wurde:

Delphi-Quellcode:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
  if ssLeft in Shift // würde die Linke Taste gedrückt? (oder welche auch immer du drücken möchtest)
    then with TImage(Sender) do
           begin
             GetCursorPos(newPos);
             //Screen.Cursor := crSize;
             Left := Left - oldPos.X + newPos.X;
             Top := Top - oldPos.Y + newPos.Y;
             oldPos := newPos;
           end;
end;
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#5

AW: Move eines TImage

  Alt 27. Jun 2013, 22:16
Da die nächste Frage vermutlich wird: "Wie speicher ich mehrere Images in einer Datei ab?": Gar nicht, der Ansatz ist dafür ungeeignet. (Man könnte einen Screenshot des Formulars machen und auf die Grenzen der Images zurecht schneiden, aber das ist zum schütteln.)

Der richtige(re) weg wäre das Weglassen von TImage, und statt dessen alles auf einer Paintbox zu malen. Die Einzelbilder sollte man sich in eigenen kleinen Klassen bereit halten, die zum einen ein TBitmap mit dem Bild, zum Anderen die X- und Y-Koordinaten (und ggf. Skalierung) beinhaltet. Dazu noch eine kleine Manager-Klasse, die das Selektieren und Bewegen von den Bildern kapselt, und das Ergebnis auf einen beliebigen Canvas blitten kann (zum Zeichnen auf die Paintbox oder ein TBitmap zum speichern z.B.), und schon wird die Nummer deutlich sauberer und handlicher.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Satyr

Registriert seit: 8. Feb 2012
Ort: Essen
305 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Move eines TImage

  Alt 27. Jun 2013, 22:26
im MouseDown weißt du ihm ja schon die Position zu.
 GetCursorPos(oldPos) Aber den Wert hat er noch nicht wenn du bloß mit der Maus auf dem Image bist - allerdings noch nicht geklickt hast.
Du könntest einfach in deiner OnMouseMove Methode überprüfen ob eine Taste gedrückt wurde:

Delphi-Quellcode:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
  if ssLeft in Shift // würde die Linke Taste gedrückt? (oder welche auch immer du drücken möchtest)
    then with TImage(Sender) do
           begin
             GetCursorPos(newPos);
             //Screen.Cursor := crSize;
             Left := Left - oldPos.X + newPos.X;
             Top := Top - oldPos.Y + newPos.Y;
             oldPos := newPos;
           end;
end;
Danke, das hat mir geholfen. Zwar nicht 1:1 übernommen aber es hat die Richtung gezeigt.
Ich habe mir ein Boolean erstellt und speicher darin ob grade ein Drag stattfindet oder nicht.
Damit geht es perfekt *s*.

@Medium
Das es nicht 100% die sauberste Lösung ist wie ich das mache, ist mir klar. Aber es ist die schnellste. Das wird kein großes Programm, da reicht es quick und leicht dirty. Ich speicher einfach das Canvas der PaintBox ab und habe mein Bild... inkl. aller darüber liegenden Bildern.
Nur wie genau ich die dynamisch erzeugten Bilder bewege weiß ich noch nicht genau. Aber eventuell ist die dynamische Erzeugung nicht nötig. Das muss ich noch abklären.
  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 08:56 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