使用WH_KEYBOARD的SetWindowsHookEx对我不起作用,我有什么不对?

rsk*_*k82 3 c++ windows console winapi keyboard-hook

#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);

}
Run Code Online (Sandbox Code Playgroud)

循环进行时每次按键时此代码都应该在控制台上打印消息并创建一个文件,但什么也没发生.我错了什么?

Rom*_* R. 8

我将引用另一个主题:

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

您的简单控制台应用程序中没有真正的窗口消息,因此您不必调用挂钩,在您的情况下,您甚至不会注入挂钩而只使用线程模式挂钩.根据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);
//}
Run Code Online (Sandbox Code Playgroud)

这样做MessageBox并关闭它开始键入之前-你会开始得到钩电话.