1.窗口子类化
子类化作用于特定的窗口实例,允许修改单个窗口的行为。它通过替换窗口过程地址来实现对消息的处理。
SetWindowSubclass / SetWindowLongPtr
HWND Hwnd = GetDlgItem(m_hWnd, IDC_LISTVIEW);
//设置新的窗口过程
SetWindowSubclass(Hwnd, &SubclassProc, MY_SUCLASS_ID, 0);
LRESULT CALLBACK SubclassProc(HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
//对期待的消息进行处理
……
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
注意:子类化只能用于进程内的窗口,不能跨进程修改窗口行为。
2.窗口超类化
超类化作用于整个窗口类,影响所有使用该类的窗口。它通过创建新的窗口类并注册来实现对消息的处理。
WNDCLASS wc = { 0 };
if (GetClassInfo(hinstance, szClassName, &wc) != FALSE)
{
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)PaneWndProc; //指定新的窗口过程
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = CNWSModule::Get().GetModuleInstance();
wc.hIcon = NULL;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = newName;
//注册新的窗口
if (!RegisterClass(&wc))
return HRESULT_FROM_WIN32(GetLastError());
}
LRESULT CALLBACK PaneWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
//处理需要处理的消息
……
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
注意:超类化只能用于自定义的窗口类,不能用于系统预定义的窗口类,如按钮、编辑框等。
3.安装钩子
可以设置不同类型的钩子,如键盘钩子、鼠标钩子等,以截获相应的消息。
SetWindowsHookEx
//安装键盘钩子
HHOOK myHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyHookProc, hinstance, NULL);
LRESULT CALLBACK MyHookProc(int code, WPARAM wParam, LPARAM lParam)
{
//处理键盘消息
……
return CallNextHookEx(myHook, code, wParam, lParam);
}
注意:钩子的使用受到系统资源的限制,因为每个线程都有一个与之关联的钩子链表。过多安装钩子可能会导致系统性能下降。