Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Button mit Maus verschieben (https://www.delphipraxis.net/82982-button-mit-maus-verschieben.html)

delphi_help 23. Dez 2006 17:45


Button mit Maus verschieben
 
Hallo,

wie kann man einen Button mit der Maus verschieben lassen (z.b für ein Spiel)?
Ich würde dafür das Ereigniss: OnMouseMove verwenden, doch wie würde dann mein Quelltext dafür aussehen?

Danke

mkinzler 23. Dez 2006 17:47

Re: Button mit Maus verschieben
 
Die Position des Buttons kannst durch Setzen der Eigenschaften .Left, .Top verändern

delphi_help 23. Dez 2006 17:53

Re: Button mit Maus verschieben
 
Ja, soweit war ich schon, nur mein Problem ist, der Button bewegt sich immer nur dann, wenn ich mit der Maus an den linken Rand des Nuttons anstosse, er soll sich aber dann bewegen, wenn die Maus auf der Mitte des Button liegt.

richie 23. Dez 2006 17:55

Re: Button mit Maus verschieben
 
Du könntest im OnMouseMove prüfen, ob die Maus über der Mitte des Buttons ist, was allerdings wahrscheinlich nicht sehr performant wäre.

dominikkv 23. Dez 2006 17:58

Re: Button mit Maus verschieben
 
http://www.swissdelphicenter.ch/de/showcode.php?id=2307

Delphi-Quellcode:
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Dieser Tip enthält eine Klasse mit der man zur Laufzeit Komponenten
 in der Größe verändern bzw verschieben kann so wie man es aus der
 Entwicklungsumgebung her gewohnt ist.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 This Tip provides a tool class that implements the functionality of
 moving or resizing any component at runtime (as in the IDE)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

//Als eigne Unit
unit Egal;

interface

uses Controls, ExtCtrls, QGraphics, Classes, SysUtils, StdCtrls;

type
  Markierungen = class
    constructor Create(Komponente: TControl);
    destructor Destroy();
  private
    panels: array[0..7] of TPanel;
    LblPos: TPanel;
    Komp: TControl;
    FDownX, FDownY: Integer;
    FDragging: Boolean;
    OrgMDown, OrgMUp: TMouseEvent;
    OrgMMove: TMouseMoveEvent;
    OrgMClick: TNotifyEvent;
    procedure panelsMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure panelsMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure panelsMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure NewPos();
  end;

implementation

type
  TMoveCracker = class(TControl);

constructor Markierungen.Create(Komponente: TControl);
var
  i: Byte;
begin
  Komp := Komponente;
  for i := 0 to 7 do
  begin //Die acht Markierungspunkte erstellen.
    panels[i]          := TPanel.Create(Komponente);
    panels[i].Parent   := Komponente.Parent;
    panels[i].Width    := 5;
    panels[i].Height   := 5;
    panels[i].Color    := clBlack;
    panels[i].BevelOuter := bvNone;
    panels[i].OnMouseDown := panelsMouseDown;
    panels[i].OnMouseMove := panelsMouseMove;
    panels[i].OnMouseUp := panelsMouseUp;
    panels[i].Tag      := i;
  end;
  NewPos(); //Die Markierungen an die richtige Position bringen
  OrgMDown := TPanel(Komp).OnMouseDown; //Sicheren der orginalen Mousereignisse
  OrgMUp   := TPanel(Komp).OnMouseUp;
  OrgMMove := TPanel(Komp).OnMouseMove;
  OrgMClick := TPanel(Komp).OnClick;
  TPanel(Komp).OnClick := nil;   //für funktionen benötige Ereignisse zuweisen
  TPanel(Komp).OnMouseDown := panelsMouseDown;
  TPanel(Komp).OnMouseUp := panelsMouseUp;
  TPanel(Komp).OnMouseMove := panelsMouseMove;
  LblPos   := TPanel.Create(Komp); //gibt beim Verschieben größe bzw Position an
  with LblPos do
  begin
    Parent    := Komp.Parent;
    Visible   := False;
    BevelOuter := bvNone;
    Color     := clYellow;
    Height    := 16;
    Width     := 50;
  end;
end;

procedure Markierungen.NewPos();
begin
  panels[0].Left := Komp.Left - 2;
  panels[0].Top := Komp.Top - 2;
  panels[1].Left := Komp.Left + Komp.Width div 2;
  panels[1].Top := Komp.Top - 2;
  panels[2].Left := Komp.Left + Komp.Width - 2;
  panels[2].Top := Komp.Top - 2;
  panels[3].Left := Komp.Left + Komp.Width - 2;
  panels[3].Top := Komp.Top + Komp.Height - 2;
  panels[4].Left := Komp.Left + Komp.Width div 2;
  panels[4].Top := Komp.Top + Komp.Height - 2;
  panels[5].Left := Komp.Left - 2;
  panels[5].Top := Komp.Top + Komp.Height - 2;
  panels[6].Left := Komp.Left - 2;
  panels[6].Top := Komp.Top + Komp.Height div 2 - 1;
  panels[7].Left := Komp.Left + Komp.Width - 2;
  panels[7].Top := Komp.Top + Komp.Height div 2 - 1;
end;

destructor Markierungen.Destroy();
var
  i: Byte;
begin
  TPanel(Komp).OnMouseDown := OrgMDown; //Rückgabe der Orginalen Eregnissprozeduren
  TPanel(Komp).OnMouseUp  := OrgMUp;
  TPanel(Komp).OnMouseMove := OrgMMove;
  TPanel(Komp).OnClick    := OrgMClick;
  for i := 0 to 7 do panels[i].Free;
  LblPos.Free;
end;

procedure Markierungen.panelsMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer); //Funktion aus Swissdelphicenter entnommen
begin                    //Tip: "Komponenten während der Laufzeit verschieben?"
  FDownX        := X;
  FDownY        := Y;
  FDragging     := True;
  TMoveCracker(Sender).MouseCapture := True;
  LblPos.Visible := True;
end;

procedure Markierungen.panelsMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if FDragging then
    with Sender as TControl do
    begin
      if Sender = Komp then
      begin
        Left := X - FDownX + Left; //Es wurde direkt auf die Komponente geklickt
        Top := Y - FDownY + Top;
        LblPos.Caption := '[' + IntToStr(Left) + ',' + IntToStr(Top) + ']';
      end
      else
      begin
        case TPanel(Sender).Tag of
          0:
            begin //oben links
              Komp.Top   := Y - FDownY + TPanel(Sender).Top + 2;
              Komp.Height := Komp.Height - (Y - FDownY);
              Komp.Left  := X - FDownX + TPanel(Sender).Left + 2;
              Komp.Width := Komp.Width - (X - FDownX);
            end;
          1:
            begin //oben mitte
              Komp.Top   := Y - FDownY + TPanel(Sender).Top + 2;
              Komp.Height := Komp.Height - (Y - FDownY);
            end;
          2:
            begin //oben rechts
              Komp.Width := X - FDownX + Komp.Width - 2;
              Komp.Top   := Y - FDownY + TPanel(Sender).Top + 2;
              Komp.Height := Komp.Height - (Y - FDownY);
            end;
          3:
            begin //unten rechts
              Komp.Width := X - FDownX + Komp.Width - 2;
              Komp.Height := Y - FDownY + Komp.Height - 2;
            end;
          4: Komp.Height := Y - FDownY + Komp.Height - 2; //unten mitte
          5:
            begin //unten links
              Komp.Left  := X - FDownX + TPanel(Sender).Left + 2;
              Komp.Width := Komp.Width - (X - FDownX);
              Komp.Height := Y - FDownY + Komp.Height - 2;
            end;
          6:
            begin //nach links
              Komp.Left := X - FDownX + TPanel(Sender).Left + 2;
              Komp.Width := Komp.Width - (X - FDownX);
            end;
          7: Komp.Width := X - FDownX + Komp.Width - 2; //nach rechts
        end;
        LblPos.Caption := '[' + IntToStr(Komp.Width) + ',' + IntToStr(Komp.Height) + ']';
      end;
      newPos(); //zum Nachführen der Markierungspanel
      LblPos.Left := TControl(Sender).Left + X;
      LblPos.Top := TControl(Sender).Top + Y + 20;
      LblPos.BringToFront;
      LblPos.Refresh;
    end;
end;

procedure Markierungen.panelsMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer); //Funktion aus Swissdelphicenter entnommen
begin                    //Tip: "Komponenten während der Laufzeit verschieben?"
  if FDragging then
  begin
    FDragging     := False;
    TMoveCracker(Sender).MouseCapture := False;
    LblPos.Visible := False;
  end;
end;

end.

//In eigenes Programm muss nur noch:

uses Egal;

var
  Veraendern: Markierungen;

  //In diesem Beispiel über ein Onclickereigniss welches jedes auf dem Form befindliche
  //Komponente und das Form selbst bekommt. (Auf Komponente Klicken löst Möglichkeit
  //zum größe ändern und verschieben aus und ein Klick wo anders beendet sie wieder.

procedure TForm1.FormClick(Sender: TObject);
  begin if Assigned(Veraendern) then
begin
  Veraendern.Destroy;
  Veraendern := nil;
end
else
Veraendern := Markierungen.Create(TControl(Sender));

end;

//Will man eine PaintBox benutzen muss man diese noch sichtbar machen.
//Z.B. so:

procedure TForm1.FormShow(Sender: TObject);
  begin PaintBox1Paint(Sender);
  end;

  procedure TForm1.PaintBox1Paint(Sender: TObject);
    begin with PaintBox1 do
  begin
    Canvas.Pen.Style := psDash;
    Canvas.Rectangle(0, 0, Width, Height);
  end;
  end;

delphi_help 23. Dez 2006 18:04

Re: Button mit Maus verschieben
 
Geht das ganze auch ohne Paintbox?

Alexander Roth 23. Dez 2006 18:17

Re: Button mit Maus verschieben
 
Ja. So verstehe ich jedenfalls:
Zitat:

Zitat von dominikkv
//Will man eine PaintBox benutzen muss man diese noch sichtbar machen.

Lass einfach den hinteren Teil weg.

delphi_help 23. Dez 2006 18:33

Re: Button mit Maus verschieben
 
Ist der Quelltext denn wirklich sol lang? Ich meine kann man das nicht einfache bzw. kürzer machen?

Alexander Roth 24. Dez 2006 07:29

Re: Button mit Maus verschieben
 
Das ist für alle arten von Komponenten ein Lösung.
Allgemeine Lösungen sind immer ein bisschen länger als spezielle.

Gruß Alexander

Nils_13 24. Dez 2006 08:55

Re: Button mit Maus verschieben
 
Moin,

irgendwie versteh ich die Verwendung der Unit nicht :gruebel: Wie verschiebt man damit denn jetzt einen Button ? Hat da mal jemand ein kleines Codebeispiel ?

Alexander Roth 24. Dez 2006 09:03

Re: Button mit Maus verschieben
 
So wie ich das verstehe, werden beim createn die ereignisse von form1 und button auf Methoden dieser Klasse umgeleitet und die eigenschaften (left, top) der Komp werden entsprechend verändert.

Gruß Alexander

Nils_13 24. Dez 2006 09:09

Re: Button mit Maus verschieben
 
Hm...ich habe einfach alles abkopiert, um es zu testen, aber bei mir wird bei genau dem gleichen Code nur die Form verschoben, sonst nichts.

Mazel 24. Dez 2006 09:58

Re: Button mit Maus verschieben
 
Hallo,

also wesentlich einfacher geht es so, wenn ich dein Bedürfnis richtig verstanden habe:

Delphi-Quellcode:
procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  //Fängt alle Mausereignisse ab
  ReleaseCapture;
  // mit TWinCotrol verschieben, $F012 verschiebt den Button
  TWinControl(Sender).Perform(WM_SYSCOMMAND, $F012, 0);
