上一节讲局部钩子,是仅限本软件内,现在所讲的全局钩子.例如:播放器->表示快进,但是切换窗口之后,比如切换到QQ上之后,在按->,就不表示快进了.如果我想表示快进?怎么办?使用全局钩子就能实现
补充一下:参考局部钩子消息机制图,它当时钩的仅是本软件的,当然也能钩住整台电脑的消息----->那我应该怎样钩住整台电脑的消息呢?
解决办法:在安装钩子的时候,设置参数4为0,即表示钩住整台电脑了(局部是GetCurrentThreadId(),参数3为0),此地参数3为指定的***.DLL或***.exe(如果不指定,默认为.dll)
------>你也可以这样认为:安装钩子的函数SetWindowsHookEx参数3为0表示局部,参数4为0表示全局
--------本文分几个模块 模块1:鼠标全局钩子 模块2:键盘全局钩子 模块3:****跟踪更新****----------
----------------模块1:鼠标全局钩子------------------注:从此开始,一定要分清好步骤(别搞混了)
首先:我在讲一边怎样调用全局的(上面刚讲过).参数4为0.参数3就要是.dll的文件,所以说这里主要就是要1个.dll即可---->追踪.dll
--->怎样搞一个.DLL文件呢?VC里有专门创建DLL的--->行.目标很明确了
--->我现在要做的就是,第1步:创建一个DLL文件,第2步.就是把这个DLL文件加载到程序中,即可
第1步:创建MFC DLL(注:VC++6.0是win32 DLL,这里的MFC DLL仅是增加了空的.h与.cpp文件而已,比如增加了.cpp与.def,方便而已)
第2步:复制代码1(自带.cpp文件内容,删了也行,不删也行),复制代码2,OK---------->详见代码区
---------------------注意:到第2步的时候,已经完成了DLL文件的编写
第3步:别人怎样使用我的.DLL文件呢?
步骤1:复制代码3
步骤2:(1)复制2个文件(.dll文件与.lib文件,就是第2步编译好的那个文件),到自己程序的目录里
(2)菜单栏->项目->属性->Link(链接器),将.lib文件路径,添加进去
**********此处路径:有3种办法:指定,未指定.与未指定..为不影响主题,另外写一篇文章来介绍*********
-----------------------------模块2:键盘全局钩子-------------------------------------
首先,在这里不能简单的使用return 1;因为鼠标与键盘都全局钩子了,那谁来关闭它,只能重启了.所以.这里要设置一个退出的后门
第1步:复制代码1(DLL文件),复制代码2(对话框程序中)
---------模块3:设置成顶层窗口---------
用GetSystemMetrics()获得坐标,用SetWindowPos()设置顶层.与钩子无关,为突出主题,所以不介绍了--->以前做过顶层窗口,搜索下本博客
---------------------------总结一下前3个模块-----------------------------
总结:
问题1.现在能不能实现全局了?能,但不完善!当运行程序的时候,控制的仅仅是一部分,还是有些不能控制,另外设置的后门关闭F2,在切换窗口后也不能使用--->因为不想让原有DLL造成错误,书中提到了"写入时复制"机制,如图所示
解决办法:在切换到别的窗口时,为了让F2关闭,应该怎么做?---------------注:前3个模块仅是做了一半(如参数4为0都已做完),还有一半
---------模块3:"写入时复制"机制---------
第1步:复制代码1(注:为突出主题,所以取消了鼠标钩子切换到别的窗口,看效果)---完成!
--------
到现在为止,已实现了全局钩子的功能,在别的窗口时,按下一个键,响应的却是另一个程序
-----------------------------代码区---------------------------------------
----------------模块1:鼠标全局钩子------------------
代码1:.cpp文件内容
#include
HHOOK g_hMouse;
LRESULT CALLBACK MouseProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // mouse coordinates
);
void SetHook()
{
g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
}
LRESULT CALLBACK MouseProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // mouse coordinates
)
{
return 1;
}
代码2:.def文件内容
LIBRARY Hook
EXPORTS
SetHook @2
;注释符号
代码3:
_declspec(dllimport) void SetHook();//放在.h或.cpp文件最上面
SetHook();//放在.cpp文件任意地方(除特殊地方外,比如头文件或映射宏等之类),此处放在OnInitDialog()中
----------------------------------------------
备注1:代码1和局部钩子写法一样,代码2/3是照着写就可以了
备注:补充的,供参考而已----->参数3(HINSTANCE hMod)一般用GetModuleHandle("Hook")就可以了,可不可以用另外一种方法?可以
HINSTANCE g_hInst;
BOOL WINAPI DllMain(//DLLMain是动态链接库入口函数,参数1就是指定的模块句柄,只要取出这个句柄,就能提供给安装钩子用了
HINSTANCE hinstDLL, // handle to the DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
g_hInst=hinstDLL;
}
注意:MFC DLL封装好的,不像win32 DLL那样,可以灵活调用DLLMain入口函数,这里仅供参考,真正使用起来推荐GetModuleHandle
-----------------模块2:键盘全局钩子--------------------
代码1:DLL文件(知道怎么复制吧.和鼠标代码一样)
HWND g_hwnd;
g_hwnd=m_hWnd;
g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,0,GetCurrentThreadId());
LRESULT CALLBACK KeyboardProc(
int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
)
{
// if(VK_SPACE==wParam&&(0==(lParam>>31&1)))
// if(VK_F4==wParam&&(1==(lParam>>29&1))&&(0==(lParam>>31&1)))
// if(VK_NUMPAD5 ==wParam)//数字键盘上的5
if(VK_F2==wParam)
{
// AfxMessageBox("请注意:您现在按下的是键盘空格钩子");
// AfxMessageBox("请注意:您现在按下的是Alt+F4组合键钩子");
::SendMessage(g_hwnd,WM_CLOSE,0,0);
UnhookWindowsHookEx(g_hKeyboard);
return 1;
}
// else
// return CallNextHookEx(g_hKeyboard,code,wParam,lParam);//CallNextHookEx,就是这样使用的.后3个参数是回调函数传
递进来的
}
代码2(对话框程序中)
_declspec(dllimport) void SetHook(HWND hwnd);//放在.h或.cpp文件最上面
SetHook(m_hWnd);//放在.cpp文件任意地方(除特殊地方外,比如头文件或映射宏等之类),此处放在OnInitDialog()中
---------模块3:"写入时复制"机制---------
代码1:在DLL中复制在.h或.cpp最上面(除特殊地方外,比如文件或映射宏等之类)
#pragma data_seg("MySec") //开始新建节
HWND g_hwnd=NULL; //详见备注1
#pragma data_seg() //节结尾
#pragma comment(linker,"/section:MySec,RWS")
/*//注:在.def中的另一种写法,但是效果仅限局部,所以以后用上面那种写法
;SEGMENTS
;MySec READ WRITE SHARED
*/
备注1:第1必须初始化,否则不认 第2必须定义:当句柄传进来时.1份给了回调函数 1份给了DLL------>给回调函数,很明显指定在自己窗口,而
给DLL,则采用了"写入时复制"(DLL的一个概念),新的页面是给别的进程用的,也就是说,在别人的窗口上,别人指向的窗口句柄,别人说了不算,
一切由传的句柄说了算.------>即播放电影时,->快进,如果窗口切换到QQ上,按->,播放器依然会运行快进
备注2:dumpbin使用----------注:此DOS命令不能在系统自带的CMD中运行(不是系统原因:XP与win7都试过),只能在VS提供的CMD中运行(VS工
具包中),它是做什么用的呢?DUMPBIN.EXE是Fortran PowerStation的清单程序,具有提供资DLL中所输出的符号的清单的功能.详见百度百科
-----------------
附注1:源代码已上传至邮箱,即取即用
附注2:全局钩子远不止这点功能,以后继续更新...