Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fenster verschieben? (https://www.delphipraxis.net/140096-fenster-verschieben.html)

DualCoreCpu 11. Sep 2009 18:19


Fenster verschieben?
 
Hallo,

Unser Lehrer hat uns die Aufgabe gegeben, eine Fensterverschiebung per Maus zu realisieren.
Leider habe ich von Delphi nicht viel Ahnung. Wir sollen die gesamte Berechnung der Fensterkoordinaten selber machen. Das Fenster soll mit der Maus verschoben werden können.

Hat jemand eine Idee?

DeddyH 11. Sep 2009 18:41

Re: Fenster verschieben?
 
Hallo und Willkommen in der DP :dp:,

diese Aufgabenstellung ist aber mehr als schwammig, da Fenster sich ja normalerweise sowieso schon per Maus verschieben lassen. Bevor wir hier also mutmaßen und an der Aufgabe vorbei Vorschläge machen, solltest Du das noch einmal konkretisieren.

DualCoreCpu 11. Sep 2009 18:58

Re: Fenster verschieben?
 
Hallo DeddyH,

Schwammig? Hmmm! Leider kann ich mich im Moment nicht besser ausdrücken. Klar lassen sich die Fenster normalerweise bereits per Maus verschieben, aber irgendwie müssen das die Programmierer von Windows doch gemacht haben. Irgendwo in den Tiefen von Windows muss doch da ein Algorhithmus stecken. Und den sollen wir nachprogrammieren.

Larsi 11. Sep 2009 19:02

Re: Fenster verschieben?
 
Delphi-Quellcode:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if ssLeft in Shift then
    begin
      ReleaseCapture;
      Form1.Perform(WM_SYSCOMMAND,$F012,0);
    end;
end;
Der Code würde das gewünscht bewirken aber berechnet wird da natrülich von dir nichts. Der Code stammt von DeddyH.

Für den Algorithmus denn du machen willst hilft dir eventuell ClientToScreen.

himitsu 11. Sep 2009 19:02

Re: Fenster verschieben?
 
- man klickt mit der Maus
- diese Position merkt man sich nun
- wird die Maus verschoben, kann man sich die Differenz zu letzen Mausposition ausrechen
- und das Fenster entsprechend verschieben
- usw.

[add]
@Larsi: ich glaub nicht, daß das der Weg ist, den sich der/ein Lehrer wünscht :zwinker:

DeddyH 11. Sep 2009 19:02

Re: Fenster verschieben?
 
Also rate ich doch einmal: ihr sollt die Fenster so programmieren, dass sie sich auch in der Client-Area statt über die Titelleiste verschieben lassen, könnte das sein?

lbccaleb 11. Sep 2009 19:10

Re: Fenster verschieben?
 
Hier ist auch noch was zu finden ;)

Fenster verschieben

DeddyH 11. Sep 2009 19:12

Re: Fenster verschieben?
 
Auch das dürfte nicht der Aufgabenstellung entsprechen. IMHO ist himitsu auf dem richtigen Weg, auch wenn das Plappermaul wieder zu vorschnell war :tongue:

Neutral General 11. Sep 2009 20:06

Re: Fenster verschieben?
 
Ich habs mal ausprobiert:

Ich bin so vorgegangen:

Wenn man Maustaste drückt, dann wird er Punkt gespeichert auf den geklickt wurde (relative Koordinaten auf dem Formular, also Point(X,Y) wobei x,y aus OnMouseDown sind)

Dann im OnMouseMove wird die neue Position mithilfe der aktuellen, globalen Mauskoordinaten und dem Punkt vom MouseDown (als ne Art Offset) berechnet.

himitsu 11. Sep 2009 20:24

Re: Fenster verschieben?
 
Zitat:

Zitat von Neutral General
Dann im OnMouseMove wird die neue Position mithilfe der aktuellen, globalen Mauskoordinaten und dem Punkt vom MouseDown (als ne Art Offset) berechnet.

Delphi-Referenz durchsuchenClientToScreen

Namenloser 11. Sep 2009 20:48

