简单的 WH_GETMESSAGE 钩子的使用。
MessageHook.h
#ifndef __MessageHook_h__
#define __MessageHook_h__
#include <Windows.h>
#include <tchar.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DLL_EXPORT
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
BOOL DLLAPI SetHook ( HWND hWnd );
BOOL DLLAPI RemoveHook ();
#ifdef __cplusplus
}
#endif
#endif // __MessageHook_h__
MessageHook.c
#define DLL_EXPORT
#include "MessageHook.h"
#pragma data_seg( "share" )
HHOOK g_hHook = NULL;
#pragma data_seg()
HWND g_hWnd = NULL;
HINSTANCE g_hInstance = NULL;
#pragma comment( linker, "/section:share, /RWS" )
LRESULT CALLBACK msghook_proc( UINT nCode, WPARAM wParam, LPARAM lParam );
BOOL APIENTRY DllMain( HINSTANCE hInstance, DWORD reason, LPVOID reserved )
{
switch( reason ) {
case DLL_PROCESS_ATTACH:
g_hInstance = hInstance;
return TRUE;
case DLL_PROCESS_DETACH:
RemoveHook();
return TRUE;
}
return TRUE;
}
BOOL DLLAPI SetHook( HWND hWnd )
{
if( NULL != g_hWnd )
return FALSE;
g_hHook = SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC)msghook_proc, g_hInstance, 0 );
if( NULL != g_hHook ) {
g_hWnd = hWnd;
return TRUE;
}
return FALSE;
}
BOOL DLLAPI RemoveHook()
{
if( NULL == g_hHook )
return FALSE;
if( UnhookWindowsHookEx(g_hHook) ) {
g_hWnd = NULL;
return TRUE;
}
return FALSE;
}
LRESULT CALLBACK msghook_proc( UINT nCode, WPARAM wParam, LPARAM lParam )
{
LPMSG lpMsg = NULL;
TCHAR lpszMsg[128] = { 0 };
POINT pt = { 0 };
HMENU menu = NULL;
HMENU submenu = NULL;
if( nCode < 0 ) {
CallNextHookEx( g_hHook, nCode, wParam, lParam );
return 0;
}
lpMsg = (LPMSG)lParam;
switch( lpMsg->message ) {
case WM_LBUTTONDBLCLK:
pt = lpMsg->pt;
ScreenToClient( g_hWnd, &pt );
_stprintf( lpszMsg, _T("Left Button Double Clicked !\r\nX:%d, Y:%d"), pt.x, pt.y );
MessageBox( g_hWnd, lpszMsg, _T(":-)"), MB_ICONINFORMATION | MB_OK );
break;
case WM_RBUTTONDOWN:
pt = lpMsg->pt;
menu = GetMenu( g_hWnd );
if( menu ) {
submenu = GetSubMenu( menu, 0 );
if( submenu )
TrackPopupMenu( submenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, g_hWnd, NULL );
}
default:
break;
}
return CallNextHookEx( g_hHook, nCode, wParam, lParam );
}
测试代码:
BOOL CMessageHookTestDlg::OnInitDialog()
{
//......
SetHook( this->m_hWnd );
return TRUE;
}
void CMessageHookTestDlg::OnDestroy()
{
CDialogEx::OnDestroy();
RemoveHook();
}
void CMessageHookTestDlg::OnFileExit()
{
OnOK();
}
运行效果: