Entwickler-Ecke

Windows API - Procedure bei Mausklick außerhalb des Forms ausführen


n-regen - Mo 18.08.08 15:57
Titel: Procedure bei Mausklick außerhalb des Forms ausführen
Hallo!

Ich möchte, dass in einem Programm eine Procedure ausgeführt wird, sobald irgendwo ein Mausklick stattfindet (also auch außerhalb des Formulars).
Ich habe schon wegen Mouse-Hooks recherchiert und es funktioniert einfach nicht.
Meine aktuelle Grundlage ist diese Anleitung: http://www.gcf.de/papers/apihooking.txt
Ich habe den Quelltext mit Müh´ und Not zum kompilieren gebracht (der Autor ist bezüglich Deklarationen ja ziemlich schweigsam), aber "UnsereMouseFunktion" wird nie ausgeführt.

Nils


elundril - Mo 18.08.08 16:11

auch schon mal auf [url]http://www.delphi-treff.de[/url] geschaut? dort gibts imho ein gutes hook tutorial.

lg elundril


Tino - Mo 18.08.08 16:12
Titel: Re: Procedure bei Mausklick außerhalb des Forms ausführen
user profile iconn-regen hat folgendes geschrieben:
der Autor ist bezüglich Deklarationen ja ziemlich schweigsam

Naja, Grundlagen wollte der Autor mit dem Tutorial wohl bewusst nicht vermitteln. ;-) Deshalb würde ich an deiner Stelle erstmal versuchen einfachere Aufgaben zu löschen bzw. Einsteiger-Tutorials vorzunehmen wenn bereits solche einfachen Dinge Probleme verursachen. Zum Beispiel der Delphi-Crashkurs [http://www.christian-stelzmann.de/artikel/crashkurs.htm].

Gruß,
Tino


n-regen - Mo 18.08.08 16:19

Das ist keineswegs - wie du vielleicht annimmst, Timo - eines meiner ersten Programme, sondern nur mein erstes, das Hooks verwendet.
Ich habe den ersten Quelltext (ich will ja nur überwachen, nicht manipulieren, also brauche ich die DLL weiter unten nicht) halbwegs verstanden und dann kopiert.
Jetzt habe ich auch herausgefunden, dass man nur FormCreate und -Destroy deklarieren und mit dem Form verknüpfen muss und die andere Funktion einfach als erstes hinschreibt.
Trotzdem funktioniert es nicht - die Funktion wird nicht aufgerufen.
Falls ihr mir dadurch besser helfen könnt - hier ist mein aktueller Quelltext:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  hMouseHook: HHOOK;

implementation

{$R *.dfm}

function UnsereMouseFunktion(nCode: integer; wparam: WPARAM; lParam: LPARAM):Integer; stdcall;
begin
 if(wParam = WM_LBUTTONDOWN) then ShowMessage('Linke Maustaste gedrückt!');
 Result := CallNextHookEx(hMouseHook, nCode, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender:TObject);
begin
 hMouseHook := SetWindowsHookEx( WH_MOUSE, UnsereMouseFunktion, 00);
end;

procedure TForm1.FormDestroy(Sender:TObject);
begin
 UnhookWindowsHookEx(hMouseHook);
end;

end.


---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Ich habe mich jetzt mit Assarbads Tutorial auseinandergesetzt und kann jetzt aus seiner DLL einen Hook einrichten.
In der DLL habe ich an der Stelle, wo man verarbeiten kann, ein "ShowMessage" hingesetzt - erfolglos.
Was mache ich falsch?

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Ich habe jetzt herausgefunden, dass die Wenn-Nachricht-Ankommt-Routine nach jedem Registrieren des Hooks 16 mal aufgerufen wird und dann in tiefes Schweigen versinkt, bis man den Hook deinstalliert und wieder installiert.
EDIT: Der Parameter nCode ist dabei jeweils 0, wparam einmal sicher 512(=MOUSEMOVE) und 15 mal irgendwas (manchmal auch 512) und lparam irgendwas rund um 1200000.


Clemens L. - Mo 18.08.08 21:17

Kann sein das ich Mist rede, aber das kann man doch auch ohne Mouse-Hook erledigen? Mit RegisterHotKey sollte das imho funktionieren, wenn du als vKey VK_LBUTTON nimmst. :)

PS: Hier ist kurz beschrieben wie's geht: http://delphi.about.com/cs/adptips2001/a/bltip0601_3.htm


n-regen - Mo 18.08.08 21:33

Eigentlich eine gute Idee, aber Sie funktioniert nicht.
Trotzdem Danke.


Delete - Di 19.08.08 00:09

Es geht auch ohne Hook. Siehe dazu SetCapture, GetCapture und ReleaseCapture.


n-regen - Di 19.08.08 12:04

Mit SetCaptureControl(Form1) - was man laut Google-Suchergebnis in Delphi hernehmen soll - erhalte ich keine Meldung, wenn außerhalb des Formulars etwas passiert.
EDIT: Offenbar wird der Capture, sobald das Formular den Fokus verliert, unwirksam.
Kann man das irgendwie verhindern?


Delete - Di 19.08.08 12:13

Frag doch einfach den status der maus ab mit GetAsyncKeystate().


n-regen - Di 19.08.08 12:26

Danke!
Es funktioniert!
Ein Timer prüft alle 100 Millisekunden, ob die linke Maustaste gedrückt ist (und somit GetAsyncKeystate(VK_LBUTTON) <> 0).


Delete - Di 19.08.08 12:27

Wundert mich das da niemand drauf gekommen sind.