2525#include " Settings\Settings.h"
2626#include " Logging\Logging.h"
2727
28+ #undef DefWindowProc
29+
2830namespace WndProc
2931{
3032 struct WNDPROCSTRUCT ;
@@ -33,7 +35,9 @@ namespace WndProc
3335 WNDPROC GetWndProc (HWND hWnd);
3436 LONG SetWndProc (HWND hWnd, WNDPROC ProcAddress);
3537 LRESULT CallWndProc (WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
38+ LRESULT DefWndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
3639 bool IsExecutableAddress (void * address);
40+ inline bool CheckFocusLoss (WINDOWPOS* wp);
3741
3842 bool SwitchingResolution = false ;
3943
@@ -174,6 +178,13 @@ LRESULT WndProc::CallWndProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM
174178 DefWindowProcA (hWnd, Msg, wParam, lParam)));
175179}
176180
181+ LRESULT WndProc::DefWndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
182+ {
183+ return (IsWindowUnicode (hWnd) ?
184+ DefWindowProcW (hWnd, Msg, wParam, lParam) :
185+ DefWindowProcA (hWnd, Msg, wParam, lParam));
186+ }
187+
177188bool WndProc::ShouldHook (HWND hWnd)
178189{
179190 if (!IsWindow (hWnd))
@@ -325,6 +336,22 @@ void WndProc::SetKeyboardLayoutFocus(HWND hWnd, bool IsActivating)
325336 }
326337}
327338
339+ bool WndProc::CheckFocusLoss (WINDOWPOS* wp)
340+ {
341+ if (!wp)
342+ {
343+ return false ;
344+ }
345+
346+ // Window is being hidden
347+ if (wp->flags & SWP_HIDEWINDOW)
348+ {
349+ return true ;
350+ }
351+
352+ return false ;
353+ }
354+
328355LRESULT CALLBACK WndProc::Handler (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROCSTRUCT* AppWndProcInstance)
329356{
330357 if (Msg != WM_PAINT)
@@ -393,6 +420,11 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
393420 }
394421 IsActive = wParam;
395422 }
423+ // Filter messages for loss of focus or minimize
424+ if (Config.HideWindowFocusChanges && wParam == FALSE )
425+ {
426+ return DefWndProc (hWnd, Msg, wParam, lParam);
427+ }
396428 break ;
397429
398430 case WM_ACTIVATE:
@@ -407,10 +439,15 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
407439 if (pDataStruct->IsActive == LOWORD (wParam))
408440 {
409441 LOG_LIMIT (3 , __FUNCTION__ << " Warning: filtering duplicate WM_ACTIVATE: " << LOWORD (wParam));
410- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
442+ return DefWndProc ( hWnd, Msg, wParam, lParam);
411443 }
412444 pDataStruct->IsActive = LOWORD (wParam);
413445 }
446+ // Filter messages for loss of focus or minimize
447+ if (Config.HideWindowFocusChanges && LOWORD (wParam) == WA_INACTIVE)
448+ {
449+ return DefWndProc (hWnd, Msg, wParam, lParam);
450+ }
414451
415452 // Special handling for iconic state to prevent issues with some games
416453 if (pDataStruct->IsDirectDraw && IsIconic (hWnd))
@@ -420,7 +457,7 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
420457 {
421458 LOG_LIMIT (3 , __FUNCTION__ << " Activating window because WM_ACTIVATE (" << LOWORD (wParam) << " ) message detected when window is iconic: " << hWnd);
422459 CallWndProc (pWndProc, hWnd, Msg, WA_ACTIVE, NULL );
423- CallWndProc ( nullptr , hWnd, WM_SYSCOMMAND, SC_RESTORE, NULL );
460+ DefWndProc ( hWnd, WM_SYSCOMMAND, SC_RESTORE, NULL );
424461 SetWindowPos (hWnd, HWND_TOP, 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
425462 SetForegroundWindow (hWnd);
426463 return NULL ;
@@ -429,18 +466,23 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
429466 if (pDataStruct->DirectXVersion <= 4 )
430467 {
431468 LOG_LIMIT (3 , __FUNCTION__ << " Warning: filtering WM_ACTIVATE when iconic: " << LOWORD (wParam));
432- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
469+ return DefWndProc ( hWnd, Msg, wParam, lParam);
433470 }
434471 }
435472 break ;
436473
437474 case WM_NCACTIVATE:
475+ // Filter messages for loss of focus or minimize
476+ if (Config.HideWindowFocusChanges && wParam == FALSE )
477+ {
478+ return DefWndProc (hWnd, Msg, wParam, lParam);
479+ }
438480 // Filter some messages while forcing windowed mode
439481 if (pDataStruct->IsDirectDraw && IsForcingWindowedMode)
440482 {
441483 LOG_LIMIT (3 , __FUNCTION__ << " Warning: filtering WM_NCACTIVATE when forcing windowed mode. " <<
442484 hWnd << " " << Logging::hex (Msg) << " " << wParam << " " << lParam << " IsIconic: " << IsIconic (hWnd));
443- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
485+ return DefWndProc ( hWnd, Msg, wParam, lParam);
444486 }
445487 break ;
446488
@@ -458,6 +500,19 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
458500 {
459501 SetKeyboardLayoutFocus (hWnd, false );
460502 }
503+ // Filter messages for loss of focus or minimize
504+ if (Config.HideWindowFocusChanges && wParam == FALSE )
505+ {
506+ return DefWndProc (hWnd, Msg, wParam, lParam);
507+ }
508+ break ;
509+
510+ case WM_SHOWWINDOW:
511+ // Filter messages for loss of focus or minimize
512+ if (Config.HideWindowFocusChanges && wParam == FALSE )
513+ {
514+ return DefWndProc (hWnd, Msg, wParam, lParam);
515+ }
461516 break ;
462517
463518 case WM_STYLECHANGING:
@@ -467,16 +522,28 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
467522 case WM_SIZING:
468523 case WM_SIZE:
469524 case WM_WINDOWPOSCHANGING:
525+ // Filter messages for loss of focus or minimize
526+ if (Config.HideWindowFocusChanges &&
527+ ((Msg == WM_SIZE && wParam == SIZE_MINIMIZED) ||
528+ (Msg == WM_WINDOWPOSCHANGING && CheckFocusLoss (reinterpret_cast <WINDOWPOS*>(lParam)))))
529+ {
530+ return DefWndProc (hWnd, Msg, wParam, lParam);
531+ }
470532 // Filter some messages while forcing windowed mode
471533 if (pDataStruct->IsCreatingDevice && IsForcingWindowedMode)
472534 {
473535 LOG_LIMIT (3 , __FUNCTION__ << " Warning: filtering some messages when forcing windowed mode. " <<
474536 hWnd << " " << Logging::hex (Msg) << " " << wParam << " " << lParam << " IsIconic: " << IsIconic (hWnd));
475- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
537+ return DefWndProc ( hWnd, Msg, wParam, lParam);
476538 }
477539 break ;
478540
479541 case WM_WINDOWPOSCHANGED:
542+ // Filter messages for loss of focus or minimize
543+ if (Config.HideWindowFocusChanges && CheckFocusLoss (reinterpret_cast <WINDOWPOS*>(lParam)))
544+ {
545+ return DefWndProc (hWnd, Msg, wParam, lParam);
546+ }
480547 // Handle exclusive mode cases where the window is resized to be different than the display size
481548 if (pDataStruct->IsDirectDraw && pDataStruct->IsExclusiveMode )
482549 {
@@ -488,21 +555,21 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
488555 {
489556 LOG_LIMIT (3 , __FUNCTION__ << " Warning: filtering WM_WINDOWPOSCHANGED when forcing windowed mode. " <<
490557 hWnd << " " << Logging::hex (Msg) << " " << wParam << " " << lParam << " IsIconic: " << IsIconic (hWnd));
491- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
558+ return DefWndProc ( hWnd, Msg, wParam, lParam);
492559 }
493560 break ;
494561
495562 case WM_PAINT:
496563 // Some games hang when attempting to paint while iconic
497564 if (pDataStruct->IsDirectDraw && IsIconic (hWnd))
498565 {
499- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
566+ return DefWndProc ( hWnd, Msg, wParam, lParam);
500567 }
501568 break ;
502569
503570 case WM_SYNCPAINT:
504571 // Send WM_SYNCPAINT to DefWindowProc
505- return CallWndProc ( nullptr , hWnd, Msg, wParam, lParam);
572+ return DefWndProc ( hWnd, Msg, wParam, lParam);
506573
507574 case WM_DISPLAYCHANGE:
508575 // Handle cases where monitor gets disconnected during resolution change
@@ -518,6 +585,11 @@ LRESULT CALLBACK WndProc::Handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
518585 {
519586 AppWndProcInstance->SetInactive ();
520587 }
588+ // Filter messages for loss of focus or minimize
589+ if (Config.HideWindowFocusChanges && (wParam & 0xFFF0 ) == SC_MINIMIZE)
590+ {
591+ return DefWndProc (hWnd, Msg, wParam, lParam);
592+ }
521593 break ;
522594
523595 case WM_CLOSE:
0 commit comments