WH_CALLWNDPROC怎么在win7下 截获记事本的wm_close消息 WH_CALLWNDPROC钩子在xp下可以正常截获消息,但在win7下只能截获自己的消息是怎么回事? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 麻烦各位大神 告知问题出在哪里?win7需要做特殊处理吗 1 Hook其它进程的 需要做成DLL2 如果64位系统 可能需要编译成64位3 检查钩子是否安装成功 WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/ 钩子的确是做成的dll,win764位32位都尝试了还是只能获取自己进程的消息,从SetWindowsHookEx返回值看是安装成功了。总之就是只能在自己进程中有效果,应该是没注入其他进程空间中。但是在xp下一切正常。 附上简单demo伪代码 ,帮忙看看有什么问题钩子dll的头文件HookDll.h#ifdef KEYHOOKLIB_EXPORTS #define KEYHOOKLIB_API extern "C" __declspec(dllexport) //导出宏 #else #define KEYHOOKLIB_API extern "C" __declspec(dllimport) //导入宏 #endif #include <windows.h>#include <string>#include <vector>using namespace std;// 自定义与主程序通信的消息 #define HM_MYHOOK WM_USER + 105 //自定义消息 // 声明要导出的函数 KEYHOOKLIB_API BOOL SetHook(BOOL bInstall, DWORD dwThreadId = 0, HWND hWndCaller = NULL);钩子dll的cpp文件HookDll.cpp:#define KEYHOOKLIB_EXPORTS#include "HookDll.h"#pragma data_seg("MyShared") HWND g_hWndCaller = NULL; // 保存传入dll的exe中主窗口句柄HHOOK g_hHook = NULL; // 保存生成的钩子句柄 #pragma data_seg() HINSTANCE g_hCwInst;///////////////////////////////////////////////////////////////////////////////int WriteLog1(const char * str){ FILE * log; log = fopen("C:\\log_msghook.txt", "a+"); if (log == NULL) return -1; fprintf(log, "%s\n", str); fclose(log); return 0;}///////////////////////////////////////////////////////////////////////////////LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){ char szTemp[MAX_PATH] = {0}; if (nCode < 0) { return CallNextHookEx(g_hHook, nCode, wParam, lParam); } PCWPSTRUCT msg; msg = (PCWPSTRUCT)lParam; //tagMSG* msg; //msg = (tagMSG*)lParam; DWORD idProcess; DWORD Idthread = GetWindowThreadProcessId(msg->hwnd, &idProcess); sprintf(szTemp, "消息类型是:%d而nCode是:%d而窗口句柄是:%x而线程id是:%d而进程id是:%d", msg->message, nCode, msg->hwnd, Idthread, idProcess); WriteLog1(szTemp); if (nCode == HC_ACTION && (msg->message == WM_CLOSE) && msg->hwnd != g_hWndCaller) { sprintf(szTemp, "截获消息的窗口句柄%d而被截获消息的进程id是:%d", (int)g_hWndCaller, idProcess); WriteLog1(szTemp); ::PostMessageW(g_hWndCaller, HM_MYHOOK, wParam, (LPARAM)msg->hwnd); return CallNextHookEx(g_hHook, nCode, wParam, (LPARAM)msg); } return CallNextHookEx(g_hHook, nCode, wParam, lParam);}KEYHOOKLIB_API BOOL SetHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller){ BOOL bOk; g_hWndCaller = hWndCaller; char szTemp[MAX_PATH] = { 0 }; sprintf(szTemp, "传进来的窗口句柄%d", (int)hWndCaller); WriteLog1(szTemp); if (bInstall) { g_hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, HookProc, g_hCwInst, dwThreadId); //安装钩子 bOk = (g_hHook != NULL); if (bOk) { WriteLog1("安装钩子成功"); } } else { bOk = ::UnhookWindowsHookEx(g_hHook); g_hHook = NULL; } return bOk;}BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hCwInst = hModule; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE;}钩子dll的描述文件Source.def:LIBRARY HookDllEXPORTS SetHookSECTIONS MyShared Read Write Shared调用程序的源文件MainWnd.cpp:#include "HookDll.h" //钩子dll的头文件#include <stdio.h>#include <tchar.h>#pragma comment(lib,"HookDll.lib")//钩子dll项目生成的引入库文件#define MAX_LOADSTRING 100// 全局变量: HINSTANCE hInst; // 当前实例TCHAR szTitle[MAX_LOADSTRING] = {_T("hookmsg")}; // 标题栏文本TCHAR szWindowClass[MAX_LOADSTRING] = { _T("hookmsg") };; // 主窗口类名// 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);HWND g_wnd;int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow){ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。 MSG msg; MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance(hInstance, nCmdShow)) { return FALSE; } // 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } ::SetHook(FALSE);//取消安装钩子 return (int)msg.wParam;}//// 函数: MyRegisterClass()//// 目的: 注册窗口类。//ATOM MyRegisterClass(HINSTANCE hInstance){ WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, NULL); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDC_ARROW)); return RegisterClassEx(&wcex);}//// 函数: InitInstance(HINSTANCE, int)//// 目的: 保存实例句柄并创建主窗口//// 注释: //// 在此函数中,我们在全局变量中保存实例句柄并// 创建和显示主程序窗口。//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); g_wnd = hWnd; if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;}//// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)//// 目的: 处理主窗口的消息。//// WM_COMMAND - 处理应用程序菜单// WM_PAINT - 绘制主窗口// WM_DESTROY - 发送退出消息并返回//LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: { if (!hWnd) { MessageBoxA(NULL, "121212", "", 0); } if (!SetHook(TRUE, 0, hWnd)) MessageBox(NULL, L"安装钩子失败!", L"", 0); } break; case HM_MYHOOK: { char szTemp[MAX_PATH] = { 0 }; HWND msg; msg = (HWND)lParam; DWORD idprocess; DWORD Idthread = GetWindowThreadProcessId(msg, &idprocess); sprintf(szTemp, "id为%d的进程要关闭窗口,线程id为%d", idprocess, Idthread); MessageBoxA(NULL, szTemp, "截获到消息:", 0); } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;} SPY++ 试试看 是否有WM_CLOSE消息? WinAPIOverride是开源的。 vc调用dll中的结构体 为什么不能定义一个对话框的变量 com组件,不是activex控件可以放到ie浏览器上吗? ☆帮我想想 老板键(隐藏IE) 的原理。谢谢了!!!! 怎么做一个象3721一样的浏览到该网页就提示下载安装的功能 请问多少分可以加等级 简单的问题,但很急,麻烦各位大虾了 关于ListCtrl,界面高手请进 最简单的问题,指针赋值。 不用findWindow怎么在线程里获得窗口类指针或者句柄 聊天窗口如何实现实时滚动? 怎么用vc6.0抓取百度百科词库中所有词语?
2 如果64位系统 可能需要编译成64位
3 检查钩子是否安装成功
钩子的确是做成的dll,win764位32位都尝试了还是只能获取自己进程的消息,从SetWindowsHookEx返回值看是安装成功了。
总之就是只能在自己进程中有效果,应该是没注入其他进程空间中。但是在xp下一切正常。
#ifdef KEYHOOKLIB_EXPORTS
#define KEYHOOKLIB_API extern "C" __declspec(dllexport) //导出宏
#else
#define KEYHOOKLIB_API extern "C" __declspec(dllimport) //导入宏
#endif
#include <windows.h>
#include <string>
#include <vector>
using namespace std;// 自定义与主程序通信的消息
#define HM_MYHOOK WM_USER + 105 //自定义消息
// 声明要导出的函数
KEYHOOKLIB_API BOOL SetHook(BOOL bInstall, DWORD dwThreadId = 0, HWND hWndCaller = NULL);
钩子dll的cpp文件HookDll.cpp:
#define KEYHOOKLIB_EXPORTS
#include "HookDll.h"
#pragma data_seg("MyShared")
HWND g_hWndCaller = NULL; // 保存传入dll的exe中主窗口句柄
HHOOK g_hHook = NULL; // 保存生成的钩子句柄
#pragma data_seg() HINSTANCE g_hCwInst;///////////////////////////////////////////////////////////////////////////////
int WriteLog1(const char * str)
{
FILE * log;
log = fopen("C:\\log_msghook.txt", "a+");
if (log == NULL)
return -1; fprintf(log, "%s\n", str);
fclose(log);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
char szTemp[MAX_PATH] = {0};
if (nCode < 0)
{
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
PCWPSTRUCT msg;
msg = (PCWPSTRUCT)lParam;
//tagMSG* msg;
//msg = (tagMSG*)lParam;
DWORD idProcess;
DWORD Idthread = GetWindowThreadProcessId(msg->hwnd, &idProcess);
sprintf(szTemp, "消息类型是:%d而nCode是:%d而窗口句柄是:%x而线程id是:%d而进程id是:%d", msg->message, nCode, msg->hwnd, Idthread, idProcess);
WriteLog1(szTemp);
if (nCode == HC_ACTION && (msg->message == WM_CLOSE) && msg->hwnd != g_hWndCaller)
{
sprintf(szTemp, "截获消息的窗口句柄%d而被截获消息的进程id是:%d", (int)g_hWndCaller, idProcess);
WriteLog1(szTemp);
::PostMessageW(g_hWndCaller, HM_MYHOOK, wParam, (LPARAM)msg->hwnd);
return CallNextHookEx(g_hHook, nCode, wParam, (LPARAM)msg);
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}KEYHOOKLIB_API BOOL SetHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller)
{
BOOL bOk;
g_hWndCaller = hWndCaller;
char szTemp[MAX_PATH] = { 0 };
sprintf(szTemp, "传进来的窗口句柄%d", (int)hWndCaller);
WriteLog1(szTemp);
if (bInstall)
{
g_hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, HookProc,
g_hCwInst, dwThreadId); //安装钩子
bOk = (g_hHook != NULL);
if (bOk)
{
WriteLog1("安装钩子成功");
}
}
else
{
bOk = ::UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
return bOk;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hCwInst = hModule;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}钩子dll的描述文件Source.def:
LIBRARY HookDll
EXPORTS
SetHook
SECTIONS
MyShared Read Write Shared
调用程序的源文件MainWnd.cpp:#include "HookDll.h" //钩子dll的头文件
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib,"HookDll.lib")//钩子dll项目生成的引入库文件
#define MAX_LOADSTRING 100// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING] = {_T("hookmsg")}; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING] = { _T("hookmsg") };; // 主窗口类名// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND g_wnd;
int WINAPI WinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。
MSG msg; MyRegisterClass(hInstance); // 执行应用程序初始化:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
} // 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
::SetHook(FALSE);//取消安装钩子
return (int)msg.wParam;
}//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, NULL);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDC_ARROW)); return RegisterClassEx(&wcex);
}//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
g_wnd = hWnd;
if (!hWnd)
{
return FALSE;
} ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); return TRUE;
}//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc; switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
{
if (!hWnd)
{
MessageBoxA(NULL, "121212", "", 0);
}
if (!SetHook(TRUE, 0, hWnd))
MessageBox(NULL, L"安装钩子失败!", L"", 0);
}
break;
case HM_MYHOOK:
{
char szTemp[MAX_PATH] = { 0 };
HWND msg;
msg = (HWND)lParam;
DWORD idprocess;
DWORD Idthread = GetWindowThreadProcessId(msg, &idprocess);
sprintf(szTemp, "id为%d的进程要关闭窗口,线程id为%d", idprocess, Idthread);
MessageBoxA(NULL, szTemp, "截获到消息:", 0);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}