雙擊鼠標HOOK學習

前一陣子換了一個好看的桌面,但是圖標太多擋住了很不高興,在桌面點右鍵,隱藏桌面圖片很麻煩,於是想做一個小軟件一鍵隱藏、顯示桌面圖標,好讓我欣賞壁紙。

鑑於這陣子學習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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章