Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Ermitteln ob die Maus auf der Form ist? (https://www.delphipraxis.net/166429-ermitteln-ob-die-maus-auf-der-form-ist.html)

smart 13. Feb 2012 13:25


Ermitteln ob die Maus auf der Form ist?
 
Hi Alle.

wie kan man ermitteln ob die Maus noch im Fenster oder ausserh. des Fensters ist?

DeddyH 13. Feb 2012 13:28

AW: Ermitteln ob die Maus auf der Form ist?
 
Wenn sie außerhalb ist, bekommst Du normalerweise keine MouseMove-Nachrichten.

Neutral General 13. Feb 2012 13:30

AW: Ermitteln ob die Maus auf der Form ist?
 
... Die bekommt man aber auch nicht wenn man mit der Maus nicht direkt auf dem Formular ist sondern auf nem Button oder so. Im Zweifelsfall GetCursorPos + ein paar Berechnungen.

smart 13. Feb 2012 13:31

AW: Ermitteln ob die Maus auf der Form ist?
 
Ja, aber ich möchte das gern von mein Programm aus ermitteln.

Sir Rufo 13. Feb 2012 13:32

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von Neutral General (Beitrag 1150780)
GetCursorPos + ein paar Berechnungen.

Was denn für Berechnungen? Es gibt doch Delphi-Referenz durchsuchenPtInRect

DeddyH 13. Feb 2012 13:32

AW: Ermitteln ob die Maus auf der Form ist?
 
Du meinst vermutlich ScreenToClient(Mouse.CursorPos). Andererseits gibt es ja auch Ereignisse für das Überfahren/Verlassen des Formulars.

Sir Rufo 13. Feb 2012 13:34

AW: Ermitteln ob die Maus auf der Form ist?
 
Vielleicht hilft ja auch mein Google-Such-Egebnis Bei Google suchenDelphi Mouse On Form

http://delphi.about.com/cs/adptips20...ltip0800_5.htm

smart 13. Feb 2012 13:35

AW: Ermitteln ob die Maus auf der Form ist?
 
Verlassen des Formulars wäre wichtig!

DeddyH 13. Feb 2012 13:36

AW: Ermitteln ob die Maus auf der Form ist?
 
Eigentlich sollte da OnMouseLeave feuern.

smart 13. Feb 2012 13:41

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von DeddyH (Beitrag 1150787)
Eigentlich sollte da OnMouseLeave feuern.

Komisch, OnMouseLeave klapt leider nicht.

DeddyH 13. Feb 2012 13:45

AW: Ermitteln ob die Maus auf der Form ist?
 
Hast Du evtl. ein Panel oder einen sonstigen Container mit alClient auf dem Formular?

Sir Rufo 13. Feb 2012 13:49

AW: Ermitteln ob die Maus auf der Form ist?
 
Also da hilft wohl nur ein MouseHook Bei Google suchenDelphi WH_MOUSE und da ja nur die eigene Form interessiert, benötigt man auch keinen Systemweiten Hook - der ja in einer DLL ausgelagert sein müsste.

Die Schweizer haben da einen Ansatz
http://www.swissdelphicenter.ch/de/showcode.php?id=571

smart 13. Feb 2012 13:57

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von DeddyH (Beitrag 1150789)
Hast Du evtl. ein Panel oder einen sonstigen Container mit alClient auf dem Formular?

Ja, habe ich?

jaenicke 13. Feb 2012 14:00

AW: Ermitteln ob die Maus auf der Form ist?
 
Dann wird dessen OnMouseLeave ausgelöst. Da du nicht auf dem Formular direkt bist, wird nicht dessen Ereignis ausgelöst.

Du müsstest aber die WndProc überschreiben und die Message dort abfangen können nehme ich an.

DeddyH 13. Feb 2012 14:00

AW: Ermitteln ob die Maus auf der Form ist?
 
Klappt es in dessen OnMouseLeave?

smart 13. Feb 2012 14:05

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von DeddyH (Beitrag 1150794)
Klappt es in dessen OnMouseLeave?

Nein, leider nicht. Das hatte ich zuerst probiert.

DeddyH 13. Feb 2012 14:14

AW: Ermitteln ob die Maus auf der Form ist?
 
Dann weiß ich auch nicht weiter, bei mir geht es.

himitsu 13. Feb 2012 14:20

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Verlassen des Formulars wäre wichtig!
Was bedeutet "verlassen" für dich?

Delphi-Referenz durchsuchenTForm.OnDeactivate - wenn die Form den Eingabefokus verliert (an eine andere Form der eigenen Anwendung)

Delphi-Referenz durchsuchenTApplication.OnDeactivate - wenn die Form, bzw. die ganze Anwendung den Eingabefokus verliert (an eine andere Anwendung)


Manchmal darf man nicht nur auf die Maus hören, sondern nur auf den Eingabefokus.
Wenn mir die Maus, bei der Eingabe, im Weg ist, dann verschiebe ich sie und passe dabei nicht auf, ob sie noch über der Form bleibt.

DeddyH 13. Feb 2012 14:22

AW: Ermitteln ob die Maus auf der Form ist?
 
Ich verstehe nicht ganz, was OnDeactivate mit OnMouseLeave zu tun haben soll :gruebel:

Perlsau 13. Feb 2012 14:25

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von smart (Beitrag 1150778)
wie kan man ermitteln ob die Maus noch im Fenster oder ausserh. des Fensters ist?

Wofür brauchst du das denn?

jaenicke 13. Feb 2012 14:27

AW: Ermitteln ob die Maus auf der Form ist?
 
TApplicationEvents auf das Formular --> OnMessage:
Delphi-Quellcode:
procedure TForm257.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
  ClientRectAbs: TRect;
begin
  if Msg.message = WM_MOUSELEAVE then
  begin
    ClientRectAbs.TopLeft := ClientToScreen(ClientRect.TopLeft);
    ClientRectAbs.BottomRight := ClientToScreen(ClientRect.BottomRight);
    InflateRect(ClientRectAbs, -2, -2);
    if not PtInRect(ClientRectAbs, Mouse.CursorPos) then
      Caption := Caption + 'AA';
  end;
end;
Zum Testen schreibt das einfach etwas in die Caption.

Sir Rufo 13. Feb 2012 14:50

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von smart (Beitrag 1150778)
wie kan man ermitteln ob die Maus noch im Fenster oder ausserh. des Fensters ist?

Brauchst du jetzt eine Abfrage oder ein Event?

Eine Abfrage würde so aussehen:
Delphi-Quellcode:
function MouseOverWindow( aHandle : HWND ) : Boolean;
var
  wndHandle : HWND;
begin
  wndHandle := WindowFromPoint( Mouse.CursorPos );

  while ( wndHandle <> 0 ) and ( wndHandle <> aHandle ) do
    begin
      wndHandle := GetParent( wndHandle );
    end;

  Result := ( wndHandle <> 0 );
end;
und in deinem Projekt dann so:
Delphi-Quellcode:
procedure TForm1.Timer1Timer( Sender : TObject );
begin
  // Wir nehmen das Handle dieser Form
  if MouseOverWindow( Self.Handle ) then
    Caption := 'ja'
  else
    Caption := 'false';
end;

smart 13. Feb 2012 15:04

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von Perlsau (Beitrag 1150810)
Zitat:

Zitat von smart (Beitrag 1150778)
wie kan man ermitteln ob die Maus noch im Fenster oder ausserh. des Fensters ist?

Wofür brauchst du das denn?

Wenn ich über meine Anwendung mit der Maus fahre, soll meine Anwendung die Farbe wechselen.

jaenicke 13. Feb 2012 15:08

AW: Ermitteln ob die Maus auf der Form ist?
 
Dann passt mein Quelltext ja. Fehlt nur zusätzlich noch die Prüfung auf WM_MOUSEMOVE um ggf. die Farbe zu ändern und in dem obigen Code kannst du sie zurück ändern.

Sir Rufo 13. Feb 2012 16:11

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von jaenicke (Beitrag 1150824)
Dann passt mein Quelltext ja. Fehlt nur zusätzlich noch die Prüfung auf WM_MOUSEMOVE um ggf. die Farbe zu ändern und in dem obigen Code kannst du sie zurück ändern.

Nun ja, so ganz ja nicht, denn die Message
Delphi-Quellcode:
WM_MOUSELEAVE
wird auch dann gesendet, wenn man von der Form auf ein anderes Control wechselt.
Wenn die Maus dann passend stehen bleibt, kommt auch kein passendes
Delphi-Quellcode:
WM_MOUSEMOVE
.

jaenicke 13. Feb 2012 16:28

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1150849)
Nun ja, so ganz ja nicht, denn die Message
Delphi-Quellcode:
WM_MOUSELEAVE
wird auch dann gesendet, wenn man von der Form auf ein anderes Control wechselt.

Deshalb prüfe ich ja auch die Mausposition um nur beim echten Verlassen zu reagieren. Und MouseMove kommt ja dann bei jeder Bewegung. Sollte doch also passen.

ASM 13. Feb 2012 16:35

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von jaenicke (Beitrag 1150824)
Dann passt mein Quelltext ja.

Erstens, funktioniert das mit Hilfe des ApplicationEvents1Message-Events zwar mit Delphi XE, jedoch merkwürdigerweise nicht mit Delphi 7.
Zweitens, wird (wenn es denn funktioniert, z.B. mit Delphi XE) die Kopfzeile der Form bereits als außerhalb der Form gewertet. Nicht sehr sinnvoll.

Die einzig verlässliche Vorgehensweise ist also die per Funktion MouseOverWindow(), wie beschrieben. Ich selbst hätte den Mausstatus der Form mit Hilfe der beiden Messages CM_MOUSEENTER und CM_MOUSELEAVE abgefangen sowie dann ebenfalls mittels Timer behandelt, aber die Funktion MouseOverWindow() ist zweifelsohne eleganter.

Sir Rufo 13. Feb 2012 17:16

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von jaenicke (Beitrag 1150860)
Zitat:

Zitat von Sir Rufo (Beitrag 1150849)
Nun ja, so ganz ja nicht, denn die Message
Delphi-Quellcode:
WM_MOUSELEAVE
wird auch dann gesendet, wenn man von der Form auf ein anderes Control wechselt.

Deshalb prüfe ich ja auch die Mausposition um nur beim echten Verlassen zu reagieren. Und MouseMove kommt ja dann bei jeder Bewegung. Sollte doch also passen.

Das funktioniert aber auch nur dann, wenn das Formular nicht von einem anderen überlappt wird ;)

jaenicke 13. Feb 2012 20:19

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von ASM (Beitrag 1150863)
Ich selbst hätte den Mausstatus der Form mit Hilfe der beiden Messages CM_MOUSEENTER und CM_MOUSELEAVE abgefangen

Und wo kommen die her?
Richtig, es wird genau das gemacht was ich mache... Beim ersten WM_MOUSEMOVE wird CM_MOUSEENTER ausgelöst, bei WM_MOUSELEAVE wird CM_MOUSELEAVE ausgelöst.

Zitat:

Zitat von Sir Rufo (Beitrag 1150875)
Das funktioniert aber auch nur dann, wenn das Formular nicht von einem anderen überlappt wird ;)

Oh, ja, da hast du Recht. Dann also so:
Delphi-Quellcode:
procedure TForm19.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
  ClientRectAbs: TRect;
begin
  if Msg.message = WM_MOUSELEAVE then
  begin
    ClientRectAbs.TopLeft := ClientToScreen(ClientRect.TopLeft);
    ClientRectAbs.BottomRight := ClientToScreen(ClientRect.BottomRight);
    InflateRect(ClientRectAbs, -2, -2);
    if not PtInRect(ClientRectAbs, Mouse.CursorPos) or (WindowFromPoint(Mouse.CursorPos) <> Handle) then
      Color := clBtnFace;
  end
  else if Msg.message = WM_MOUSEMOVE then
    Color := clRed;
end;
Einen Timer braucht man aber trotzdem nicht...

Sir Rufo 13. Feb 2012 21:21

AW: Ermitteln ob die Maus auf der Form ist?
 
Nenn mich Erbsenzähler, aber das gibt ein schönes Geflacker, wenn du mit diesem Code
Delphi-Quellcode:
if not PtInRect(ClientRectAbs, Mouse.CursorPos) or (WindowFromPoint(Mouse.CursorPos) <> Handle) then
über irgendein Control auf der Form entlangfährst. Denn jedes Control hat ein eigenes Handle ;)

Es müsste also die Abfrage aus meiner Funktion - oder einfach die Funktion selber - eingebaut werden :)

jaenicke 13. Feb 2012 21:54

AW: Ermitteln ob die Maus auf der Form ist?
 
Stimmt. Darauf habe ich jetzt nicht geachtet, weil ich mich gerade sehr an dem Timer gestört hatte.

Sir Rufo 13. Feb 2012 22:01

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von jaenicke (Beitrag 1150917)
Stimmt. Darauf habe ich jetzt nicht geachtet, weil ich mich gerade sehr an dem Timer gestört hatte.

Macht nix, the knight is watching you :cyclops:

ASM 13. Feb 2012 22:29

AW: Ermitteln ob die Maus auf der Form ist?
 
Zitat:

Zitat von jaenicke (Beitrag 1150902)
Zitat:

Zitat von ASM (Beitrag 1150863)
Ich selbst hätte den Mausstatus der Form mit Hilfe der beiden Messages CM_MOUSEENTER und CM_MOUSELEAVE abgefangen

Und wo kommen die her?
Richtig, es wird genau das gemacht was ich mache... Beim ersten WM_MOUSEMOVE wird CM_MOUSEENTER ausgelöst, bei WM_MOUSELEAVE wird CM_MOUSELEAVE ausgelöst.
[/DELPHI]

Obwohl inzwischen ja alles mit der Funktion MouseOverWindow() sehr einfach und bestens gelöst ist, hier doch noch meine Antwort auf die Frage.
Da kommen sie her (komplettes Beispiel):
Code:
type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Timer1: TTimer;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  protected
  private
    { Private-Deklarationen }
    isMouseOnForm: Boolean;
    changed: Boolean;
    procedure CMMouseEnter(var msg: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;
  public
    { Public-Deklarationen }
  end;
 
  Implementation
 
  const
    cMouseOnForm = 'Mouse on form';
    cMouseOutOfForm = 'Mouse outside of form';
 
  procedure TForm1.CMMouseEnter(var msg: TMessage);
  begin
    isMouseOnForm := true;
    label1.caption := cMouseOnForm;
    changed := true;
  end;
 
  procedure TForm1.CMMouseLeave(var msg: TMessage);
  begin
    isMouseOnForm := false;
    label1.caption := cMouseOutOfForm;
    changed := true;
  end;
 
  procedure TForm1.FormCreate(Sender: TObject);
  begin
    panel1.Caption := '';
    label1.Caption := '';
    timer1.interval := 100; // oder nach Bedarf
  end;
 
  procedure TForm1.Timer1Timer(Sender: TObject);
  begin
    // "changed"- Abfrage nur, um unnötige Aktionen zu vermeiden
    if changed then
    begin
      changed := false;
      label1.invalidate;
      // oder was auch immer nötig:
      if isMouseOnForm then MachDies()
      else MachDas();
    end;
  end;
Und damit funktioniert es - anders als mit dem ApplicationEvent - perfekt auch unter Delphi 7, und zudem wird auch die Kopfzeile der Form als Bestandteil der Form erkannt, und es ist egal, ob und welche Komponente (z.B. ein Panel) auf der Form plaziert ist.

EWeiss 13. Feb 2012 22:48

AW: Ermitteln ob die Maus auf der Form ist?
 
Warum nicht einfach WindowFromPoint ?

GetCursorPos in verbindung mit WindowFromPoint
Wenn beim Loslassen des Button (oder was auch immer ein HWND/THandle besitzt)

das HWND vom WindowFromPoint das gleiche wie mein Handle des Button ist
Ergebnis true andernfalls false

UPS:
Sehe gerade hatte Sir Rufo ja schon geschrieben.

gruss

Popov 14. Feb 2012 02:33

AW: Ermitteln ob die Maus auf der Form ist?
 
Probier das mal aus. Sollte eigentlich das sein was du brauchst:

Delphi-Quellcode:
procedure TForm1.FormDeactivate(Sender: TObject);
begin
  ReleaseCapture;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if GetCapture = 0 then
    SetCapture(Handle);

  if PtInRect(BoundsRect, ClientToScreen(Point(x, y))) then
    Caption := 'Maus ist über der Form'
  else
    Caption := 'Maus ist außerhalb der Form';
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:22 Uhr.

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