Re: Fenster verschieben?
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von Neutral General
Dann im OnMouseMove wird die neue Position mithilfe der aktuellen, globalen Mauskoordinaten und dem Punkt vom MouseDown (als ne Art Offset) berechnet.

Delphi-Referenz durchsuchenClientToScreen

Das ist nicht mal nötig. Es reicht, die relative Bewegung zu kennen, und die Distanz zu den Koordinaten der Form dazu zu addieren.

Neutral General 12. Sep 2009 00:53

Re: Fenster verschieben?
 
Hi,

Ich addiere nichtmal dazu.

Ich setze Left,Top der Form = Mouse.CursorPos und addiere den offset der Maus innerhalb des Formulars drauf.

SirThornberry 12. Sep 2009 08:52

Re: Fenster verschieben?
 
Zitat:

Zitat von Neutral General
Ich addiere nichtmal dazu....und addiere den offset der Maus...

:mrgreen:

DeddyH 12. Sep 2009 08:57

Re: Fenster verschieben?
 
Zitat:

Zitat von Larsi
Delphi-Quellcode:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if ssLeft in Shift then
    begin
      ReleaseCapture;
      Form1.Perform(WM_SYSCOMMAND,$F012,0);
    end;
end;
Der Code würde das gewünscht bewirken aber berechnet wird da natrülich von dir nichts. Der Code stammt von DeddyH.

Für den Algorithmus denn du machen willst hilft dir eventuell ClientToScreen.

Hab ich das wirklich so geschrieben :shock:? Falls das jemand nutzen sollte, bitte das "Form1." vor dem Perform weglassen.

Larsi 12. Sep 2009 09:19

Re: Fenster verschieben?
 
Du hast Panel1.Perform geschrieben, ich hab das durch Form1 ausgetauscht.

DeddyH 12. Sep 2009 09:20

Re: Fenster verschieben?
 
Ahaaaa, dann erscheint das schon in einem anderen Licht. Aber wie gesagt, lass das Form1 weg oder ersetze es durch self, dann ist das auch richtig.

Aphton 12. Sep 2009 10:04

Re: Fenster verschieben?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Blank Window Example (nonvcl) :D
Delphi-Quellcode:
program DemoFormMovement;

{$A+,B-,C-,D-,E-,F-,G+,H+,I-,J-,K-,L-,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y-,Z1}
{$APPTYPE GUI}

type
  TWndClassEx = packed record
    cbSize: Cardinal;
    style: Cardinal;
    lpfnWndProc: Pointer;
    cbClsExtra: Integer;
    cbWndExtra: Integer;
    hInstance: Cardinal;
    hIcon: Cardinal;
    hCursor: Cardinal;
    hbrBackground: Cardinal;
    lpszMenuName: PAnsiChar;
    lpszClassName: PAnsiChar;
    hIconSm: Cardinal;
  end;

  TPoint = packed record
    X: Longint;
    Y: Longint;
  end;

  TMsg = packed record
    hwnd: Cardinal;
    message: Cardinal;
    wParam: Integer;
    lParam: Integer;
    time: Cardinal;
    pt: TPoint;
  end;

const
  kernel32          = 'kernel32.dll';
  user32            = 'user32.dll';

  _Classname: PChar = 'WndDmoCls';
  _Width: Word     = 320;
  _Height: Word    = 240;

  {Windows Rip}
  HWND_TOP         = 0;
  COLOR_WINDOW     = 5;
  WS_EX_TOOLWINDOW = $80;
  GWL_STYLE        = -16;
  WS_VISIBLE       = $10000000;
  WS_CAPTION       = $C00000;
  VK_ESCAPE        = 27;  
  SWP_SHOWWINDOW   = $40;          
  IDC_ARROW        = Pointer(32512);

  {Messages Rip}
  WM_DESTROY       = $0002;
  WM_KEYUP         = $0101;
  WM_LBUTTONDOWN   = $0201;
  WM_MOUSEMOVE     = $0200;
  WM_LBUTTONUP     = $0202;

var
  hWnd: Cardinal;
  mMsg: TMsg;
  wWnd: TWndClassEx;

  InitialFormMousePosition,
  ScreenMouse: TPoint;
  MouseIsDown: Boolean;

