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

}

ループの進行中にキーを押すたびにこのコードを実行すると、コンソールにメッセージが出力されてファイルが作成されますが、何も起こりません。何が間違っていますか?

4

4 に答える 4

8

別のトピックから引用します:

コンソールウィンドウは、システムプロセスであるCSRSSによって完全に処理されます。プロセスにフックをインストールするということは、DLLをプロセスに挿入することを意味します。CSRSSは非常に重要であるため(システムの実行に不可欠であり、内部のコードはローカルのスーパー管理者ユーザーであるLocalSystemとして実行されます)、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実行し、閉じる前に入力を開始します-フック呼び出しを取得し始めます。

于 2012-06-24T11:10:46.200 に答える
1

Sleep(1000)タイムアウト間隔が経過するまで、現在のスレッドの実行を一時停止します。これは、このスリープ中にプログラムが実際に実行されていない(つまり、メッセージを処理していない)ことを意味します。

別の種類のコマンドを使用する必要があります。これにより、メッセージループが実行され続けます。最も簡単なことは、ユーザー入力を待つことです

while(true)
   std::cin.get(); 
于 2012-06-24T10:49:37.527 に答える
1

SetWindowsHookEx のドキュメントを読んでください。機能していますか。失敗した場合は NULL を返します。GetLastError() を呼び出してエラー コードを取得し、問題の診断に役立てることができます。

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

于 2012-06-24T10:08:53.383 に答える
0

キーボードをフックする dll を作成し、そこで関数を使用して で使用できるDllMainを取得しました。HINSTANCESetWindowsHookEx

次に、すべてのスレッドがフックされるように、threadid として 0 も使用しました。

おそらく、同様の戦術を試すこともできます。

于 2012-06-24T12:10:06.983 に答える