Maus Hook Rekursion
-
Hallo,
ich habe eine dll geschrieben, die alle Mausklicks untersucht.
Funzt auch...
Jetzt möchte ich, dass dann auch noch ein weiterer Mausklick simuliert wird.
Das führt dann zu einer Rekursion!
Wie kann ich das umgehen?!?Das ist meine MouseHookFunc:
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) { if(nCode < 0) return CallNextHookEx(hMouseHook, nCode, wParam, lParam); // Verhindern das eine Nachricht mehrmals verarbeitet wird. if(nCode == HC_ACTION) { static bool bSelfAdvice=false; if (!bSelfAdvice) { bSelfAdvice = true; switch(wParam) { case WM_LBUTTONUP: // get a pointer to the mouse hook struct. PMOUSEHOOKSTRUCT mhs = (PMOUSEHOOKSTRUCT) lParam; /* ::mouse_event(MOUSEEVENTF_LEFTDOWN, mhs->pt.x, mhs->pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_LEFTUP, mhs->pt.x, mhs->pt.y, 0, 0);*/ } bSelfAdvice = false; } } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); }
Wenn ich den Kommentar rausnehme, dann ist das ganze rekursiv....
Danke im voraus...
Grüße
TimoL
-
wie wäre es mit einem flag?
-
Hi,
ich dachte, dass hätte ich hiermit
static bool bSelfAdvice=false;
gemacht?!?
Das beachtet der irgendwie nicht...
Er führt das trotzdem aus.Was habe ich falsch gemacht???
Danke schonmal
-
// versuch mal die Definition der bSelfAdvice global und für alle Instazen der DLL zu definieren:
#pragma data_seg ("Shared")
bool bSelfAdvice = FALSE ;
#pragma data_seg ()
#pragma comment (linker, "/section:Shared,RWS")
-
Danke schonmal für Deine Antwort.
Aber leider war's das auch net...
Gruß
TimoL
-
Ich denke, dass das mit der static Variable so schon gehen müsste. Ich vermute eher, dass es daran liegt, dass mouse_event wohl gleich zurückkehrt, und die Nachricht halt nur in die Message-Queue kommt - sprich: die gesendeten Events werden erst abgearbeitet, nachdem bSelfAdvice = false; erreicht wurde bzw. dieses Event halt abgearbeitet ist
D.h. du müsstest bSelfAdvice als globale Variable deklarieren und erst nach der Abarbeitung des letzten von dir in diesem Rahmen gesendeten Events wieder auf false zurücksetzen.Ist jetzt nur eine Spekulation, aber vielleicht hilft's ja
-
Hallo,
danke für den Hinweis.Habe den Code daraufhin mal so geändert:
// Verhindern das eine Nachricht mehrmals verarbeitet wird. if(nCode == HC_ACTION) { switch(wParam) { case WM_LBUTTONDOWN: if (g_iEventCounter < 1) { // diese Nachricht ist meine!!! ;) g_iEventCounter++; } else { g_iEventCounter = 0; PMOUSEHOOKSTRUCT mhs = (PMOUSEHOOKSTRUCT) lParam; POINT pt = mhs->pt; ::mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x+10, pt.y+10, 0, 0); WinExec("notepad", SW_SHOW); } } }
g_iEventCounter zählt jetzt die Mausklicks...
Jetzt habe ich keine Rekursion mehr. <- schonmal einfacher, dass Programm unter "Kontrolle" zu halten...
aber:
1. Mein Mausklick wird nicht ausgeführt (aber notepad wird gestartet)!
2. Das Programm reagiert "nur" auf jeden 2. Mausklick.Ich hoffe es handelt sich um einen Gedankenfehler...
Ich sehe schon den Wald vor lauter Bäumen nicht....
-
Ich hab's!
Danke!
Der hat den Mausklick simuliert, aber immer auf der selben Stelle...
Weil halt mein Ausgangspunkt immer wieder neu berechnet wurde.
Habe mal MOVE eingebaut, und dann sieht man auch was...Hier mein Ergebniscode (wen's interessiert):
case WM_LBUTTONDOWN: if (g_iEventCounter < 2) { // diese Nachricht ist meine!!! ;) g_iEventCounter++; } else { g_iEventCounter = 0; PMOUSEHOOKSTRUCT mhs = (PMOUSEHOOKSTRUCT) lParam; POINT pt = mhs->pt; ::mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_MOVE, 10, 0, 0, 0); ::mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_MOVE, -20, 0, 0, 0); ::mouse_event(MOUSEEVENTF_LEFTDOWN, pt.x, pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_LEFTUP, pt.x, pt.y, 0, 0); ::mouse_event(MOUSEEVENTF_MOVE, 10, 0, 0, 0); }