{Windows Rip}
function RegisterClassEx(const WndClass: TWndClassEx): Word; stdcall;
  external user32 name 'RegisterClassExA';
function LoadCursor(Cardinalance: Cardinal; lpCursorName: PChar): Cardinal; stdcall;
  external user32 name 'LoadCursorA';
function CreateWindowEx(dwExStyle: Cardinal; lpClassName: PChar;
  lpWindowName: PChar; dwStyle: Cardinal; X, Y, nWidth, nHeight: Integer;
  hWndParent: Cardinal; hMenu: Cardinal; Cardinalance: Cardinal; lpParam: Pointer): Cardinal;
  stdcall; external user32 name 'CreateWindowExA';
function SetWindowLong(hWnd: Cardinal; nIndex: Integer; dwNewLong: Longint): Longint; stdcall;
  external user32 name 'SetWindowLongA';
function GetMessage(var lpMsg: TMsg; hWnd: Cardinal;
  wMsgFilterMin, wMsgFilterMax: Cardinal): Boolean; stdcall;
  external user32 name 'GetMessageA';
function TranslateMessage(const lpMsg: TMsg): Boolean; stdcall;
  external user32 name 'TranslateMessage';
function DispatchMessage(const lpMsg: TMsg): Longint; stdcall;
  external user32 name 'DispatchMessageA';
function UnregisterClass(lpClassName: PChar; Cardinalance: Cardinal): Boolean; stdcall;
  external user32 name 'UnregisterClassA';
function GetLastError: Cardinal; stdcall;
  external kernel32 name 'GetLastError';
procedure PostQuitMessage(nExitCode: Integer); stdcall;
  external user32 name 'PostQuitMessage';
function GetCursorPos(var lpPoint: TPoint): Boolean; stdcall;
  external user32 name 'GetCursorPos';
function SetWindowPos(hWnd: Cardinal; hWndInsertAfter: Cardinal;
  X, Y, cx, cy: Integer; uFlags: Cardinal): Boolean; stdcall;
  external user32 name 'SetWindowPos';
function DefWindowProc(hWnd, Msg: Cardinal; wParam, lParam: Integer ): Integer; stdcall;
  external user32 name 'DefWindowProcA';

function WndProc( hWnd, uMsg: Cardinal; wParam, lParam: Integer ): Integer; stdcall;
begin
  Result := 0;
  case uMsg of
    WM_DESTROY:
      PostQuitMessage(0);
    WM_KEYUP:
      case Word( wParam ) of
        VK_ESCAPE:
          WndProc( hWnd, WM_DESTROY, 0, 0 );
      end;
    WM_LBUTTONDOWN:
    begin
      with InitialFormMousePosition do
      begin
        X := Word( lParam );
        Y := Word( lParam shr 16 );
      end;
      MouseIsDown := True;
    end;
    WM_MOUSEMOVE:
    if MouseIsDown then
    begin
      GetCursorPos( ScreenMouse );
      SetWindowPos( hWnd, HWND_TOP, ScreenMouse.X - InitialFormMousePosition.X,
        ScreenMouse.Y - InitialFormMousePosition.Y, _Width, _Height, SWP_SHOWWINDOW );
    end;
    WM_LBUTTONUP:
      MouseIsDown := False;
  else
    Result := DefWindowProc( hWnd, uMsg, wParam, lParam );
  end;
end;

begin
  with wWnd do
  begin
    cbSize := SizeOf( wWnd );
    lpfnWndProc := @WndProc;
    hCursor := LoadCursor( 0, IDC_ARROW );
    hbrBackground := COLOR_WINDOW;
    lpszClassName := _Classname;
  end;
  RegisterClassEx( wWnd );
  hWnd := CreateWindowEx( WS_EX_TOOLWINDOW, _Classname, NIL, WS_VISIBLE,
    100, 100, _Width, _Height, 0, 0, 0, NIL );
  SetWindowLong( hWnd, GWL_STYLE, WS_VISIBLE and (not WS_CAPTION) );
  while GetMessage( mMsg, 0, 0, 0 ) do
  begin
    TranslateMessage( mMsg );
    DispatchMessage( mMsg );
  end;
  UnregisterClass( _Classname, 0 );
  ExitCode := GetLastError;
