Is it safe to remove subclasses of windows?

I am trying to subclass the current focused window on a Windows system using the CBT global hook. This is due to what is happening in this question , but the error is different.

What happens when this subclass acts is that the main Opera window (version 10.50) is not displayed. Opera has a “splash screen” where you need to click “Start” for the main window to show what appears after Opera has not shutdown properly. Whenever this window appears, the main Opera window is not displayed. If Opera was turned off properly and this splash screen is not displayed, the main window is displayed as it should.

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; } 

My suspicion is that the main Opera window is somehow already subclassed. I assume the following happens:

  • A window is created with its own base WndProc and receives focus.
  • My application subclasses the window, keeping the original WndProc
  • Opera subclasses its own window
  • When the window loses focus, I restore the original WndProc, ignoring the second WndProc

Is it really so? Are there any other explanations?

+4
source share
1 answer

This can happen as Raymond Chen writes :

Think about what happens if someone else subclasses this window during the "... do stuff ..." section. When we close the window, we would remove two subclasses, the one we installed and the one that was installed after us. If a memory was allocated in another subclass (which is very common), then this memory leaked, in addition to the subclass that did not complete everything that he was trying to do.

He continues the decision:

This is a rather cumbersome process, so the shell team wrote some helper functions to do all this for you. The SetWindowSubclass function does all the hard work of setting up the subclass procedure, remembering the previous one and passing the reference data to the subclass procedure that you provide, you use the DefSubclassProc function to forward the message to the previous subclass procedure, and when you are done, you use the RemoveWindowSubclass function to delete yourself out of the chain. RemoveWindowSubclass does all the work to do the right thing if you are not a window program at the top of the chain.

+8
source

Source: https://habr.com/ru/post/1304128/


All Articles