应用SetWinEventHook截获Windows事件
用SetWindowsHookEx可以截获Windows中的消息,然而对于更高级一点的Windows事件(如:弹出菜单事件、ATL+TAB切换事件等等),可以用SetWinEventHook来截获.
SetWinEventHook创建的钩子也分为进程内和进程外两种,进程内钩子效率高但必须以DLL形式存在,因为其须映射到别的进程中.在这个Demo中我采用进程外钩子来截获所有事件。
钩子例程如下所示:
VOID CALLBACK WinEventsProc( HWINEVENTHOOK hWinEventHook, DWORD dwEvent, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime )
{
switch( dwEvent )
{
case EVENT_SYSTEM_SWITCHSTART:
AtlMessageBox( NULL, _T("Alt+Tab开始") );
break;
case EVENT_SYSTEM_SWITCHEND:
AtlMessageBox( NULL, _T("Alt+Tab结束") );
break;
case EVENT_SYSTEM_MENUPOPUPSTART:
AtlMessageBox( NULL, _T("弹出菜单开始") );
break;
case EVENT_SYSTEM_MENUPOPUPEND:
AtlMessageBox( NULL, _T("弹出菜单开始") );
break;
}
}
安装进程外HOOK(截获所有进程的所有事件):
HWINEVENTHOOK hHook = ::SetWinEventHook( EVENT_MIN , EVENT_MAX , NULL, WinEventsProc, 0, 0, WINEVENT_OUTOFCONTEXT );
使用完一定要记得卸载HOOK:
::UnhookWinEvent( hHook );
AutoHotkey应用,自动关闭指定窗口
#NoEnv
#Warn
#SingleInstance, Force
Process, Priority,,High
SetWorkingDir, %A_ScriptDir%
#Persistent
Process, Priority,,High
Hook := 0
F2:: WinCloseAuto( Hook:=!Hook, ["ahk_class Notepad"]
, ["ahk_class CalcFrame"]
, ["Windows Task Manager ahk_class #32770"] )
WinCloseAuto(P*) { ; WinCloseAuto v0.50 by SKAN on D36I/D36I @ tiny.cc/wincloseauto
Static CBA:=RegisterCallBack("WinCloseAuto"), WEP:="", hHook:=0, EVENT_OBJECT_SHOW:=0x8002
If IsObject(P)
Return (P.1=1 && (WEP:=P)) ? hHook:=DllCall("SetWinEventHook","Int",EVENT_OBJECT_SHOW
,"Int",EVENT_OBJECT_SHOW, "Ptr",0, "Ptr",CBA, "Int",0, "Int",0, "Int",0, "Ptr")
: (P.1=0 && (WEP:="")="") ? DllCall("UnhookWinEvent", "Ptr",hHook) : ""
If WinExist((WEP.2)*) || WinExist((WEP.3)*) || WinExist((WEP.4)*) || WinExist((WEP.5)*)
PostMessage, 0x112, 0xF060 ; WM_SYSCOMMAND, SC_CLOSE
}
升级版,支持ini配置自动关闭窗口列表
#NoEnv
#Warn
#SingleInstance, Force
Process, Priority,,High
SetWorkingDir, %A_ScriptDir%
#Persistent
ObjWEP:=[], WinTitle:=""
Loop
{
IniRead,WinTitle,wantclose.ini, WinList,%A_Index%
If (WinTitle="ERROR")
Break
ObjWEP.Push(StrSplit(WinTitle,",", A_Space))
}
WinCloseAuto(True, ObjWEP*)
Return ; // end of auto-execute section
WinCloseAuto(P*) { ; WinCloseAuto v0.50 by SKAN on D36I/D36I @ tiny.cc/wincloseauto
Static CBA:=RegisterCallBack("WinCloseAuto"), WEP:="", hHook:=0, EVENT_OBJECT_SHOW:=0x8002
If IsObject(P)
Return (P.1=1 && (WEP:=P)) ? hHook:=DllCall("SetWinEventHook","Int",EVENT_OBJECT_SHOW
,"Int",EVENT_OBJECT_SHOW, "Ptr",0, "Ptr",CBA, "Int",0, "Int",0, "Int",0, "Ptr")
: (P.1=0 && (WEP:="")="") ? DllCall("UnhookWinEvent", "Ptr",hHook) : ""
If WinExist((WEP.2)*) || WinExist((WEP.3)*) || WinExist((WEP.4)*) || WinExist((WEP.5)*)
PostMessage, 0x112, 0xF060 ; WM_SYSCOMMAND, SC_CLOSE
}
配置文件名称为,wantclose.ini,内容示例如下:
[WinList]
1=ahk_class Notepad
2=ahk_class CalcFrame
3=Windows Task Manager ahk_class #32770