end.

Matze 12. Sep 2009 10:08

Re: Fenster verschieben?
 
Das ist sicher genau das, was ein Lehrer von einem Delphi-Neuling verlangt. :wall:

Gerade über OnMouseDown (wurde alles genannt) geht es doch sehr einfach und das ist vermutlich das, was der Lehrer sehen möchte. Ich denke es geht um das Verstehen und Anwenden der VCL-Ereignisse.

Aphton 12. Sep 2009 10:50

Re: Fenster verschieben?
 
I know :D
Aber einem Neuling wird ein Lehre sicher das nicht abkaufen!
Also von daher :P

MfG

DeddyH 12. Sep 2009 10:59

Re: Fenster verschieben?
 
Um wieder zur eigentlichen Aufgabenstellung zurückzukehren: die generelle Vorgehensweise wurde mindestens 2 mal bereits genannt. Hier etwas ausführlicher: im Ereignis OnMouseDown, das ausgelöst wird, sobald auf dem Formular eine Maustaste gedrückt wird, merkst Du Dir den aktuellen Punkt des Mauszeigers (die X- und Y-Koordinate werden freundlicherweise bereits als Parameter übergeben) in einer globalen Variablen (@all: keine Meckereien jetzt!!). Dabei solltest Du aber auswerten, welche Maustaste gedrückt wurde, was wiederum im Button-Parameter steht, dieser sollte für die linke Maustaste mbLeft sein. In Pseudo-Code sieht das dann so aus:
Delphi-Quellcode:
var MausPos: TPoint;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: integer);
begin
  wenn Button mbLeft ist
    MausPos ist der Punkt(X,Y)
end;
Im MouseMove-Ereignis wiederum kannst Du nun die Differenz zwischen den einzelnen Koordinaten errechnen und die Eigenschaften Top bzw. Left des Formulars so setzen, dass der Mauszeiger wieder an der gemerkten relativen Position innerhalb des Formulars steht (auch in diesem Ereignis werden wieder X und Y übergeben). Ob die linke Maustaste dabei gedrückt ist, kannst Du feststellen, indem Du prüfst, ob ssLeft in der Menge Shift enthalten ist.
Delphi-Quellcode:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: integer);
begin
  wenn ssLeft in Shift enthalten
    Left ist gleich Left + Differenz aus X und MausPos.X
    Top ist gleich Top + Differenz aus Y und MausPos.Y
end;
Ich hoffe, das war ein halbwegs verständlicher Ansatz. Versuch es einfach einmal auf diesem Wege, falls Du nicht klarkommst, helfen wir gerne weiter.
Sollte ich hier Fehler gemacht haben (da aus dem Kopf getippt), bitte ich einen Wissenden um Korrektur.

haentschman 12. Sep 2009 12:44

Re: Fenster verschieben?
 
Hallo an alle,

