![]() |
Re: Maus sperren während Tastatureingabe
Meinst du, es sollte so aussehen?
Delphi-Quellcode:
Wirft aber auch eine AV ab.
procedure TForm1.Button1Click(Sender: TObject);
var h: hwnd; begin h := WindowHandle; InstallHooks(h); // EXCEPTION WM_MOUSEHOOKMSG:=getprop(h,mousmsg); WM_KEYBHOOKMSG:=getprop(h,keybmsg); end; Das Problem ist, dass ich vom DP-Tutorial keine Belegung des hWnd's sehen konnte. Dort wird nämlich die API-Funktion mittels
Delphi-Quellcode:
aufgerufen, jedoch kann ich dann nicht wirklich die dlgfunc-Parameter, die auch die hWnd enthält, sehen...
DialogBoxParam(HInstance, MAKEINTRESOURCE(DIALOG1), 0, @dlgfunc, 0);
In sofern weiß ich nicht genau, welches Handle überhaupt verlangt ist... |
Re: Maus sperren während Tastatureingabe
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var h: hwnd; begin h := Form1.Handle; // <--- Eher so ... InstallHooks(h); // EXCEPTION WM_MOUSEHOOKMSG:=getprop(h,mousmsg); WM_KEYBHOOKMSG:=getprop(h,keybmsg); end; |
Re: Maus sperren während Tastatureingabe
Hallo.
Funktioniert leider immer noch nicht. Ich denke, die AV kommt aufgrund einer ungültigen DLL-Interaktion. Wäre nur das Handle falsch, würde das wahrscheinlich nicht zu einer AV führen. Hast du eine Idee? Gruß blackdrake |
Re: Maus sperren während Tastatureingabe
Hallo,
Der Fehler lag beim GetProcAddress, da bei den 2 Tutorials einmal von *Hook und einmal von *Hooks die Rede war. Ich habe jetzt einen fast funktionierenden Code, jedoch gibt es noch 2 Dinge, mit denen ich Probleme habe: 1. Die Strg-Taste wird auch als Taste angesehen ... hier muss sich dringend noch eine Allgemeine Lösung finden, weil Strg+Maustaste ja legitim sind 2. Das Sperren der Maustaste funktioniert nicht. Eigentlich dachte ich, es genüge, einfach das WndProc, das man verwerfen möchte, einfach nicht mehr per inherited weiterzureichen, doch es funktioniert einfach nicht. Zum Testen: Ich habe während die Anwendung im Hintergrund läuft in einem Notepad etwas eingetippt. Das Fenster im Hintergrund zeigt als Debugausgabe "Gesperrt". Während der Eingabe klicke ich in meinen geschriebenen Text hinein. Nach der Eingabe werden die Textstellen markiert, weil scheinbar die Mausereignisse doch noch im Eingabepuffer waren und nicht durch die Hook-DLL verworfen wurden. Code (DLL hooks.dll in den oberen Posts):
Delphi-Quellcode:
Gruß
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Label1: TLabel; debug_tmr: TTimer; Label2: TLabel; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure debug_tmrTimer(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); public last_keyboard_input: DWORD; procedure WndProc(var Message:TMessage); override; end; var Form1: TForm1; implementation {$R *.dfm} type TInstallHook = function(Hwnd: THandle): Boolean; stdcall; TUninstallHook = function: Boolean; stdcall; var InstallHooks: TInstallHook; UninstallHooks: TUninstallHook; lib: Cardinal; WM_MOUSEHOOKMSG: Cardinal = 0; WM_KEYBHOOKMSG: Cardinal = 0; const mousmsg='MouseHookMessage_Assarbad'; keybmsg='KeyboardHookMessage_Assarbad'; const sperrdauer = 3000; // 3 Sekunden, später Variabel // ToDo: Programm total lahm, wenn Delphi gestartet ist // (auch außerhalb des Debuggers) ? 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 ? // 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; procedure TForm1.debug_tmrTimer(Sender: TObject); var difference: DWORD; begin difference := GetTickCount() - last_keyboard_input; if difference > sperrdauer then begin label1.Caption := 'Freigegeben'; end else begin label1.Caption := 'Gesperrt'; end; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin UnInstallHooks; WM_MOUSEHOOKMSG:=0; WM_KEYBHOOKMSG:=0; end; procedure TForm1.FormCreate(Sender: TObject); begin lib := LoadLibrary('hooks.dll'); if lib <> INVALID_HANDLE_VALUE then begin InstallHooks := GetProcAddress(lib, 'InstallHooks'); UnInstallHooks := GetProcAddress(lib, 'UninstallHooks'); end else begin ShowMessage('Hook could not be initialized. Please check "hooks.dll".'); Application.Terminate; end; end; procedure TForm1.FormDestroy(Sender: TObject); begin FreeLibrary(lib); end; procedure TForm1.FormShow(Sender: TObject); begin InstallHooks(Handle); WM_MOUSEHOOKMSG:=getprop(Handle, mousmsg); WM_KEYBHOOKMSG:=getprop(Handle, keybmsg); end; end. blackdrake |
Re: Maus sperren während Tastatureingabe
Zitat:
Zitat:
a) ist sie sehr weit weg vom Mousepad b) wird diese beim Schreiben von Text eher selten benötigt c) wird beim Schreiben von Text innerhalb der Sperrzeit eine weitere Taste gedrückt. Nur mit der STRG-Taste ist es schwierig einen Text zu verfassen :mrgreen: Zitat:
Aber das weiß ich adhoc auch nicht ... vielleicht habe ich nachher, wenn der planet wieder scheint, etwas zeit, mir das mal anzusehen ;-) Zitat:
cu Oliver |
Re: Maus sperren während Tastatureingabe
Hallo.
Ich weiß nicht, wie ich hier die Maus-Aktion rückgängig machen soll.
Delphi-Quellcode:
Dieses Konstrukt der DLL sieht nicht aus wie eine WndProc-Schleife, bei der man eine nicht gebrauchte Message einfach nicht per inherited weiterreicht...
function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin //es ist ebenfalls moeglich die Bearbeitung an eine Bedingung zu knuepfen //it's possible to call CallNextHookEx conditional only. Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; //wenn code kleiner 0 wird nix gemacht //if code smaller 0 nothing has to be done FALSE: begin //Hier kann jetzt alles bearbeitet werden //Here one can work with the parameters 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); SendMessage(HWND_BROADCAST, WM_MOUSEHOOKMSG, wParam, lParam); end; end; end; Ich glaube, dass ich nach SendMessage() das result neutralisieren muss, wenn ich das Ereignis verwerfen möchte. Das Problem: Die Message WM_MOUSEHOOKMSG müsste dann ja auch noch ein Ergebnis zurückliefern, in dem steht, ob das WM_MOUSE* Ereignis gelöscht wird oder nicht. Gibt es denn keine bessere Lösung, bei der ich das Maus-Links-Klick-Ereignis löschen kann, ohne die DLL unnötig zu erweitern? Gruß blackdrake |
Re: Maus sperren während Tastatureingabe
Vielleicht ist der Maushook dann der falsche Ansatz?! Es gibt auch Messagehooks :-)
|
Re: Maus sperren während Tastatureingabe
Och nö, wie soll denn das jetzt gehen?
Ich habe mal versucht, ![]() Außerdem wird nirgends beschrieben, WIE dieser Left-Mouse-Hook (im Link Middle-Mouse-Hook) nun angewandt wird, also dass der Hook sich tatsächlich als Ereignis auf meine Anwendung auswirkt. Folgendes scheint nicht zu funktionieren:
Delphi-Quellcode:
Kann mir bitte jemand helfen? Ich möchte ein systemglobales Maus-Hook mit der möglichkeit, das Mausereignis innerhalb meiner Anwendung (also nicht in der DLL) rückgängig zu machen.
public
procedure Test(var msg: TWMNCLButtonDown); message WM_NCLBUTTONDOWN; end; procedure RunHook; stdcall; external 'left_mouse_hook.dll' name 'RunHook'; procedure KillHook; stdcall; external 'left_mouse_hook.dll' name 'KillHook'; procedure TForm1.Test(var msg: TWMNCLButtonDown); begin Button1.Caption := IntToStr(GetTickCount()); end; procedure TForm1.FormCreate(Sender: TObject); begin RunHook; end; procedure TForm1.FormDestroy(Sender: TObject); begin KillHook; end; |
Re: Maus sperren während Tastatureingabe
Erstelle eine MMF mit einem eindeutigen Namen (am besten ein GUID). In diese schreibst du von der Anwendung aus das Fensterhandle deines Forms. In der DLL öffnest du die MMF und schickst deine eigene Nachricht an das Fenster, am besten eine mit RegisterWindowMessage registrierte. Dieses Senden sollte unbedingt mit SendMessageTimeout erfolgen und mit den Flags SMTO_ABORTIFHUNG sowie SMTO_BLOCK! Alles andere kann dazu führen, dass das System nicht mehr zu gebrauchen ist. Dein Formular kann mit dem Nachrichten-Ergebnis mitteilen, ob der Hook die alte Nachricht weiterleiten oder verändern soll.
|
Re: Maus sperren während Tastatureingabe
Oh je, sowas kompliziertes habe ich noch nicht gehört :pale: Geht denn das nicht auch einfacher oder irgendwie als existierenden Code, den man umändern kann?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:25 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