双击鼠标HOOK学习

本文介绍了使用C++编写程序,通过全局鼠标HOOK(MH_MOUSE_LL)来实现双击鼠标右键隐藏和显示桌面图标的技巧。首先尝试了模拟按键但未成功,然后通过SPY++捕捉系统消息,发现使用ShowWindow(hwnd, SW_HIDE)可以隐藏桌面。由于MH_MOUSE_LL无法捕获双击事件,采用了计时器来监控两次单击的时间间隔,从而达到双击隐藏的效果。" 135653057,9306031,Redis 数据持久化:如何避免宕机数据丢失,"['Redis', '数据库', '缓存', '持久化策略']

前一阵子换了一个好看的桌面,但是图标太多挡住了很不高兴,在桌面点右键,隐藏桌面图片很麻烦,于是想做一个小软件一键隐藏、显示桌面图标,好让我欣赏壁纸。

鉴于这阵子学习C语言,就用C++写一个程序。暂定为双击鼠标右键,隐藏桌面图标。

查询得知,需要关键的技术为HOOK。于是开始动工。


首先,要解决的是如何执行隐藏操作。

鉴于之前做过一个类似的C#程序,我先尝试了模拟按键:找到桌面的句柄后,依次按下,鼠标右键(或菜单键)、查看(快捷键V)、显示桌面图标(快捷键D)。经过百般尝试,最终得出结论,我对桌面发送右键可以执行,紧接着的模拟键盘都不成功,按键应该对应菜单项的句柄才能发送。我暂时放弃了这个方法。

然后经过SPY++捕捉系统消息,查阅msdn得出了一个消息ShowWindow(hwnd,SW_HIDE); 这个消息可以隐藏桌面,测试通过。


然后,解决响应鼠标双击。

写了一个简单的HOOK程序,使用MH_MOUSE_LL全局鼠标钩子,无需DLL注入。测试单击左键右键,配合ShowWindow这个消息,已经可以显示隐藏桌面图标了。但是对于双击鼠标,程序始终没有响应。查阅资料得知,MH_MOUSE_LL方法虽然省事,但是他能捕获到的鼠标消息只有,单击,移动,并没有双击这个消息。

我还走了一段弯路,以为console程序就不支持鼠标双击事件,还写了一个MFC窗口,才发现,支持的双击仅限于在窗口本身操作,并是不我想要的HOOK全局双击。

既然没有双击,解决方案就两种,一是自己写个计时器,来监控两次单击的时间间隔;另一种是改用MH_GETMESSAGE DLL注入全局拦截双击事件。这里我选用第一种,最终完成,代码如下。


#include "stdafx.h"
#include <windows.h>

DWORD  lastTime; 
BOOL lastIsRight=FALSE; 
BOOL isHiden=FALSE; //定义为全局变量,每次点击保证重新载入值
LRESULT CALLBACK LowLevelMouseProc(
								   int nCode,
								   WPARAM wParam,
								   LPARAM lParam
								   )
{

typedef void (WINAPI *PSWITCHTOTHISWINDOW) (HWND,BOOL);
PSWITCHTOTHISWINDOW SwitchToThisWindow;
HMODULE hUser32=GetModuleHandle(_T("user32"));
//载入窗口前置函数
SwitchToThisWindow=(PSWITCHTOTHISWINDOW)GetProcAddress(hUser32,"SwitchToThisWindow");
HWND hwnd =FindWindow(_T("Progman"),NULL); 
hwnd = FindWindowEx(hwnd, NULL, _T("SHELLDLL_DefView"), NULL);
hwnd = FindWindowEx(hwnd, NULL, _T("SysListView32"), NULL);
//桌面句柄查找
if(hwnd!=NULL){	


	if (nCode>=0)
    {   
		
        if(wParam==WM_RBUTTONUP)
        {
			
            if(!lastIsRight)
            {
                lastTime=::GetTickCount();
                lastIsRight=TRUE;
            }
            else
            {
                DWORD  nowTime=::GetTickCount();
                if(nowTime-lastTime<350)//时间间隔为350ms
                {
					if(!isHiden) {ShowWindow(hwnd,SW_HIDE);isHiden=TRUE;}
					else {ShowWindow(hwnd,SW_SHOW);isHiden=FALSE;}
					lastIsRight=FALSE;
                }
                else
                    lastTime=nowTime;
            }
			
        }
    }
}
	return CallNextHookEx(0,nCode,wParam,lParam);
}


int _tmain(int argc, _TCHAR* argv[])
{
	MSG msg;
	SetWindowsHookExW(WH_MOUSE_LL,LowLevelMouseProc,GetModuleHandleW(0),0);
	while(GetMessageW(&msg,0,0,0))DispatchMessageW(&msg);
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值