今天这个话题比较简单,仅截取同进程的窗体消息,如果我们再做一些处理做成一个DLL然后将DLL驻入到指定进程的窗体中那更有意思了, 我们将在后面的章节里再研究一下。 我们开始学习了。 本节与上一节都在讲述着同相的内容围绕着GetWindowLongPtr, SetWindowLongPtr两个API进行的
(一) 函数声明
LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex );
LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong );
获取/修改Window窗体信息值
Code1: 通过修改窗体过程函数来截取窗体消息
1. 为了保存原窗体过程函数, 我们将它到设置USER_DATA位,实现各函数数据共享;
2. 通过SetWindowLongPtr, 来设置新的窗体过程函数;
if (! bHook )
{
TCHAR szTmp [ MAX_PATH ];
TCHAR szClsName [ MAX_PATH ];
GetClassName ( hWnd , szClsName , MAX_PATH );
WNDCLASSEX wcx = {0};
wcx . cbSize = sizeof ( WNDCLASSEX );
SetWindowText ( GetDlgItem ( hWnd , ID_BTNHOOKMSG ), _T ( "Stop Hook" ));
OutputDebugString ( _T ( "\n============== Start Hook Message ================\n" ));
GetClassInfoEx ( GetModuleHandle ( NULL ), szClsName , & wcx );
_stprintf_s ( szTmp , _T ( "WndProc Value before SetWindowLongPtr: 0x%0X ==> 0x%0X\n" ), wcx . lpfnWndProc , GetWindowLongPtr ( hWnd , GWLP_WNDPROC ));
OutputDebugString ( szTmp );
SetWindowLongPtr ( hWnd , GWLP_USERDATA , ( LONG ) WndProc );
SetWindowLongPtr ( hWnd , GWLP_WNDPROC , ( LONG ) _HookWndProc );
GetClassInfoEx ( GetModuleHandle ( NULL ), szClsName , & wcx );
_stprintf_s ( szTmp , _T ( "WndProc Value After SetWindowLongPtr: 0x%0X ==> 0x%0X\n" ), wcx . lpfnWndProc , GetWindowLongPtr ( hWnd , GWLP_WNDPROC ));
OutputDebugString ( szTmp );
OutputDebugString ( _T ( "==================================================================\n" ));
bHook = true ;
} else {
SetWindowText ( GetDlgItem ( hWnd , ID_BTNHOOKMSG ), _T ( "Start Hook" ));
OutputDebugString ( _T ( "\n============== Stop Hook Message ================\n" ));
SetWindowLongPtr ( hWnd , GWLP_USERDATA , ( LONG )0);
SetWindowLongPtr ( hWnd , GWLP_WNDPROC , ( LONG ) WndProc );
bHook = false ;
}
3. 在新的窗体过程函数中打印被截取消息
//
LRESULT CALLBACK _HookWndProc ( HWND hWnd , UINT nMsg , WPARAM wParam , LPARAM lParam )
{
TCHAR szTemp [256];
_stprintf_s ( szTemp , _T ( "[HookProc msg] => hWnd: 0x%06X nMsg: %06X wParam: 0x%06X lParam: 0x%06X\n" ),
hWnd , nMsg , wParam , lParam );
OutputDebugString ( szTemp );
WNDPROC _oldWndProc = ( WNDPROC ) GetWindowLongPtr ( hWnd , GWLP_USERDATA );
if ( NULL == _oldWndProc )
{
_oldWndProc = ( WNDPROC ) GetClassLongPtr ( hWnd , GCLP_WNDPROC );
}
return _oldWndProc ( hWnd , nMsg , wParam , lParam );
}
演示结果:
1. 没修改窗体过程前
[WndProc msg] => hWnd: 0x010BBA nMsg: 0000A0 wParam: 0x000012 lParam: 0x282023C
[WndProc msg] => hWnd: 0x010BBA nMsg: 0002A2 wParam: 0x000000 lParam: 0x000000
[WndProc msg] => hWnd: 0x010BBA nMsg: 000086 wParam: 0x000000 lParam: 0x000000
[WndProc msg] => hWnd: 0x010BBA nMsg: 000006 wParam: 0x000000 lParam: 0x000000
[WndProc msg] => hWnd: 0x010BBA nMsg: 00001C wParam: 0x000000 lParam: 0x001B10
[WndProc msg] => hWnd: 0x010BBA nMsg: 000008 wParam: 0x000000 lParam: 0x000000
[WndProc msg] => hWnd: 0x010BBA nMsg: 000281 wParam: 0x000000 lParam: 0xC000000F
[WndProc msg] => hWnd: 0x010BBA nMsg: 000282 wParam: 0x000001 lParam: 0x000000
2. 修改窗体过程之后
WndProc Value before SetWindowLongPtr: 0x8C11B8 ==> 0x8C11B8
WndProc Value After SetWindowLongPtr: 0x8C11B8 ==> 0x8C10DC
==================================================================
[WndProc msg] => hWnd: 0x010BBA nMsg: 000111 wParam: 0x0003E9 lParam: 0x010BBE
[HookProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[HookProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[HookProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
3. 恢复原窗体过程
[WndProc msg] => hWnd: 0x010BBA nMsg: 000111 wParam: 0x0003E9 lParam: 0x010BBE
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
[WndProc msg] => hWnd: 0x010BBA nMsg: 000020 wParam: 0x010BBE lParam: 0x2000001
(二) 特别说明
演示的代码里我们也在设置窗体过程函数前后打印了WNDCLASSEX类信息, 也发布我们设置的窗体过程并没有修改了WNDCLASS wndProc;