![]() |
Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Hallo ihr da draussen, die an diesem Samstagabend auch nix besseres zu tun haben als in der Stube zu hocken und sich mit Delphi rumzuquälen :-)
Mein Problem heute: ich möchte ein Edit-Feld zur Laufzeit auf dem Formular verschieben können. Das habe ich nach folgendem Prinzip gelöst (der Code ist nicht von mir, habe ihn von einer Delphi-Website :-)):
Delphi-Quellcode:
Mit diesem Code (etwas geändert, so dass ich damit ein Edit-Feld bewege und nicht Image1), klappt es ganz gut. Das Problem ist jedoch, dass an das Edit-Feld auch ein Label "angekoppelt" werden soll, so dass es sich gemeinsam bewegt.
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; begin ReleaseCapture; TWinControl(Image1).perform(wm_syscommand,sc_dragmove, 0); end; Hat jemand eine Ahnung, wie ich das hinbekommen könnte? MfG davar |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Nimm anstelle eines Labels ein TStaticText und mach's so:
(ungetestet)
Delphi-Quellcode:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; begin ReleaseCapture; TWinControl(Image1).perform(wm_syscommand,sc_dragmove, 0); TWinControl(StaticText1).perform(wm_syscommand,sc_dragmove, 0); end; |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Geändert hat sich nichts. Verhält sich genauso wie beim Label.
|
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
HI,
Das dürfte genau das machen was du suchst
Delphi-Quellcode:
Mfg ReDoX
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; begin ReleaseCapture; TWinControl(Edit1).perform(wm_syscommand,sc_dragmove, 0); end; procedure TForm1.FormPaint(Sender: TObject); begin Label1.Left := Edit1.Left; Label1.Top := Edit1.Top - Label1.Height; end; |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
da muss man natürlich erst einmal darauf kommen :-)
genau so läuft, es danke! |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Nun kommt jedoch der zweite Schritt, bei dem es wiederum nicht geht..
Das Problem ist nämlich, dass die beiden Komponenten Edit und Label erst zur Laufzeit erstellt werden. Und so kommt eine Fehlermeldung, weil die Komponenten noch gar nicht existieren.. Gibt es einen Befehl, mit dem man abfragen kann, ob eine Komponente existiert? mfg davar |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Hi,
versuche es mal so
Delphi-Quellcode:
Mfg ReDoX
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; ReleaseCapture; TWinControl(FindComponent ('NameDesButtons') as TButton).perform(wm_syscommand,sc_dragmove, 0); end; |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Hi Redox,
bei dem Edit-Feld (das, was auf Mausklick bewegt wird) gibt es keine Probleme. Das Problem macht das Label, das mit dem Edit gemeinsam bewegt werden soll. FormPaint wird ja schon aufgerufen, bevor die Komponenten erstellt werden. mfg davar |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
:?:
Delphi-Quellcode:
Nicht getestet.
if (Assigned(Label1) and (Assigned(Edit1)) )then
begin Label1.Left := Edit1.Left; Label1.Top := Edit1.Top - Label1.Height; end; |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Zitat:
Falls ich dir irgendwann begegnen sollte, lad ich dich zum Essen ein ;-) Vielen Dank, so gehts tatsächlich.. |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Du kannst sonts ja auch ein LabeledEdit (ein Edit mit nem Label verbunden^^) verwenden, dann brauchst du nur eine Komponente verschieben.
|
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Zitat:
Ah, noch was.Man kann es einfacher schreiben:
Delphi-Quellcode:
"checked typecast" ist heir überflussig.
//TWinControl(Edit1).perform(wm_syscommand,sc_dragmove, 0);
Edit1.perform(wm_syscommand,sc_dragmove, 0); |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Hallo!
Ich stöbere grad bissl in der DP rum und da komm ich grad auf diesen Thread und sehe diesen Quelltext:
Delphi-Quellcode:
Hab ich sofort ausprobiert. Funzt! Ich kann auch statt TWinControl(Edit1).... TWinControl(Sender)... schreiben. Funzt auch.
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; begin ReleaseCapture; TWinControl(Edit1).perform(wm_syscommand,sc_dragmove, 0); end; procedure TForm1.FormPaint(Sender: TObject); begin Label1.Left := Edit1.Left; Label1.Top := Edit1.Top - Label1.Height; end; Nun interessiert mich, ob es eine Möglichkeit gibt, statt Image1MouseDown auch ComponentMouseDown zu schreiben, wobei ich damit meine, ob es ne Möglichkeit gibt, das ganze zu verallgemeinern. Ich weiß, das es zum Beispiel so hier geht:
Delphi-Quellcode:
Ich suche aber eine Möglichkeit, eine Komponente zur Laufzeit auf das Formular zu bringen und dann verschieben zu können. Möglichst ohne Erweiterung der Komponenten. Wenn ich beim Schreiben so drüber nachdenke geht das dann wohl doch nur mit Zuweisung der MouseDown Methode an OnMouseDown, wenn die Kompo auf der Form erzeugt wird. Weiterhin dürfte es dann auch nicht mehr allzu schwierig sein, einen Rahmen um die selektierte Kompo zu zeichnen. Der Hintergrund meiner Anfrage -> Lazarus Projekt -> FormDesigner. Den Quelltext dort kapier ich bloß nich. Das ganze sollte dann mit FCL und LCL genau so funzen.
unit main;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Panel1: TPanel; ListBox1: TListBox; Label1: TLabel; Edit1: TEdit; procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormPaint(Sender: TObject); procedure Edit1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; begin ReleaseCapture; TWinControl(Sender).perform(wm_syscommand,sc_dragmove, 0); //Statt Sender kann im Konkreten Fall auch Panel1 stehen //Der OriginalQuelltext verschiebt so ein TEdit end; procedure TForm1.FormPaint(Sender: TObject); begin if Sender is TPanel then begin Label1.Left := TWinControl(Sender).Left; Label1.Top := TWinControl(Sender).Top - Label1.Height; end; end; procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Panel1MouseDown(Sender,Button,Shift,X,Y); end; end. Delphifan2004 |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
ich weiss nicht, ob das gerade die beste Form ist und ob das deine Frage beantwortet, aber wie folgt geht es:
Delphi-Quellcode:
mfg
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } procedure Bewegen(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); var MyEdit: TEdit; begin MyEdit := TEdit.Create(Form1); with MyEdit do begin Parent := Form1; Name := 'Edit1'; Left := 50; Top := 50; OnMouseDown:= Bewegen; end; end; procedure TForm1.Bewegen(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); const sc_dragmove = $f012; begin ReleaseCapture; TEdit(Sender).perform(wm_syscommand,sc_dragmove, 0); end; end. davar |
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
pack das edit und das label auf ein panel und führe das perform auf das Panel aus
|
Re: Zwei Komponenten auf einmal verschieben (zur Laufzeit)
Hallo davar!
Dake erst mal für die schnelle Antwort! Super. Funktionirt! Hab allerdings noch folgendes machen müssen:
Delphi-Quellcode:
habe ich den Zähler einfügen müssen, sonst klappt der Einfügevorgang nur ein einziges mal. Danach kommt Exception: EComponentError -> Meldung: "Es gibt bereits Kompo mit gl. Namen"type TForm1 = class(TForm) private counter: array[0..1] of Integer; //bei mehr Kompos größeres- oder dynamisches Array nehmen public procedure Bewegen... end; implementation procedure TForm1.Button1Click(Sender: TObject); var MyEdit: TEdit; begin MyEdit := TEdit.Create(Form1); with MyEdit do begin Parent := Form1; Name := 'EditKompo' + IntToStr(Counter[0]); // HIER Left := 50; Top := 50; OnMouseDown:= Bewegen; Inc(Counter[0]); // UND HIER end; end; Deshalb der Zähler. Nun hat jede Kompo nen anderen Namen. Noch mal Danke für die schnelle Antwort. Es grüßt Delphifan2004 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz