Entwickler-Ecke
Windows API - MouseHook - Ereignis komplett abfangen
netspy - Do 21.12.06 01:52
Titel: MouseHook - Ereignis komplett abfangen
Meine
Anwendung [
http://www.delphi-forum.de/topic_LingoPad+243+Woerterbuch_58314.html] möchte ich mittels eines Maus-Tastatur-Ereignis (bspw. Alt + rechte Maustaste) aktivieren. Dazu habe ich einen MouseHook gesetzt, der etwa so aussieht:
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:
| function HookProc(nCode: Integer; MsgID: wParam; Data: LParam): LResult; stdcall; var WindowHandle: THandle;
begin
if (MsgID = WM_RBUTTONDOWN) and (GetKeyState(VK_MENU) < 0) then begin
WindowHandle := GetWindow(PMouseHookStruct(Data)^.HWND, GW_OWNER);
if WindowHandle <= 0 then WindowHandle := PMouseHookStruct(Data)^.HWND;
if nCode >= 0 then SendMessage(FindWindow(MouseHookWindow, nil), MouseHookMessage, MsgID, WindowHandle);
Result := 0;
end else begin
Result := CallNextHookEx(Hook, nCode, MsgID, Data);
end;
end; |
Neben dem Aktivieren meines Programms will ich an die Anwendung, die beim Drücken der Maus aktiv war, noch ein Strg-C schicken, um einen markierten Text in die Zwischenablage zu holen. Leider funktioniert dies nicht. Das Handle des fremden Fenster stimmt aber meine Keybd_Event kommen nicht an. Da in der Anwendung auch ein Kontext-Menü (wegen der rechten Maustaste) aufgeht, ist klar, dass das Ereignis nicht abgefangen wird und vermutlich irgendwie mit meinen eigenen Keybd_Event kollidiert.
Frage: Wie kann ich das im MouseHook abgefangene Ereignis vor der eigentlich dafür bestimmten Anwendung verbergen? Result:=0 hilft nicht. Oder gibt es noch andere Wege nach Rom, die ich übersehen habe?
Mario
jaenicke - Do 21.12.06 11:59
Kannst du nicht mit
RegisterHotkey [
http://www.dsdt.info/tipps/?id=635] arbeiten?
(Zu deiner konkreten Frage kann ich im Moment nichts sagen, ich hab bisher immer damit gearbeitet.)
Die Frage ist nur: geht dabei auch die Mauseinbeziehung, aber ich denke eigentlich schon.
// EDIT: Ja, es gibt zum Beispiel VK_LBUTTON, und das sollte auch damit funktionieren. Alt und Strg und so kannst du direkt angeben.
netspy - Do 21.12.06 12:03
Mache ich bisher schon und damit klappt es auch. Das funktioniert ja aber nur mit Tastaturereignissen und nicht mit der Maus, weshalb ich wohl nicht an einem MouseHook vorbeikomme.
netspy - Do 21.12.06 12:11
jaenicke hat folgendes geschrieben: |
| Wie bereits eben im Edit geschrieben: Es gibt doch einen virtuellen Keycode für die linke Maustaste, also würde ich jetzt denken, dass man den dort auch verwenden kann. (und natürlich gibts auch welche für die mittlere, etc.) |
Nein, das geht leider nicht.
jaenicke - Do 21.12.06 12:49
Hmm, also AFAIK kannst bei einem Hook zwar durch Nichtaufrufen von CallNextHookEx dafür sorgen, dass die weiteren Hooks in der Hook-Kette das Ereignis nicht bekommen, aber da die Anwendung in diesem Fall (normalerweise) keine Hooks einsetzt, kann man wohl nicht so einfach verhindern, dass die das selbst bekommt.
Aber dafür kenne ich mich mit Hooks zuwenig aus um das definitiv zu sagen... Vielleicht kann dir da jemand anderes weiterhelfen.
netspy - Do 21.12.06 12:51
jaenicke hat folgendes geschrieben: |
| ... Vielleicht kann dir da jemand anderes weiterhelfen. |
Das hoffe ich auch. :) :roll:
wulfskin - Do 21.12.06 13:37
Hallo,
wenn ich dich richtig verstanden habe, möchtest du den markierten Text in die Zwischenablage kopieren?! In welchem Control steht denn der Text?
Gruß Hape!
netspy - Do 21.12.06 14:08
wulfskin hat folgendes geschrieben: |
| wenn ich dich richtig verstanden habe, möchtest du den markierten Text in die Zwischenablage kopieren?! In welchem Control steht denn der Text? |
Ja, genau das ist mein Anliegen. In welchem Control der Text steht, ist mir prinzipiell egal, da so ziemlich alle Controls, die ein Markieren von Text erlauben, auch Strg+C oder Strg+Einfügen unterstützen.
Bisher machen ich das über eine mit RegisterHotKey registrierte Tastenkombination und das funktioniert auch ziemlich gut. Da ich aber auch auf Tasten+Maustasten-Ereignisse reagieren möchte, komme ich mit RegisterHotKey nicht weiter und hab es mit einem MouseHook versucht. Leider funktioniert beim Aktivieren meiner Anwendung durch den MouseHook das Senden von Strg+C nicht mehr. Da die Funktion dazu die gleiche wie bei der Aktivierung durch RegisterHotKey ist und das WindowHandle der fremnden Anwendung stimmt, vermute ich, dass sich da irgendwelche Meldungen in der MessageQueue blockieren oder kollidieren.
wulfskin - Do 21.12.06 14:56
Hallo,
damit dir klar ist warum ich frage: Wenn es ein einfaches Control ist, dann brauchst du nicht den Umweg über die Zwischenablage und den simulierten Tastendruck machen, sondern kannst ihn direkt auslegen.
Also: Um was für ein Controll handelt es sich?
Gruß Hape!
netspy - Do 21.12.06 15:19
wulfskin hat folgendes geschrieben: |
| Also: Um was für ein Controll handelt es sich? |
Das kann ich dir nicht sagen, da es beliebige Controls sein können. Die Anwendung ist ein
Wörterbuch [
http://www.ego4u.de/de/lingopad] und der Sinn ist, dass man in einer beliebigen Anwendung (bspw. ein Browser, Textverarbeitung, Mailprogramm, etc. pp) einen Text markiert, mit einem HotKey das Wörterbuch gestartet und der Text gesucht wird. Da es sich dabei um die unterschiedlichsten Anwendungen mit unterschiedlichen und meist sehr speziellen Controls handelt, macht das direkte Auslesen (soweit überhaupt möglich) IMO zu viel Arbeit. Ich lasse mich aber gerne korrigieren, falls es doch einen einfacheren Weg gibt.
jaenicke - Do 21.12.06 15:45
Es gibt ja auch die Message WM_GETTEXT. Da bekommst du wohl den kompletten Text, nicht nur den markierten. Aber vielleicht gibts ja sowas auch für den markierten. Mal sehen...
// EDIT: Hmm, wohl nicht...
netspy - Do 21.12.06 17:08
jaenicke hat folgendes geschrieben: |
| Es gibt ja auch die Message WM_GETTEXT. Da bekommst du wohl den kompletten Text, nicht nur den markierten. |
Eben, da gibt es leider nur den gesamten Text und was anderes habe ich auch nicht gefunden.
wulfskin - Do 21.12.06 18:27
Hallo,
ich würde an das Problem anders herangehen: Such nach einer Möglichkeit das Handle an der Mausposition zu bekommen. Dann überprüfe um was es sich für ein Fenstertyp handelt (
GETCLASSNAME). Zum Schluss lies den Text entsprechend des Typs ein.
Für das erste fehlt mir noch der Ansatz, aber Motzis X-Spy findet ja auch die Klassen unter dem Mauszeiger, es geht also.
Gruß Hape!
netspy - Di 26.12.06 03:07
Titel: Lösung
Ich hab nun rausgefunden, warum ich bisher das Ereignis nicht abfangen konnte. Erstens brauche ich einen LowLevel-Hook (WH_MOUSE_LL) und zweitens hatte ich nur das MouseDown-Ereignis abgefangen. Zusätzlich muss natürlich auch noch das folgende MouseUp abgefangen werden.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!