Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   MousePosition in dynamischer Klasse (https://www.delphipraxis.net/138302-mouseposition-dynamischer-klasse.html)

BAMatze 7. Aug 2009 07:53


MousePosition in dynamischer Klasse
 
Hallo und guten Morgen an alle DP´ler,

Ich hab da ein kleines Problem. Ich möchte in einer abgeleiteten TPaintBox meine Position der Mouse bestimmen. Hab eigendlich auch schon alle nötigen Quellcode herausgesucht aber in meinen Versuchen sind diese leider noch nicht zu gewünschten Ergebnis gekommen.
Ich denke ich setze diesen Quellcode:
Delphi-Quellcode:
    TempPoint.X := Left;
  TempPoint.Y := Top;
  ScreentoClient(TempPoint);
noch nicht an die richtige Stelle in meinem Projekt. Aber erstmal schnell zur Situation. Also nur nochmal zur Verdeutlichung, das Ziel ist wenn ich an der oberen linken Ecke von meiner PaintBox bin, möchte ich den Punkt(0,0) haben und am rechten unteren Eck den Punkt(PaintBox.Width, PaintBox.Height).

Das Auslesen der Mouse habe ich dafür so in die abgeleitete TPainbox-Klasse eingesetzt:
Delphi-Quellcode:
const MouseOver = CM_MOUSEENTER;
      MouseLeave = CM_MOUSELEAVE;

Type TPaintboxPos = Class(TPaintbox)
  private
    FbMouseOnPB: boolean;
    function GetxWert: integer;
    function GetyWert: integer;
    procedure CMMouseOver(var Msn: TMessage); message MouseOver;
    procedure CMMouseLeave(var Msn: TMessage); message MouseLeave;
  protected
  public
    property xPos: integer read GetxWert;
    property yPos: integer read GetyWert;
End;

implementation

function TPaintboxPos.GetxWert: integer;
begin
  if FbMouseOnPB then result := Mouse.CursorPos.X
  else result := -1;
end;

function TPaintboxPos.GetyWert: integer;
begin
  if FbMouseOnPB then result := Mouse.CursorPos.Y
  else result := -1;
end;

// Wenn die Maus über dem Label ist, ändert sich der Cursor, damit erkannt werden
// kann, dass man hier eine Eingabe tätigen kann.
procedure TPaintboxPos.CMMouseOver(var Msn: TMessage);
begin
  Cursor := crHandPoint;
  FbMouseOnPB := true;
end;
// Cursor wird auf den normalen Default-Cursor zurück gesetzt.
procedure TPaintboxPos.CMMouseLeave(var Msn: TMessage);
begin
  FbMouseOnPB := false;
  Cursor := crDefault;
end;
Nichts wildes, wie man sieht und funktioniert. Aber es werden noch die absoluten Koordinaten angezeigt. Ich habe den Screentoclient schon in die createWnd-Prozedure meiner Oberklasse (in der die PaintBox kreiert wird) gesetzt, leider keine Änderungen am Ergebnis und auch in der FromShow-Procedure der Form, in der die Oberklasse eingebunden wird, gibt es kein richtiges Ergebnis.

Hoffe ihr könnt mir wieder bei dem Problem helfen.

Vielen Dank
BAMatze

DeddyH 7. Aug 2009 08:10

Re: MousePosition in dynamischer Klasse
 
Ich bin nicht sicher, ob ich das richtig verstanden habe, aber die relative Mausposition müsstest Du doch so ermitteln können.
Delphi-Quellcode:
function TBla.GetXPos: integer;
var p: TPoint;
begin
  p := ScreenToClient(Mouse.CursorPos);
  Result := p.X;
end;

function TBla.GetYPos: integer;
var p: TPoint;
begin
  p := ScreenToClient(Mouse.CursorPos);
  Result := p.Y;
end;

BAMatze 7. Aug 2009 08:14

Re: MousePosition in dynamischer Klasse
 
Alles richtig verstanden @DeddyH :dp: bekomme das gewünschte Ergebnis. Hatte das wohl falsch verstanden, weil ich dachte, ich muss dem Programm das direkt beim Erstellen sagen, dass er die Mouse nur auf das Objekt/ Form beziehen soll.

Danke dir.

schöni 8. Aug 2009 07:14

Re: MousePosition in dynamischer Klasse
 
Hallo,

Dieser Thred bewegt mich zu der Frage, wie die Mausbewegung registriert wird:

Delphi-Quellcode:

function ContainsMouse(Left,Top, Width, Height ,X,Y: Integer): Boolean;
begin
  ContainsMouse := (X > Left) and (Y > Top) and (X < Width+Left) and (Y < Height+Top);
end;
Mit dieser Funktion bewegt sich das Control immer nach links. Um bei Bewegung der Maus nach rechts
das Control auch nach rechts zu bewegen, muss die Mausbewegungsrichtung registriert werden. Gibt es da standardisierte Verfahren?

Delphi-Quellcode:
Tform1.MyControlMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
begin
  if X < Xalt then directionX := -1 else directionX := 1;
  if Y < Yalt then directionY := -1 else directionY := 1;
  Xalt := X; Yalt := Y;
end;
Danach sähe meine Funktion ContainsMouse so aus:

Delphi-Quellcode:

function TForm1.ContainsMouse(Left,Top, Width, Height ,X,Y: Integer): Boolean;
begin
  X := X * directionX;
  Y := Y * directionY;
  ContainsMouse := (X > Left) and (Y > Top) and (X < Width+Left) and (Y < Height+Top);
end;
Nun funktioniert ja das Bewegen und Ändern der Größe der Delphi Controls bereits. Aber wie wird die Mausbewegung registriert. Wie ermittelt Delphi also die Variablen Xalt, Yalt, die ich in meinem Beispielcode stehen habe. Sicher kommt hier noch der Timer "ins Spiel". Welcher Zeitabstand wird da standardmäßig verwendet, um die Bewegungsrichtung festzustellen?

aaaaaaaaaaa_10 8. Aug 2009 10:03

Re: MousePosition in dynamischer Klasse
 
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure TimerOnTimer(Sender: TObject);
  private
    FXpos,FYpos: Integer;
  public
  end;


implementation

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  FXpos := X;
  FYpos := Y;
end;

procedure Tform1.TimerOnTimer(Sender: TObject);
begin
  //Aber was muss dann hier stehen, damit der Richtungswechsel registriert wird,
  //was mein Vorgänger ja erfragt?
end;

BAMatze 8. Aug 2009 12:43

Re: MousePosition in dynamischer Klasse
 
Hallo @a...10,

Also da ich das in einer Klasse verwendet hab, habe ich das einfach in die property´s (GetxWert, GetyWert <-- Getter für die property) reinprogrammiert, ala:

Delphi-Quellcode:
function TBla.GetXPos: integer;
var p: TPoint;
begin
  if binside then
    begin
      p := ScreenToClient(Mouse.CursorPos);
      Result := p.X;
    end
  else Result := -1;
end;
// ebenso für Y
darin hab ich dann noch ein Event OnxChange/ OnyChange eingebunden, so ersparte ich mir den Timer und reagiere einfach nur in der Oberklasse auf das Event, wenn sich was ändert (finde ich persönlich schöner so). Ist aber persönliche Geschmackssache.

MfG
BAMatze

aaaaaaaaaaa_10 10. Aug 2009 06:21

Re: MousePosition in dynamischer Klasse
 
Zitat:

Zitat von BAMatze
Hallo @a...10,

Also da ich das in einer Klasse verwendet hab, habe ich das einfach in die property´s (GetxWert, GetyWert <-- Getter für die property) reinprogrammiert, ala:

Delphi-Quellcode:
function TBla.GetXPos: integer;
var p: TPoint;
begin
  if binside then
    begin
      p := ScreenToClient(Mouse.CursorPos);
      Result := p.X;
    end
  else Result := -1;
end;
// ebenso für Y
darin hab ich dann noch ein Event OnxChange/ OnyChange eingebunden, so ersparte ich mir den Timer und reagiere einfach nur in der Oberklasse auf das Event, wenn sich was ändert (finde ich persönlich schöner so). Ist aber persönliche Geschmackssache.

MfG
BAMatze

So weit, so gut, aber diese X- und Y Position muss doch irgendwo in den Tiefen der VCL ermittelt werden. Und hinzu kommt der Richtungswechsel der Maus. Ich meine, wenn ich zB. mein Hauptfenster der Anwendung mit der Maus nach links verschiebe, die Muastaste gedrückt lasse und mein Fenster sofort wieder ein Stück nach rechts verschiebe. Dann muss sich ja das Vorzeichen der X- und Y Position passend ändern. In der VCL ist das alles schon eingebaut. Aber Borland/Codegear muss das ja da irgendeinen Algorhitmus verwendet haben. Aus dem VCL Quelltext werd ich da nicht schlau. Ich meine aber, das das nur miteinem internen Timer zu machen ist.

jaenicke 10. Aug 2009 06:53

Re: MousePosition in dynamischer Klasse
 
Da ändert sich doch kein Vorzeichen. Du bewegst die Maus nach links, vorher war die x-Position 250, danach ist sie 200, jetzt bewegst du sie nach rechts auf 300. Die Mausposition ist absolut. Deshalb verstehe ich nicht so ganz wie du das meinst.

Einen Timer benötigt man auch nicht. Wenn die Maus bewegt wurde, bekommt man ja eine Message (WM_MOUSEMOVE) von Windows geschickt, auf die man reagiert. Windows ist ereignisbasiert, deshalb wäre es eine äußerst schlechte Idee mit einem Timer immer zu schauen, ob sich die Position geändert hat. Man wird ja benachrichtigt, wenn dem so ist, muss darauf also nur reagieren.

BAMatze 10. Aug 2009 13:06

Re: MousePosition in dynamischer Klasse
 
WM_MouseMove hab ich noch gar nicht dran gedacht. Aber ist wahrscheinlich noch besser als bei meinem eingebauten Event.

schöni 10. Aug 2009 19:02

Re: MousePosition in dynamischer Klasse
 
@jaenicke:
vielleicht meint ja aaa...a_10 wie man diese Mausbewegung selber prorgrammieren würde, wäre das nicht schon in Win-API bzw. VCL eingebaut. Auf der Windows-Ebene macht man das natürlich mit den Messages.

Aber wenn man die Mausbewegungen selber programmieren müsste, dann fällt mir nur das ein, was ich im vorigen Beitrag schon geschrieben habe.


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