我想在Windows系統上使用全局CBT鉤子繼承當前聚焦的窗口。這與this question中發生的事情有關,但是錯誤是不同的。安全刪除窗口子類?
當此子類生效時會發生什麼情況,Opera的(版本10.50)主窗口無法顯示。 Opera有一個「啓動畫面」,您需要點擊主窗口的「開始」才能顯示Opera沒有正確關閉後出現的畫面。只要這個窗口彈出,Opera的主窗口就不會顯示。如果Opera被正確關閉,並且此啓動畫面不顯示,則主窗口將顯示它應該顯示的內容。
HHOOK hHook;
HWND hWndSubclass = 0;
void SubclassWindow(HWND hWnd)
{
Unsubclass();
FARPROC lpfnOldWndProc = (FARPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)SubClassFunc);
SetProp(hWnd, L"PROP_OLDWNDPROC", lpfnOldWndProc);
hWndSubclass = hWnd;
}
void Unsubclass()
{
if (hWndSubclass != 0 && IsWindow(hWndSubclass))
{
FARPROC lpfnOldWndProc = (FARPROC)GetProp(hWndSubclass, L"PROP_OLDWNDPROC");
RemoveProp(hWndSubclass, L"PROP_OLDWNDPROC");
SetWindowLongPtr(hWndSubclass, GWLP_WNDPROC, (LPARAM)lpfnOldWndProc);
hWndSubclass = 0;
}
}
static LRESULT CALLBACK SubClassFunc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_MOVING)
{
// do something irrelevant
}
else if (message == WM_DESTROY)
{
Unsubclass();
}
FARPROC lpfnOldWndProc = (FARPROC)GetProp(hWndSubclass, L"PROP_OLDWNDPROC");
return CallWindowProc((WNDPROC)lpfnOldWndProc, hWndSubclass, message, wParam, lParam);
}
static LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_SETFOCUS && hWndServer != NULL)
{
SubclassWindow((HWND)wParam);
}
if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
return 0;
}
BOOL APIENTRY DllMain(HINSTANCE hInstance,
DWORD Reason,
LPVOID Reserved
)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
hInst = hInstance;
return TRUE;
case DLL_PROCESS_DETACH:
Unsubclass();
return TRUE;
}
return TRUE;
}
我懷疑是歌劇院的主窗口在某種程度上繼承。我想象着正在發生的事情如下:
- 與它自己的基本的WndProc創建的窗口,並給予重點
- 我的應用程序子類的窗口,存儲原始的WndProc
- 戲子類自己的窗口
- 當窗口失去焦點時,我恢復原來的WndProc,從而忽略了第二個WndProc
這是真的嗎?還有其他解釋嗎?
永遠不會懷疑雷蒙德。 :)我不知道這些助手,所以你只是救了我一堆編碼,試圖自己修復。 :) – 2010-03-15 10:39:25