[OT]
...schon 2 Seiten Antworten und Diskussion aber der TE hat sich noch noch nicht dazu geäußert bzw. (für mein Verständnis) klar ausgedrückt. :gruebel:
...Beiträge die keinem wirklich weiterhelfen :(
[/OT]

DualCoreCpu 12. Sep 2009 13:55

Re: Fenster verschieben?
 
Hallo,

Danke zuerst mal für Eure zahlreichen Atworten und Anregungen. Ich habe jetzt die folgende Lösung, da wir die Berechnung ohne Windows API selber machen sollen:

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    lblmouseX: TLabel; //Erkärung welcher Wert
    lblmouseY: TLabel; //Erkärung welcher Wert
    lblwidth: TLabel;  //Erkärung welcher Wert
    lbltop: TLabel;    //Erkärung welcher Wert
    lblleft: TLabel;   //Erkärung welcher Wert
    lblheight: TLabel; //Erkärung welcher Wert
    lbMouseX: TLabel;  //Darstellung des Wertes
    lbMouseY: TLabel;  //Darstellung des Wertes
    lbLeft: TLabel;    //Darstellung des Wertes
    lbHeight: TLabel;  //Darstellung des Wertes
    lbWidth: TLabel;   //Darstellung des Wertes
    lbTop: TLabel;     //Darstellung des Wertes
    procedure FormCreate(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private-Deklarationen }
    DeltaX,DeltaY: Integer;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  lbLeft.Caption := IntToStr(Left);
  lbTop.Caption := IntToStr(Top);
  lbWidth.Caption := IntToStr(Width);
  lbHeight.Caption := IntToStr(Height);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  LbMouseX.Caption := IntToStr(X);
  LbMouseY.Caption := IntToStr(Y);
  DeltaX := X - Left; //Differenz linke obere Ecke und
  DeltaY := Y - Top;  //Mausposition
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssLeft in Shift Then
  begin
    MouseX := X;
    MouseY := Y;
    DeltaX := MouseX - Left;
    DeltaY := MouseY - Top;
  end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Left := Left - DeltaX;
  Top := Top - DeltaY;
  lbLeft.Caption := IntToStr(Left);
  lbTop.Caption := IntToStr(Top);
end;

end.
Wie aber erkenne ich da die Bewegungsrichtung der Maus? Wenn ich die nach links bewege und die linke Maustaste gedrückt halte, soll sich ja das Fenster nach links bwewegen, wenn Maus nach rechts bewegt wird, entsprechend nach rechts, analog wenn hoch oder tief.

DeddyH 12. Sep 2009 14:02

Re: Fenster verschieben?
 
Die musst Du gar nicht erkennen ;). Ganz kurzes Rechenbeispiel, gegeben sei eine gemerkte Koordinate X mit Wert 100.
Mausbewegung nach rechts -> X(101) - gemerktes X(100) = 1, d.h. Left um 1 erhöhen
Mausbewegung nach links -> X(99) - gemerktes X(100) = -1, d.h. Left um -1 erhöhen (also de facto um 1 verringern)

Dasselbe gilt natürlich analog für die Y-Koordinate.

[edit] Schlechtschreibung :oops: [/OT]

Aphton 12. Sep 2009 14:52

Re: Fenster verschieben?
 
@DualCoreCPU:
Speichere einfach die X, Y Werte der Maus sobald geklickt wurde und setze eine Boolean Variable auf true
Sobald die Maus bewegt wird, prüfst du deine Boolean Variable auf True und - ist die Bedingung erfüllt - setzt die die neue Left/Top Werte der Form - dies machst du am besten, wenn du der alten Left / Top Position die Differenz zwischen der >jetztigen< X / Y Werte und Anfangs X / Y Werte hinzuaddierst!
Wird die Maus wieder losgelassen, setzt du natürlich die Boolean Variable auf False

MfG

DeddyH 12. Sep 2009 14:55

Re: Fenster verschieben?
 
Wozu die Boolean-Variable?

Aphton 12. Sep 2009 15:00

Re: Fenster verschieben?
 
ok ist nicht zwingend notwendig (hab das mit TShiftState nicht bedacht);
danke fürs Darauf-hinweisen

MfG

DualCoreCpu 12. Sep 2009 16:36

Re: Fenster verschieben?
 
Hallo!

Ich habe jetzt das MouseUp Ereignis so geändert:

Delphi-Quellcode:
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Left := Left + MouseX + DeltaX;
  Top := Top + MouseY + DeltaY;
  lbLeft.Caption := IntToStr(Left);
  lbTop.Caption := IntToStr(Top);
end;
Die Werte MouseX, MouseY sind die aktuellen Muskoordinaten. Hier werden nun Left und Top immer erhöht, auch wenn ich die Maus nach oben bzw. links bewege.

Wenn ich DeltaX, DeltaY hinzu addiere, stimmt die Verschiebungsrichtung nicht bei jeder Mausposition. Außerdem ist der Betrag von DeltaX,DeltaY größer als 1. Intuitiv sage ich,
das ich ein Vorzeichen für MouseX,MouseY brauche.

In FormMouseDown merke ich mir die Mausposition in MouseX, MouseY. Aber wie dann weiter?

@DeddyH: Nach Deiner ANregung brauche ich noch ein DeltaX, DeltaY mit Vorzeichen. Wieso sollte ich da die Richtungserkennung nicht benötigen? Da brauch ich ja irgendwo einen Vergleich der Mausposition mit der vorherigen. Aber wie stelle ich das an?

