Я пытаюсь подклассы в настоящее время сфокусированное окно в системе 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;
}
Мое подозрение, что главное окно Opera как-то уже подклассифицировано. Я полагаю, происходит следующее:
- окно создается с его собственной основной WndProc, и фокус имеет
- Мое приложение подклассы окно, сохраняя оригинальный WndProc
- Opera подклассом свое собственное окно
- Когда окно теряет фокус, я восстанавливаю исходный WndProc, игнорируя второй WndProc
Возможно ли это так? Есть ли другие объяснения?
Не сомневайся, Раймонд Чен. :) Я не знал об этих помощниках, поэтому вы просто спасли мне кучу кодирования, пытаясь исправить это сам. :) –