该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
VC开发实例
一、开发背景:
我想大家都有过忙手忙脚最小化窗口(或关闭窗口)的经历吧!原因很简单--不想让突如其来的老板、老妈、老婆看到我们电脑屏幕上正在显示的游戏、日记、MM:-) 等属于个人隐私的东东。
如果能做一个程序在后台运行,当我们发出一个特殊的输入事件(我选择了鼠标左、右键同时按下)时,该程序就迅速隐藏正在显示的窗口,免去人工瞄准并按下每个窗口右上方的那个小得可怜的的最小化按扭之苦了。当危险解除再利用这个特殊事件使隐藏的窗口恢复。
这对于像我这样小脑不太发达、心理素质又不过硬而又经常在老板的眼皮底下"悬崖骑马"的同志们来说是绝对有实战意义的。于是我做了这个"魔高一丈"以实现上述功能!
二、程序原理:
首先,我们得能截获鼠标左、右键同时按下去这个事件--这并不难--设一个标志变量当鼠标发出WM_LBUTTONDOWN并且又有WM_RBUTTONDOWN消息发出时把它置"1"罢了。
而我要说明的是,这个"同时按下"只是一种宏观上的概念,鼠标是不会同时发出两个消息的。其次就是解决不管鼠标位于任何窗口之上都能在程序里截获(或者称为监听更准确)到鼠标发出的消息并加以过滤的问题了,这是很关键的。我用了钩子船长的那只钩子(Hook),而且是全局的鼠标钩子,它给了我们跟操作系统沟通的一个机会。
许多比较有神秘感的程序(比如金山词霸的鼠标取词)都是用它实现的,稍后我将详细解释。最后就是剩下能得到可见的窗口的句柄(HANDLE)并根据其句柄显示、隐藏窗口的问题了,这也没什么难的有现成的API函数--EnumWindows和ShowWindow。你可以先运行一下我的程序(那个大五星,需要把它跟那个Mousehook.dll文件放在一个文件夹下)。当鼠标左右键一起按下时所有的窗口都隐藏了;再一次同时按下左右键又可恢复隐藏窗口;单击任务栏右下角(托盘)的图标可隐藏或显示本程序窗口。
三、开发步骤:
第0步、选用VC 6.0集成开发环境。
第1步、由于建立全局钩子必须把钩子函数放在DLL里面,所以我们选择MFC AppWizard(DLL)创建一个新的项目,命名为"Mousehook",再选择选择MFC Extension DLL类型(为了方便嘛!)。
为什么必须把全局钩子函数放在DLL里呢?这是因为系统会动态地调用你所添加的全局鼠标钩子,所有窗口消息数都会由于你添加了鼠标钩子而引起系统处理(何为处理?调用钩子函数也。)这必然需要操作系统能够从一个东东里动态地加入这段处理程序,而这个东东非DLL莫属。
第2步、在项目中加入Mousehook.h文件用以构造一个钩子类--CMousehook,具体如下:
class AFX_EXT_CLASS CMousehook:public CObject
{
public:
CMousehook();
~CMousehook();
BOOL starthook();//封装SetWindowsHookEx( int idHook, HOOK_PROC lpfn, HINSTANCE hMod,DWORD dwThreadID)用来安装钩子
BOOL stophook(); //封装UnhookWindowsHookEx( HHOOK hhk )用来卸载钩子
VOID SetCheck1(UINT i);//处理对话框的选择钩选框1
VOID SetCheck2(UINT i);//处理对话框的选择钩选框2
VOID SetCheck3(UINT i);//处理对话框的选择钩选框3
static BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);//系统回调的钩子函数
VOID UseForExit();//退出程序时恢复所有隐藏窗口
};
这里我想特别地提一下EnumWindowsProc函数前的CALLBACK跟static,对于CALLBACK我想给大家一个特别江湖的解释其就是:凡是由你设计而却由Windows系统调用的函数,统称callback函数。这些函数都有一定的类型,以配合Windows的调用操作。--引用台湾侯师傅的话。他还说,某些Windows API函数会要求以callback函数(的函数地址)作为其参数之一。
我们这里用到的又比如 SetWindowsHookEx( int idHook, HOOK_PROC lpfn, HINSTANCE hMod,DWORD dwThreadID)的第二个参数。这种API通常会在进行某种行为之后或满足某种状态的情况下调用其参数中的callback函数。