0CCh Blog

用Windows Event监控前台窗口变化

网络上有这样一种小工具,号称可以提高计算机响应速度。简单看了下其中的一款工具,实现原理很简单,就是监控前台窗口的变化,设置进程线程的优先级。设置进程线程的优先级无非就是SetPriorityClass和SetThreadPriority这两个函数,主要问题就是要获得前台窗口的情况。
Windows提供了一种叫做Windows Event Hook的机制,来让我们获得多种不同的事件,其中一种就是前台窗口变化事件。所以要完成这个功能很简单,只需要注册一个针对EVENT_SYSTEM_FOREGROUND的HOOK就行了。注册和反注册Hook的函数分别是SetWinEventHook和UnhookWinEvent。
比如注册EVENT_SYSTEM_FOREGROUND事件的Hook,我们只需要这样:

HWINEVENTHOOK hWinEventHook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND,
NULL, WinEventProc, 0, 0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);

前两个参数设置我们感兴趣的事件范围,由于我们最后一个参数设置的WINEVENT_OUTOFCONTEXT,表示Hook函数并不在产生Event的进程内部,所以hmodWinEventProc设置为NULL。WinEventProc则是我们的Hook函数idProcess和idThread为0,表示我们关心所有桌面上的进程线程,最后的flags还有一个WINEVENT_SKIPOWNPROCESS表示我们对自己的进程不感兴趣。
要反注册Hook只需要

UnhookWinEvent(hWinEventHook);

WinEventProc的很简单

void CALLBACK WinEventProc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime
)
{
if (hwnd &&
idObject == OBJID_WINDOW &&
idChild == CHILDID_SELF &&
event == EVENT_SYSTEM_FOREGROUND) {
...
}
}

其中只需要知道hwnd就是当前的前台窗口就行了。然后通过hwnd和函数GetWindowThreadProcessId,获得进程线程id,自然就能获得其句柄,最后调用调整进程线程优先级的函数即可。