end;
Gruß
Mazel

Nils_13 24. Dez 2006 12:33

Re: Button mit Maus verschieben
 
Hey, das funktioniert ja richtig gut :) Kann man eigentlich noch was direktes für die Größenveränderung machen (6 Punkte und damit rezisen) ?

Mazel 24. Dez 2006 12:42

Re: Button mit Maus verschieben
 
Jo, das geht auch:

Statt $F012 kannst du folgende Werte verwenden:

$F001 - ändert Größe nach Links
$F002 - ändert Größe nach Rechts
$F003 - ändert Größe nach Oben
$F006 - ändert Größe nach Unten

$F004 - ändert Größe nach Links, Oben
$F005 - ändert Größe nach Rechts, Oben
$F007 - ändert Größe nach Links, Unten
$F008 - ändert Größe nach Rechts, Unten

Gruß
Mazel

delphi_help 26. Dez 2006 11:57

Re: Button mit Maus verschieben
 
Also, kann man das ganze auch mit OnMouseMover machen, außerdem: wie kann man den Button denn verschieben, ohne auf die Maus zu klicken, es soll eher fü eine Art Spiel (ähnlich wie Magnoid) werden.

Danke

_frank_ 26. Dez 2006 18:14

Re: Button mit Maus verschieben
 
wenn du es ähnlich dem Editor aus der Delphi-IDE machen willst, versuch mal TSizeCtrl von http://angusj.com/delphi/
die Komponente hab ich in meinem DFM-Editor verwendet und funktioniert sehr gut. Ich bin niemand der für jedes kleine Problem eine Komponente installiert, aber diese nimmt einem sehr viel Arbeit ab...

HTH Frank

platan1 23. Mär 2007 22:03

Re: Button mit Maus verschieben
 
Hallo

Suche schon länger nach einer einfachen Art Komponenten zur Laufzeit zu verschieben.
Hab das hier zufällig entdeckt, und es funct super.
Aber ist es möglich das normales Klick Ereignis des Buttons zu kriegen, und erst
wenn man die Maus mit gedrücker li. Taste zb. 5 Pixel bewegt, der Button verschoben wird.
Und das man das beliebig oft wiederholen kann.

Danke mfG.

Cyberbob 24. Mär 2007 01:23

Re: Button mit Maus verschieben
 
Joa, damit kann man alle Komponeten verschieben. Buttons, Panles, Forms. Einfach genial.
Sowas kann man immer mal verwenden.

cruiser 24. Mär 2007 01:46

Re: Button mit Maus verschieben
 
Edit: Das war wohl nix...

@Platan: fang on MouseDown ab, merk dir die Koordinate und verrechne die Koordinate von OnMouseMove damit

torud 5. Apr 2007 20:44

Re: Button mit Maus verschieben
 
Also ich bin völlig überrascht, dass es so einfach geht, denn ich benutze bisher für solche Dinge die Komponente FormDesPro von Greatis, welche um die 100 Euro kostet. Die bietet zwar wesentlich mehr Komfort und man muss die Komponente nicht erst einmal anklicken, um Sie beim nächste mal zu verschieben, oder es gibt verschiedene Cursor für verschiedene Aktionen usw, aber insgesamt würde ich es wirklich begrüssen, wenn man das hier noch etwas verfeinern könnte und weiterentwickelt, denn damit kann man schon öfter was anfangen und wenn jeder was macht, muss keiner dafür Gled ausgeben. Oder?

Ich habe mir in der Unit "egal" noch über Const eine eigene BorderColor eingepflegt. Vielleicht könnte man die Sache auch so gestalten, dass man da noch optional mit shapes arbeitet, um um das ganze Control eine gestrichelte Linie zu erzeugen!? Wer hat denn dazu ne Idee?

ps.: Entschuldigt bitte meine Überschwenglichkeit...:???:

edit: habe gerade festgestellt, dass shapes sich nicht verschieben lassen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:25 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