![]() |
Re: Maus sperren während Tastatureingabe
Ich habe gerade wieder etwas mit der Mouse+Keyboard-Hook-DLL probiert.
Kann man das auch irgendwie so machen, dass auf die Hook-Message mit "0" geantwortet wird, wenn das Mausereignis gelöscht werden soll?
Delphi-Quellcode:
In der DLL:
procedure TForm1.WndProc(var Message:TMessage);
var difference: DWORD; begin if Message.Msg = WM_KEYBHOOKMSG then begin inherited WndProc(Message); // Eine Taste wurde gedrückt, wir merken uns den Zeitpunkt last_keyboard_input := GetTickCount(); // ToDo: Tasten wie Strg dürfen nicht mitgezählt werden, // da diese in Kombination mit der Maustaste OK sind! end else if Message.Msg = WM_MOUSEHOOKMSG then begin difference := GetTickCount() - last_keyboard_input; if (difference <= sperrdauer) and ((Message.wParam = WM_LBUTTONDBLCLK) or (Message.wParam = WM_LBUTTONDOWN) or (Message.wParam = WM_LBUTTONUP)) then begin // Ereignis verwerfen, da linke Maustaste innerhalb // der Sperrzeit gedrückt wurde // Something ToDo ? Message.Result := 0; // Debug: Zeigen, dass etwas gesperrt wurde label2.Caption := 'Sperrung: ' + IntToStr(GetTickCount()); end else begin // Sonstiges Mausereignis bzw. Mausklick außerhalb // der Sperrzeit erlauben inherited WndProc(Message); end; end else begin // Andere Ereignisse durchlassen inherited WndProc(Message); end; end;
Delphi-Quellcode:
Würde soetwas funktionieren oder ist es der falsche Weg? Ich komme mit der Windows API einfach nicht klar...
function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin setprop(WindowHandle, 'mous_ncode', nCode); setprop(WindowHandle, 'mous_hwnd', PMOUSEHOOKSTRUCT(lParam)^.hwnd); setprop(WindowHandle, 'mous_hitt', PMOUSEHOOKSTRUCT(lParam)^.wHitTestCode); setprop(WindowHandle, 'mous_xpos', PMOUSEHOOKSTRUCT(lParam)^.pt.x); setprop(WindowHandle, 'mous_ypos', PMOUSEHOOKSTRUCT(lParam)^.pt.y); if SendMessage(HWND_BROADCAST, WM_MOUSEHOOKMSG, wParam, lParam) = 0 then begin result := WM_NULL; // Funktioniert das? end; end; end; end; |
Re: Maus sperren während Tastatureingabe
Wenn du deine Nachricht an HWND_BROADCAST schickst, kannst du kein Ergebnis erhalten, da die Nachricht an alle Top-Level-Fenster geschickt wird. Deshalb habe ich auch die MMF vorgeschlagen.
Zum Verwerfen der Nachricht zitiere ich mal die MSDN Library: Zitat:
|
Re: Maus sperren während Tastatureingabe
Könntest du bzgl. des MMF ein kleines Beispiel posten, sofern es keine Umstände macht?
|
Re: Maus sperren während Tastatureingabe
Kein Thema.
Delphi-Quellcode:
//Anwendung
hMapping := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, 4, 'The mapping of the black drake'); pView := MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0); PCardinal(pView)^ := Handle; //Aufräumen bei Programmende UnmapViewOfFile(pView); CloseHandle(hMapping); //In der DLL hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'THe mapping of the black drake'); pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); TargetHandle := PCardinal(pView)^; //Aufräumarbeiten bei DLL_PROCESS_DETACH UnmapViewOfFile(pView); CloseHandle(hMapping); |
Re: Maus sperren während Tastatureingabe
Hallo.
Danke für den Code. Ich werde versuchen, damit den Übertragungsweg zu realisieren. |
Re: Maus sperren während Tastatureingabe
Der MMF Übertragungsweg funktioniert nun.
Ein Problem habe ich noch bei der Verwerfung des Mausklicks. Ich verstehe nicht ganz, wie das getan werden soll. WM_NULL ist ja scheinbar falsch, aber was soll dann als Result zurückgegeben werden? Ausschnitt Anwendung:
Delphi-Quellcode:
Ausschnitt DLL:
procedure TForm1.WndProc(var Message:TMessage);
var difference: DWORD; begin if Message.Msg = WM_ANYKEY_PRESSED then begin inherited WndProc(Message); // Eine Taste wurde gedrückt, wir merken uns den Zeitpunkt last_keyboard_input := GetTickCount(); end else if Message.Msg = WM_LMOUSECLK_CONFIRM then begin difference := GetTickCount() - last_keyboard_input; if (difference <= sperrdauer) then begin // Ereignis verwerfen, da linke Maustaste innerhalb // der Sperrzeit gedrückt wurde // Der DLL melden, dass das Hook die Mausnachricht verwerfen soll. Message.Result := 10; // Debug: Zeigen, dass etwas gesperrt wurde label2.Caption := 'Sperrung: ' + IntToStr(GetTickCount()); end else begin // Sonstiges Mausereignis bzw. Mausklick außerhalb // der Sperrzeit erlauben inherited WndProc(Message); end; end else begin // Andere Ereignisse durchlassen inherited WndProc(Message); end; end;
Delphi-Quellcode:
Die "10" ist die Rückantwort, die sagen soll, dass das Mausereignis verworfen werden soll.
function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var res: Cardinal; begin Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin // Handelt es sich um einen linken Mausklick? if (wParam = WM_LBUTTONDBLCLK) or (wParam = WM_LBUTTONDOWN) or (wParam = WM_LBUTTONUP) then begin // Dann Anwendung fragen, ob das OK ist SendMessageTimeOut(TargetHandle, WM_LMOUSECLK_CONFIRM, wParam, lParam, SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res); if res = 10 then begin // Mausklick verwerfen Result := WM_NULL; // ToDo: Funktioniert nicht... end; end; end; end; end; |
Re: Maus sperren während Tastatureingabe
Das Problem ist wohl, dass du CallNextHook() in jedem Fall aufrufst.
Delphi-Quellcode:
Das einzige was ich jetzt nicht weiss ist, ob und wann nCode jemals <0 wird. Result ist in dem Fall dann undefiniert, und müsste mit einem konstanten Wert vorbelegt werden, der dazu führt dass der Wert von nCode ebenfalls Einfluss darauf hat ob das Ereignis durchkommt oder nicht. Man müsste nur mal schauen unter welchen Bedingungen nCode<0 auftritt.
function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var res: Cardinal; begin case nCode < 0 of TRUE: exit; FALSE: begin // Handelt es sich um einen linken Mausklick? if (wParam = WM_LBUTTONDBLCLK) or (wParam = WM_LBUTTONDOWN) or (wParam = WM_LBUTTONUP) then begin // Dann Anwendung fragen, ob das OK ist SendMessageTimeOut(TargetHandle, WM_LMOUSECLK_CONFIRM, wParam, lParam, SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res); if res = 10 then // Mausklick verwerfen Result := 1 // Irgend ein nicht-null Wert. So hab ich es zumindest auch schon mal gemacht ;) else Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam); end; end; end; end; end; |
Re: Maus sperren während Tastatureingabe
Hallo.
Danke für den Tipp, ich werde es später zu Hause gleich ausprobieren. Ein Verständnisproblem habe ich aber noch: Du sagst, CallNextHookEx() soll nicht aufgerufen werden, wenn ich mein Ereignis verwerfen will, deswegen hast du CallNextHookEx() in die If-Abfrage reingepackt. Klingt logisch. Was ist aber für den Fall dass nCode<0 ist (was das auch immer bedeuten soll)? In meinem vorherigen Code, den ich von Delphi-Treff übernommen habe, wurde CallNextHookEx() auch aufgerufen wenn nCode<0 wäre - war das unrichtig bzw. unnötig? Gruß blackdrake |
Re: Maus sperren während Tastatureingabe
Deswegen mein letzter Absatz ;). Ich hatte bei meinem Programm die Abfrage vor, also ausserhalb der nCode-Bedingung, da ich selbst noch in der DLL auf das Event reagieren wollte, aber sonst keiner mehr. Das Problem bei dir ist nun, dass du deine Hostanwendung erst fragen musst ob zu ignorieren ist oder nicht. Wenn du es so biegen kannst dass du es in der DLL direkt entscheiden kannst, dürfte es kein Problem sein das ganze aus dem nCode-Abschnitt zu nehmen. (So langsam wäre es echt interessant zu wissen was nCode angibt. Das msdn fand ich da imho nicht recht hilfreich.)
Bei meinem Programm kann man auch im Host das Ignorieren ab- und anschalten, was mir ein Flag in einem gemeinsamen MMF setzt. Damit entscheide ich dann in der DLL ob geblockt wird oder nicht ohne jedes Mal nachfragen zu müssen. Evtl. wäre das eine Alternative zum Message-Frage-Antwort-Spiel für dich. |
Re: Maus sperren während Tastatureingabe
Hi Blackdrage,
ich hatte auch dieses Touchpad Problem und habe es dann mittels automatischem sperren der Maus gelöst, evtl reicht dir das ja auch Siehe ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz