SetWindowsHookEx with WH_KEYBOARD doesn't work for me, what do I wrong?

荒凉一梦 提交于 2019-12-06 08:27:16

问题


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

}

This code on every key press while the loop is going should print message on console and create a file, but nothing is happening. What do I wrong ?


回答1:


I will quote from another topic:

Console windows are handled entirely by CSRSS, which is a system process. Installing a hook into a process means injecting your DLL into it. Since CSRSS is so important (it's vital for running of the system, and code within runs as LocalSystem, which is the local super-admin user), you're not allowed to inject code into it. So you can't hook any of its windows.

There are no real window messages taking place in your simple console application, so your hook does not have to be called, and in your case you are not even injecting your hook but using thread mode hook only. Per MSDN documentation it is called when messages are about to be processed:

An application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.

Now let me show you what you can do to start receiving calls on your hook:

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);
//}

Do MessageBox and before closing it start typing - you will start getting hook calls.




回答2:


Read the documentation for SetWindowsHookEx. Is it working, it will return NULL if it fails and GetLastError() can be called to get an error code to help diagnose what is wrong.

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




回答3:


Sleep(1000) suspends the execution of the current thread until the time-out interval elapses. It means that your program is not actually running (ie. processing messages) during this sleep.

You need to use a different kind of command, that will keep the message loop running. The simplest thing would be to wait for user input

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



回答4:


I have created a dll that hooked the keyboard and in there I used the DllMainfunction to retrieve a HINSTANCE that can be used in SetWindowsHookEx.

Next to that I also used 0 as the threadid so all threads get hooked.

Perhaps you could try a similar tactic as well.



来源:https://stackoverflow.com/questions/11176408/setwindowshookex-with-wh-keyboard-doesnt-work-for-me-what-do-i-wrong

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!