用 2017 工具链编译, 创建线程这一步就卡住不运行了:
换 2019 编译,线程运行正常,钩子成功注册:
C++代码:
#include <Windows.h>
#include <stdio.h>
#include <thread>
extern "C" {
__declspec(dllexport) BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved) // reserved
{
// Perform actions based on the reason for calling.
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
// Initialize once for each new process.
// Return FALSE to fail DLL load.
printf("附加到进程\n");
std::thread th([]{
HHOOK hook = SetWindowsHookExW(WH_KEYBOARD_LL, (HOOKPROC)[](int code, WPARAM wParam, LPARAM lParam)->LRESULT{
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
// Do the wParam and lParam parameters contain information about a keyboard message.
if (code == HC_ACTION)
{
// Messsage data is ready for pickup
if (wParam == WM_SYSKEYDOWN || wParam == WM_KEYDOWN)
{
if (p->vkCode == VK_LWIN)
{
printf("拦截 KeyDown 事件\n");
return TRUE;
}
}
}
// hook procedure must pass the message *Always*
return CallNextHookEx(NULL, code, wParam, lParam);
}, NULL, 0);
printf("hook = %p\n", hook);
MSG msg = {0};
while (1) {
GetMessage(&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
});
th.detach();
break;
}
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
printf("附加到线程\n");
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
printf("从线程分离\n");
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
printf("从进程分离\n");
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.