![]() |
Hook, als Componente
Hallo,
Wieder mal eine Frage zu Hooks :) Mein Problem ist das ich eine Komponente machen will die einen Hook beinhaltet. Problem dabei ist das ich die Hookfunktion nicht übergeben kann: SetWindowsHookEx bekommt normalerweise so HandleA := SetWindowsHookEx(WH_KEYBOARD,@Funcktion,HInstance, GetCurrentThreadId()); eine Prodedure mit. Da es aber ja in eine Componten soll sind es ja keine einfachen procedure sondern "Methoden" also procedure of object im Prinzip. Ich habs sogar hinbekommen das die Procedure aufgerufen wird, wenn ich TMethod.Code übergebe, allerdings mit Zugriffs verletzungen :) Vielleicht hat einer von euch ja schonmal so was ähnliches gemacht, bzw kennt einer evtl. nen Link zu einer Komponten die Hooks benutzt.
Delphi-Quellcode:
//type TKeyboardHookProc_object=function (Code: Integer;WordParam: Word;LongParam: LongInt): LongInt of object; stdcall;
//type PKeyboardHookProc_object=^TKeyboardHookProc_object; //type TKeyboardHookProc=function (Code: Integer;WordParam: Word;LongParam: LongInt): LongInt; stdcall; //type PKeyboardHookProc=^TKeyboardHookProc; type THook=class (Tcomponent) private FHooksActive:boolean; FHookHandle : HHook; function KeyboardHookProc2(Code: Integer;WordParam: Word;LongParam: LongInt): LongInt; stdcall; public procedure SetActive(const value:boolean); end; //......... procedure THook.SetActive(const value:boolean); var p:pointer; begin if value=FHooksActive then exit; FHooksActive:=value; if not FHooksActive then begin UnHookWindowsHookEx(FHookHandle); end else begin p:=@KeyboardHookProc2; //hier das Problem FHookHandle:=SetWindowsHookEx(WH_KEYBOARD, {callback —>} p, //hier muss die Funktion/Pointer zur Funktion übergeben werden HInstance, GetCurrentThreadId()); end; end; function THook.KeyboardHookProc2(Code: Integer; WordParam: Word; LongParam: Integer): LongInt; var shift : TShiftState; key : Word; f:Tform; KeyState1: TKeyBoardState; s:string; begin result := 0; if Code<0 then begin result:=CallNextHookEx(FHookHandle,Code,WordParam,LongParam); exit; end; //Keydown: code=3 //KeyUp: code=0; //if code<>0 then exit; // alles nur bei keyup verarbeiten... if (LongParam and (1 SHL 31) <> 0) then exit; GetKeyboardState(KeyState1); shift := []; if ((KeyState1[vk_Menu] and 128)<>0) then shift:=shift+[ssAlt]; if ((KeyState1[VK_CONTROL] and 128)<>0) then shift:=shift+[ssCtrl]; if ((KeyState1[VK_SHIFT] and 128)<>0) then shift:=shift+[ssShift]; key := WordParam; if key=VK_RETURN then key:=0; if key=VK_TAB then key:=0; if key<>0 then result:=CallNextHookEx(FHookHandle,Code,WordParam,LongParam) else begin result:=-1; //CallNextHookEx(FHookHandle,Code,0,0) end; end; |
Re: Hook, als Componente
Hab die Lösung.
scheint sehr kompliziert zu sein unter Delphi das zu instanzieren. hier noch eine lösung mit csarp, wo es sehr einfach scheint.
Delphi-Quellcode:
public class KeyHook
{ private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); //Declare hook handle as int. static int hHook = 0; public static List<Keys> KeyCodes = new List<Keys>(); //Declare keyboard hook constant. //For other hook types, you can obtain these values from Winuser.h in Microsoft SDK. const int WH_KEYBOARD_LL = 13; HookProc KeyboardHookProcedure; [StructLayout(LayoutKind.Sequential)] private class keyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } //Import for SetWindowsHookEx function. //Use this function to install thread-specific hook. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); //Import for UnhookWindowsHookEx. //Call this function to uninstall the hook. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern bool UnhookWindowsHookEx(int idHook); //Import for CallNextHookEx. //Use this function to pass the hook information to next hook procedure in chain. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll")] static extern IntPtr LoadLibrary(string lpFileName); public KeyHook() { Hook(); } ~KeyHook() { UnHook(); } public int Hook() { KeyboardHookProcedure = new HookProc(KeyHook.KeyboardHookProc); hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, (IntPtr)LoadLibrary("User32"), 0); return hHook; } public bool UnHook() { bool ret = UnhookWindowsHookEx(hHook); if (ret) hHook = 0; return ret; } private static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0) { return CallNextHookEx(hHook, nCode, wParam, lParam); } else { if (((int)wParam == 256) || ((int)wParam == 260)) { keyboardHookStruct MyKeyboardHookStruct = (keyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(keyboardHookStruct)); KeyCodes.Add((Keys)MyKeyboardHookStruct.vkCode); } return 1; } } } |
Re: Hook, als Componente
Zitat:
Du übergibst eine reine Prozedur. Die hat nun einmal keinen Bezug zu einem Objekt. Dennoch greifst du innerhalb deiner Methode auf Self (z.B. FHookHandle) zu. Das gibt es aber gar nicht. Es gibt keine Möglichkeit eine Methode inkl. Bezug zum Objekt als Callback anzugeben. Einfach weil dort nur ein Zeiger mit 4 Byte erwartet wird und die zweiten 4 Byte mit dem Zeiger auf die Instanz dort nirgends angegeben werden können. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:49 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 by Thomas Breitkreuz