Butten mit der maus verschieben können

Ich sehe schon, es ist zu kompliziert, um es hier mit Worten zu erklären. Deswegen will ich einmal vollständigen Code hier posten. Den hab ich extra für dich geschrieben :).

Mein Programm hat ein Fenster (namens MainWin) mit einem einzigen Button (namens Button). Wenn du mit der rechten Maustaste auf den Button klickst, kannst du ihn ziehen. Die Variable OldDelta ist notwendig, damit der Button nicht dauernd hin- und herspringt. Wenn man nämlich den Button bewegt, während der Mauszeiger über ihm steht, wird ein neues MouseMove-Ereignis ausgelöst, was wiederum ein Bewegen des Buttons verursacht, was wiederum ein MouseMove-Ereignis verursacht... usw. Mit OldDelta berechne ich, ob sich der Mauszeiger tatsächlich selber bewegt hat oder ob sich nur der Button unter dem Mauszeiger bewegt hat. In letzterem Fall darf der Button nicht erneut bewegt werden.

Ist es das, was du realisieren wolltest? Ich hoffe...
Code:
unit MoveButton_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TMainWin = class(TForm)
    Button: TButton;
    procedure ButtonMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ButtonMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure ButtonMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
    OldPos: TPoint ;
    OldDelta: TPoint ;
    Dragging: Boolean ;
  end;

var
  MainWin: TMainWin;

implementation

{$R *.dfm}

procedure TMainWin.ButtonMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if( Button=mbRight ) then
  begin
    Dragging := True ;
  end ;
end;

procedure TMainWin.ButtonClick(Sender: TObject);
begin
  ShowMessage( 'Clicked' ) ;
end;

procedure TMainWin.FormCreate(Sender: TObject);
begin
  Dragging := False ;
end;

procedure TMainWin.ButtonMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if( Dragging and ((X-OldDelta.X<>OldPos.X) or (Y-OldDelta.Y<>OldPos.Y)) ) then
  begin
    OldDelta.X := OldPos.X-X ;
    OldDelta.Y := OldPos.Y-Y ;
    Button.Left := Button.Left-OldDelta.X ;
    Button.Top := Button.Top-OldDelta.Y ;
  end ;

  OldPos.X := X ;
  OldPos.Y := Y ;
end;

procedure TMainWin.ButtonMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Dragging := False ;
end;

end.
 
Zuletzt bearbeitet:
So, problem gelöst! :)
Das mit den Buttons funktioniert jetzt!
Zwar bewegen sich die Buttons an sich nicht aber wenn man auf den Button
Klickt und ihn zu senem zielort zieht ist an der Maus ein kleines Blatt zu sehen!
Die daten werden also übertragen...
 
100000 Dank! :)

Find ich cool das du dich da extra hingesetzt hast und das geproggt für mich hast!
Bin dir voll dankbar!

Du bist ein schatz!
Küsschen an dich! :-(

Ich weiß gar nicht wie ich dir da danken soll!
 
So, die Buttons kann man ja nun über die Form bewegen!
Nun steht ein weiteres Problem an! :)


Die Coordinaten des Buttons sollen in einem Label ausgegeben werden!
Also wo sich der Button grade auf der Form befindet!
Kann mir da jemand weiterhelfen?

Mfg

ZeroGirl
 
Die Lösung dieser Geschichte ist recht einfach:
Code:
Label.Caption := 'X:'+IntToStr( Button.Left )+'; Y:'+IntToStr( Button.Top ) ;
Gawayn
 
Danke das du mir da wieder einmal weitergeholfen hast!

Da kommen noch zwei weitere fragen auf! :-(

1. Die Koordinaten sollen ja wenn sich der Button bewegt weitergehen!
Wie wäre das zu realisieren?

2. Es bewegt sich ja jetzt nur ein Button, es müssen sich aber auf der Form 20
Button bewegen lassen können! Wenn man Diesen Quelltext für jeden Button
einzeln schreibt wird es ganz schön unübersichtlich!
Ich wollte das jetzt ene procedure schreiben, weis aber nich so wirklich wie
das geht!

Wüstes du da was? :-(
 
Zu 1: Du hast ja den Eventhandler, in dem die Koordinaten des Buttons geändert werden (in meinem Programm die Prozedur ButtonMouseMove). Dort kannst du ja die Befehle zur Anzeige der Koordinaten einbauen. So wird das Label immer automatisch geändert, wenn sich die Position des Buttons ändert.

Zu 2: Wenn du 20 Buttons brauchst, ist es in der Tat etwas unübersichtlich, dafür den Code zu schreiben. Es ist dann besser, die Buttons dynamisch zu erzeugen. Das heißt, du machst dir ein Array von TButtons, z.B.
Code:
const MAX_BUTTONS = 20 ;
var buttons: array[1..MAX_BUTTONS] of TButton;
Dann musst du an einer geeigneten Stelle, z.B. im Eventhandler OnCreate deines Hauptfensters, in einer Schleife all diese Buttons erstellen:
Code:
for i := 1 to MAX_BUTTONS do
  buttons[i] := TButton.Create() ;
Nun existieren die Buttons, allerdings sind ihnen noch keine Positionen, keine OnClick-Handler und keine Beschriftungen zugewiesen worden. Außerdem gibt es noch eine Besonderheit: Die Buttons haben keine Eltern. Damit ein Button auf dem Formular sichtbar wird, muss das Formular als Besitzer des Buttons definiert werden. Das geht mit der Eigenschaft Parent (wenn ich mich recht erinnere):
Code:
buttons[i].Parent := MeinFenster ;
Außerdem stellst du für jeden Button *denselben* OnClick-Handler ein (über die Eigenschaft OnClick). Der OnClick-Handler für die Buttons hat einen Parameter namens Sender. Anhand dieses Parameters kannst du feststellen, von welchem Button der Click kommt, indem du den Sender als TButton behandelst (z.B. per Typecast) und dann z.B. die Eigenschaft Caption abfragst. Dies setzt aber voraus, dass alle Buttons unterschiedliche Captions haben. Alternativ könntest du auch einfach die Eigenschaft Tag der Buttons verwenden, um dort eine eindeutige ID zu speichern, die du im OnClick-Handler abfragst.

Gawayn
 
Das ist echt lieb von dir!
Ohne deine Hilfe wäre ich wohl echt aufgeschmissen! :-(

Ich werde es gleich mal probieren!

HDL

Mfg

ZeroGirl
 
Hier

buttons[ i ] := TButton.Create();

sagt er mir immer diesen fehler an:

[Fehler] Unit1.pas(38): Nicht genügend wirkliche Parameter


Kannst du mir sagen woran es liegt!?
Muss da noch was in die Klammer reingeschrieben werden?
Und wenn ja, was?
 
Zurück