Я пытаюсь создать подкласс текущего окна в системе Windows, используя глобальный хук CBT. Это связано с тем, что происходит в этом вопросе , но ошибка другая.
Что происходит, когда действует это подклассирование, так это то, что главное окно 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
Может ли это быть действительно так? Есть ли другие объяснения?