DeddyH 12. Sep 2009 16:43

Re: Fenster verschieben?
 
Noch einmal ganz in Ruhe: im OnMouseDown merkst Du Dir DeltaX und DeltaY. Im OnMouseMove addierst Du nun zum Form.Left einfach die Differenz aus aktueller X-Koordinate und DeltaX und zu Form.Top die Differenz aus aktueller Y-Koordinate und DeltaY. Wenn diese Differenz positiv ist, verschiebt sich das Formular somit automatisch nach rechts bzw. unten, bei negativer Differenz nach links bzw. oben, denn z.B. 100 + -10 => 100 - 10 = 90 :zwinker:

DualCoreCpu 12. Sep 2009 17:08

Re: Fenster verschieben?
 
Hallo!

Habe es jetzt so gelöst:

Danke noch mal allen, die mir hier helfen!!!

Delphi-Quellcode:
unit movewin;

interface

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

type
  TForm1 = class(TForm)
    lblmouseX: TLabel;
    lblmouseY: TLabel;
    lblwidth: TLabel;
    lbltop: TLabel;
    lblleft: TLabel;
    lblheight: TLabel;
    lbMouseX: TLabel;
    lbMouseY: TLabel;
    lbLeft: TLabel;
    lbHeight: TLabel;
    lbWidth: TLabel;
    lbTop: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private-Deklarationen }
    DeltaX,DeltaY: Integer;
    MouseX,MouseY: Integer;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  lbLeft.Caption := IntToStr(Left);
  lbTop.Caption := IntToStr(Top);
  lbWidth.Caption := IntToStr(Width);
  lbHeight.Caption := IntToStr(Height);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  LbMouseX.Caption := IntToStr(X);
  LbMouseY.Caption := IntToStr(Y);
  DeltaX := X - Left;
  DeltaY := Y - Top;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssLeft in Shift Then
  begin
    DeltaX := X - Left;
    DeltaY := Y - Left;
    MouseX := X;
    MouseY := Y;
   (*
     DeltaX := MouseX - Left; // ---- so hatte ich vorher DeltaX
     DeltaY := MouseY - Top; // ---- und DeltaY berechnet.
   *)
  end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Left := Left + DeltaX;
  Top := Top + DeltaY;
  lbLeft.Caption := IntToStr(Left);
  lbTop.Caption := IntToStr(Top);
end;

end.
Jetzt ist aber der Betrag meiner Verschiebung zu groß gegenüber meiner Mausbewegung.

DeddyH 12. Sep 2009 17:19

Re: Fenster verschieben?
 
Du machst ja auch zuviel des Guten ;)
Delphi-Quellcode:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DeltaX := X;
  DeltaY := Y;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssLeft in Shift then
    begin
      Left := Left + X - DeltaX;
      Top := Top + Y - DeltaY;
    end;
end;
Das genügt. Du darfst bei dem Ganzen nicht übersehen, dass X und Y relativ zum Formular angegeben werden und nicht relativ zum Bildschirm.

DualCoreCpu 12. Sep 2009 17:36

Re: Fenster verschieben?
 
Danke, @DeddyH, so klappt es! Problem gelöst!

DeddyH 12. Sep 2009 17:37

Re: Fenster verschieben?
 
Wenn Du das jetzt auch noch nachvollziehen kannst, sind ja alle zufrieden :zwinker:

DualCoreCpu 12. Sep 2009 17:49

Re: Fenster verschieben?
 
Zitat:

Zitat von DeddyH
Wenn Du das jetzt auch noch nachvollziehen kannst, sind ja alle zufrieden :zwinker:

Werde mir das auf jeden Fall noch durcharbeiten. Klar, wenn X und Y relativ zum Formular zu betrachten sind, dann entsprechen X und Y der Strecke der Mausbewegung und die Richtung müsste sich dann mit dem Vorzeichen ergeben.

Left + X - DeltaX
Left + Y - DeltaY



In FormMouseDown werden DeltaX,DeltaY vorzeichengerecht ermittelt. Dann kommt die fragliche Berechnung.

