使用WH_KEYBOARD的SetWindowsHookEx不适用于我,我错了什么?

#include <iostream> #include <fstream> #define _WIN32_WINNT 0x501 #include <windows.h> using namespace std; HHOOK hKeyboardHook = 0; LRESULT CALLBACK KeyboardCallback(int code,WPARAM wParam,LPARAM lParam) { cout << "a key was pressed" << endl; ofstream myfile; myfile.open ("hookcheck.txt", ios::ate | ios::app); myfile << "a key was pressed\n"; myfile.close(); return CallNextHookEx(hKeyboardHook,code,wParam,lParam); } int main() { HWND consoleWindow = GetConsoleWindow(); HINSTANCE hInstCons = (HINSTANCE)GetWindowLong( consoleWindow, GWL_HINSTANCE ); hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyboardCallback, (HINSTANCE)consoleWindow, GetCurrentThreadId()); MessageBox(NULL, "It is keyboard time!", "Let's Go", MB_OK); } 

当循环进行时,每次按键时的这个代码应该在控制台上打印消息并创build一个文件,但是没有任何事情发生。 我错了什么?

Solutions Collecting From Web of "使用WH_KEYBOARD的SetWindowsHookEx不适用于我,我错了什么?"

我会引用另一个话题 :

控制台窗口完全由CSRSS处理,这是一个系统过程。 在进程中安装钩子意味着将DLL注入到其中。 由于CSRSS非常重要(对系统的运行至关重要,而且本地代码是本地超级管理员用户),因此不允许向其中注入代码。 所以你不能挂任何的窗口。

在简单的控制台应用程序中没有发生真正的窗口消息,所以你的钩子不必被调用,在你的情况下,你甚至不注入你的钩子,而只使用线程模式钩子。 每消息即将被处理时,它被称为每个MSDN文档:

与SetWindowsHookEx函数一起使用的应用程序定义或库定义的回调函数。 每当应用程序调用GetMessage或PeekMessage函数并且有一个键盘消息(WM_KEYUP或WM_KEYDOWN)需要处理时,系统调用此函数。

现在让我告诉你,你可以做什么来开始在你的钩子接受电话:

 MessageBox(NULL, _T("It is keyboard time!"), _T("Let's Go"), MB_OK); //for(int i=0; i<=10; i++) { // cout << i << endl; // Sleep(1000); //} 

MessageBox和关闭它之前开始输入 – 你将开始获得挂钩调用。

阅读SetWindowsHookEx的文档。 它是否工作,如果失败,将返回NULL,并且可以调用GetLastError()来获取错误代码,以帮助诊断错误。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx

Sleep(1000)暂停当前​​线程的执行,直到超时间隔结束。 这意味着你的程序在休眠期间并不实际运行(即处理消息)。

您需要使用不同类型的命令,以保持消息循环运行。 最简单的事情就是等待用户输入

 while(true) std::cin.get(); 

我创建了一个钩住键盘的dll,并在那里使用了DllMain函数来检索可以在SetWindowsHookEx使用的HINSTANCE

接下来,我也使用0作为threadid所以所有的线程都被钩住了。

也许你也可以尝试类似的策略。