我正在开发一个可全局监听触摸事件的应用程序,并在该应用程序上设置了一个钩子来检索WM_TOUCH
消息。该消息将从WH_GETMESSAGE
挂钩中检索。
问题在于,每次我运行该应用程序时,explorer.exe
都会崩溃,并且需要很长时间才能再次打开。在这个问题上可以有人吗?我以前使用过WH_KEYBOARD_LL
来完成此操作,但是它做的却不一样。
这,而且我仍然没有任何全局触摸事件。
我已经如下设置了我的钩子:
public void hook() {
IntPtr hInstance = LoadLibrary("User32");
hhook = SetWindowsHookEx(WH_GETMESSAGE, hookProc, hInstance, 0); // set Thread ID to 0 to listen to all threads within the same desktop
}
我已阅读有关在MSDN here上设置全局挂钩的信息。
我还在应用程序窗口中调用了RegisterTouchWindow
函数以启用接收触摸事件。
答案 0 :(得分:0)
我将尝试尽可能详细地回答我的问题,以使其他初学者了解正在发生的事情。
首先,我遵循了如何从MSDN Hook Documentation创建钩子的指南,但是该示例显示了它在c ++上的用法。在使用SetWindowHookEx
搜索了参考文献之后,我阅读了有关挂钩低级Windows挂钩的示例。这些挂钩(即WH_KEYBOARD_LL
和WH_MOUSE_LL
)是最常见的教程,可以全局挂钩,而无需将其挂钩进程分离为dll。如果WH System Events
的其余部分要全局挂接,则需要分开。文档中也对此进行了描述:
必须将全局挂钩过程放置在与安装挂钩过程的应用程序分开的DLL中。正在安装的应用程序必须具有DLL模块的句柄,然后才能安装挂钩过程。
背后的大概想法是,钩子函数被注入到所有正在运行的线程中。对于WH_KEYBOARD_LL
和WH_MOUSE_LL
使用User32.dll
作为其钩子库的情况,这很好。但是,如果像我一样将它用于其他系统事件,则该过程可能会使整个桌面崩溃,就像它发生的方式一样。
我的应用程序是用C#编码的,所以我必须用c ++创建一个dll,然后将其链接到我的C#应用程序。另外,请阅读有关pInvokes
的信息,以便能够使用LoadLibrary
和GetProcAddress
您可以从Visual Studio本身创建dll
文件。您只需要修改dllmain.cpp文件。我玩过这个example
WH_GETMESSAGE
在我的C#应用中,我要做的就是像这样调用SetHook
函数:
IntPtr hInstance = IntPtr.Zero;
IntPtr hProc = IntPtr.Zero;
private delegate void HookSetting();
public void SetHook()
{
hInstance = LoadLibrary("Dll1");
if (IntPtr.Zero == hInstance)
{
//do a null check
}
hProc = GetProcAddress(hInstance, "_SetHook@0"); // SetHook is in its "mangled" form right here
if(IntPtr.Zero == hProc)
{
//do a null check
}
//Ways of starting the Hook:
// OPTION 1: calling the SetHook function of the DLL within the C# app.
//HookSetting hookset = (HookSetting)Marshal.GetDelegateForFunctionPointer(hProc, typeof(HookSetting));
//hookset();
// OPTION 2: Instead of using the SetHook function, call the SetwindowsHookEx directly
hhook = SetWindowsHookEx(WH_GETMESSAGE, hProc, hInstance, 0);
}