Delphi-Quellcode:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssLeft in Shift then
    begin
      Left := Left + X - DeltaX;
      Top := Top + Y - DeltaY;
    end;
end;
Wie sind X und Y hier zu interpretieren?

Habe soeben mal die Addition von X und Y entfernt (auskommentiert). Da funktioniert die Verschiebung nicht mehr.

Und egal wei ich die Maus bewege, X und Y werden immer hinzu addiert. Das erkläre ich mir damit, das DeltaX,DeltaY wirklich die Differenz zur vorherigen Mausposition ist, während X und Y in FormMouseMove die aktuellen X,Y Werte der Mausposition sind.

DeddyH 12. Sep 2009 18:14

Re: Fenster verschieben?
 
Also, Du merkst Dir OnClick die aktuellen Koordinaten relativ zum Formular. Wenn man die Maus verschiebt, ändern sich diese logischerweise. Der Trick ist nun lediglich, das Formular so zu verschieben, dass die jetzt aktuellen Koordinaten wieder den gemerkten entsprechen. Dazu genügt uns die Addition von Form.Left bzw. Form.Top mit der Differenz aus aktuell und gemerkt. Dabei kann uns egal sein, ob die jeweilige Differenz positiv oder negativ ist, denn eine Addition mit einem negativen Wert entspricht ja einer Subtraktion. Für Details dazu siehe meine vorherigen Posts, ich möchte das nicht alles wiederholen.

Namenloser 12. Sep 2009 21:30

Re: Fenster verschieben?
 
Ich würde die Variablen aber nicht Delta nennen. Delta weist immer auf eine Differenz hin. StartX bzw StartY (oder Offset) wäre da vielleicht passender.

DeddyH 12. Sep 2009 21:33

Re: Fenster verschieben?
 
Meinetwegen kann er die auch Erbsensuppe nennen, am Anfang kommt es ja eher auf eine verständliche Problemlösung an. Aber gut, Du hast insofern Recht, als dass man auch meiner Meinung nach immer sprechende Namen verwenden sollte, sonst steigt man später durch seinen eigenen Code nicht mehr durch.

DualCoreCpu 13. Sep 2009 08:22

Re: Fenster verschieben?
 
Hallo,

bin noch immer beim Nachvollziehen meines Quelltextes. Zum besseren Verständnis habe ich den Hinweis von @NamenLozer aufgegriffen. Ich habe also die bisherigen DeltaX,DeltaY Variablen in StartX und StartY umbenannt, weil diese Werte unabhängig von der Bewegungsrichtung der Maus immer positiv sind. Danach müssten DeltaX,DeltaY die Differenz zum Startpunkt in FormMouseDown und dem aktuellen Punkt in FormMouseUp bzw. FormMouseMove sein.

Der folgende Quelltext zeigt mir aber in FormMouseUp den Wert 0 für DeltaX und DeltaY an. Irgendwas habe ich da doch noch nicht verstanden. Bitte helft mir noch mal. Hier sind meine Änderungen.

Delphi-Quellcode:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssLeft in Shift Then
  begin
    Left := Left + X - StartX;
    Top := Top + Y - StartY;
  end;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  var P: TPoint;
begin
  StartX := X; StartY := Y;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DeltaX := X - StartX;
  DeltaY := Y - StartY;
  lbMouseX.Caption := IntToStr(DeltaX);
  lbMouseY.Caption := IntToStr(DeltaY);
end;

DeddyH 13. Sep 2009 09:31

Re: Fenster verschieben?
 
Zitat:

Zitat von DeddyH
Der Trick ist nun lediglich, das Formular so zu verschieben, dass die jetzt aktuellen Koordinaten wieder den gemerkten entsprechen.

Also muss die Differenz logischerweise 0 sein, sonst hätten wir etwas falsch gemacht ;)

Aphton 13. Sep 2009 09:57

Re: Fenster verschieben?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vielleicht hilft dir ne bildliche Darstellung des Problems bzw der Lösung!

MfG

DeddyH 13. Sep 2009 09:59

Re: Fenster verschieben?
 
:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:55 Uhr.
Seite 1 von 2  1 2      

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