使用 WinAPI WH_CALLWNDPROC 挂钩时不调用回调方法
Callback method is not called when using WinAPI WH_CALLWNDPROC hook
我想在 window 移动时收到消息。
我开始编写一个简单的 C++ 控制台应用程序,它连接到 windows 的默认记事本应用程序。
其中一部分包含以下设置钩子的代码(不是全部三个,只有一个)
_hook = SetWindowsHookEx(WH_MOUSE, CallWndProc, _dllInstance, tid); //WORKS
_hook = SetWindowsHookEx(WH_KEYBOARD, CallWndProc, _dllInstance, tid); //WORKS
_hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, _dllInstance, tid); //DOESNT WORK
所以挂钩的过程基本上是相同的,并且每种挂钩类型都使用相同的回调函数。
为什么它不适用于 WH_CALLWNDPROC?
当应用 WH_CALLWNDPROC 时,钩子像其他钩子一样成功,但它根本不起作用。
这是回调函数
// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
std::cout << "callback " << counter++ << "\n";
//This is a must
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
但是设置这个钩子时 CallWndProc 永远不会被调用。
我什至尝试在 DLL 中调用 CallWndProc 函数,但这也不起作用,所以我将它从 DLL 中完全删除,现在它是一个空 DLL。即使它有效,它对我也没有用,因为我需要在我的应用程序中处理消息,而不是在目标线程上。
有什么建议吗?这是完整的代码
#include "Main.h"
#include <Windows.h>
#include <iostream>
/* Variable to store the HANDLE to the hook. Don't declare it anywhere else then globally
or you will get problems since every function uses this variable. */
HHOOK _hook;
// the dll instance
HINSTANCE _dllInstance;
//HOOKPROC _dllCallback;
int counter = 0;
// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
std::cout << "callback " << counter++ << "\n";
//This is a must
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
// This functions installs a hook to a window with given title
int InstallHook(const wchar_t* title) {
/* 1. Get window handle of given title */
std::wcout << "INFO: Getting window handle for \"" << title << "\"...\n";
HWND hwnd = FindWindow(NULL, title);
if (hwnd == NULL) {
std::cout << "ERROR: Could not find target window.\n";
return -1;
}
/* 2. Get ThreadID (TID) of the window handle */
std::wcout << "INFO: Getting TheadID (TID) of \"" << title << "\"...\n";
DWORD pid = NULL; // If we dont know -> NULL
DWORD tid = GetWindowThreadProcessId(hwnd, &pid);
if (tid == NULL) {
std::cout << "ERROR: Could not find target window.\n";
return -2;
}
/* 3. Load in the DLL */
std::wcout << "INFO: Loading the DLL\n";
_dllInstance = LoadLibrary(TEXT("winhooks_dll.dll"));
if (_dllInstance == NULL) {
std::cout << "ERROR: Could not load DLL...\n";
return -3;
}
/* 3.5 Get Callback function from dll*/
//_dllCallback = (HOOKPROC)GetProcAddress(_dllInstance, "_wmProcCallback@12");
//if (_dllCallback == NULL) {
// std::cout << "ERROR: Could not get Callback function from dll instance\n";
// return -4;
//}
/* 4. Install the hook and set the handle */
std::wcout << "INFO: Setting the hook...\n";
_hook = SetWindowsHookEx(WH_MOUSE, CallWndProc, _dllInstance, tid); // The local callback version
//_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, _dllCallback, _dllInstance, tid); // The dll callback function
if (_dllInstance == NULL) {
std::cout << "ERROR: Could not set hook handle\n";
return -5;
}
return 0;
}
int main() {
const wchar_t* title = L"Untitled - Notepad";
if (InstallHook(title) != 0) {
std::wcout << "ERROR: Could not install hook on " << title << " last error -> " << GetLastError() << "\n";
system("pause");
return 1;
}
std::wcout << "SUCCESS: Hook is successfully installed on " << title << "\n";
std::wcout << "Running message loop..." << std::endl;
MSG msg;
while (GetMessage(&msg, NULL, 0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
首先,源平台(32位或64位)必须与目标平台匹配。(在我的64位机器上,记事本是64位的。)
其次,对于DLL中的hook程序,不要通过打印来验证是否有效,同std::out。 DLL 无处打印其内容。以下代码使用文件流。
// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION)
{
if (wParam > 0)
{
std::cout << "sent by the current thread wParam=" << wParam;
}
CWPSTRUCT* s = (CWPSTRUCT*)lParam;
//have no
std::cout << " Index=" << nwinhooksdll++ << " s->message=" << s->message << " s->hwnd=" << s->hwnd << " s->wParam=" << s->wParam << " s->lParam=" << s->lParam << "\n";
//MessageBox(NULL,L"CallWndProc",L"CALLBACK",0);
//works
myfile << " Index=" << nwinhooksdll++ << " s->message=" << s->message << " s->hwnd=" << s->hwnd << " s->wParam=" << s->wParam << " s->lParam=" << s->lParam << "\n";
}
//This is a must
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
我想在 window 移动时收到消息。
我开始编写一个简单的 C++ 控制台应用程序,它连接到 windows 的默认记事本应用程序。 其中一部分包含以下设置钩子的代码(不是全部三个,只有一个)
_hook = SetWindowsHookEx(WH_MOUSE, CallWndProc, _dllInstance, tid); //WORKS
_hook = SetWindowsHookEx(WH_KEYBOARD, CallWndProc, _dllInstance, tid); //WORKS
_hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, _dllInstance, tid); //DOESNT WORK
所以挂钩的过程基本上是相同的,并且每种挂钩类型都使用相同的回调函数。 为什么它不适用于 WH_CALLWNDPROC? 当应用 WH_CALLWNDPROC 时,钩子像其他钩子一样成功,但它根本不起作用。
这是回调函数
// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
std::cout << "callback " << counter++ << "\n";
//This is a must
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
但是设置这个钩子时 CallWndProc 永远不会被调用。
我什至尝试在 DLL 中调用 CallWndProc 函数,但这也不起作用,所以我将它从 DLL 中完全删除,现在它是一个空 DLL。即使它有效,它对我也没有用,因为我需要在我的应用程序中处理消息,而不是在目标线程上。
有什么建议吗?这是完整的代码
#include "Main.h"
#include <Windows.h>
#include <iostream>
/* Variable to store the HANDLE to the hook. Don't declare it anywhere else then globally
or you will get problems since every function uses this variable. */
HHOOK _hook;
// the dll instance
HINSTANCE _dllInstance;
//HOOKPROC _dllCallback;
int counter = 0;
// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
std::cout << "callback " << counter++ << "\n";
//This is a must
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
// This functions installs a hook to a window with given title
int InstallHook(const wchar_t* title) {
/* 1. Get window handle of given title */
std::wcout << "INFO: Getting window handle for \"" << title << "\"...\n";
HWND hwnd = FindWindow(NULL, title);
if (hwnd == NULL) {
std::cout << "ERROR: Could not find target window.\n";
return -1;
}
/* 2. Get ThreadID (TID) of the window handle */
std::wcout << "INFO: Getting TheadID (TID) of \"" << title << "\"...\n";
DWORD pid = NULL; // If we dont know -> NULL
DWORD tid = GetWindowThreadProcessId(hwnd, &pid);
if (tid == NULL) {
std::cout << "ERROR: Could not find target window.\n";
return -2;
}
/* 3. Load in the DLL */
std::wcout << "INFO: Loading the DLL\n";
_dllInstance = LoadLibrary(TEXT("winhooks_dll.dll"));
if (_dllInstance == NULL) {
std::cout << "ERROR: Could not load DLL...\n";
return -3;
}
/* 3.5 Get Callback function from dll*/
//_dllCallback = (HOOKPROC)GetProcAddress(_dllInstance, "_wmProcCallback@12");
//if (_dllCallback == NULL) {
// std::cout << "ERROR: Could not get Callback function from dll instance\n";
// return -4;
//}
/* 4. Install the hook and set the handle */
std::wcout << "INFO: Setting the hook...\n";
_hook = SetWindowsHookEx(WH_MOUSE, CallWndProc, _dllInstance, tid); // The local callback version
//_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, _dllCallback, _dllInstance, tid); // The dll callback function
if (_dllInstance == NULL) {
std::cout << "ERROR: Could not set hook handle\n";
return -5;
}
return 0;
}
int main() {
const wchar_t* title = L"Untitled - Notepad";
if (InstallHook(title) != 0) {
std::wcout << "ERROR: Could not install hook on " << title << " last error -> " << GetLastError() << "\n";
system("pause");
return 1;
}
std::wcout << "SUCCESS: Hook is successfully installed on " << title << "\n";
std::wcout << "Running message loop..." << std::endl;
MSG msg;
while (GetMessage(&msg, NULL, 0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
首先,源平台(32位或64位)必须与目标平台匹配。(在我的64位机器上,记事本是64位的。)
其次,对于DLL中的hook程序,不要通过打印来验证是否有效,同std::out。 DLL 无处打印其内容。以下代码使用文件流。
// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION)
{
if (wParam > 0)
{
std::cout << "sent by the current thread wParam=" << wParam;
}
CWPSTRUCT* s = (CWPSTRUCT*)lParam;
//have no
std::cout << " Index=" << nwinhooksdll++ << " s->message=" << s->message << " s->hwnd=" << s->hwnd << " s->wParam=" << s->wParam << " s->lParam=" << s->lParam << "\n";
//MessageBox(NULL,L"CallWndProc",L"CALLBACK",0);
//works
myfile << " Index=" << nwinhooksdll++ << " s->message=" << s->message << " s->hwnd=" << s->hwnd << " s->wParam=" << s->wParam << " s->lParam=" << s->lParam << "\n";
}
//This is a must
return CallNextHookEx(_hook, nCode, wParam, lParam);
}