How to get the HWND of the next window that will be active when you minimize the foreground window?

Leonardo 91 Reputation points
2022-08-13T03:18:02.547+00:00

Scenario: there's windows X in the foreground, when you minimize it, it will bring windows Y to the front or the desktop.

What WINAPI i could use to get the HWND of Y before minimizing X?

I tried this:

   HWND hWndnext = GetWindow(hWnd, GW_HWNDNEXT);  

but it didn't return the HWND i was looking for.

I'm trying to set my window transparent upon trying to minimize but not letting it be minimized, and after it gets transparent, activate/focus whatever would be the next window case it really was minimized, then upon clicking on it again at the taskbar restore the transparency to default.

My second attempt was:

case WM_SYSCOMMAND:  
{  
 if (wParam == SC_MINIMIZE) {  
  
 DefWindowProc(hWnd, msg, wParam, lParam);  
  
 BYTE alpha = GetWindowAlpha(hWnd) ? 0 : 255;  
  
 // Update the window transparency.  
 DWORD exstyle = GetWindowLongW(hWnd, GWL_EXSTYLE);  
 SetWindowLongW(hWnd, GWL_EXSTYLE, exstyle | WS_EX_LAYERED);  
 SetLayeredWindowAttributes(hWnd, 0, alpha, LWA_ALPHA);  
  
 // Attempt to restore the window without activating it.  
 ShowWindow(hWnd, SW_SHOWNOACTIVATE);  
 return 0;  
  
 }  
 break;  
}  

But it still ain't focusing the next window into the taskbar. What else i could try?

Would like to mention that i did a similar help question on Stack.
Thank you.

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,423 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,532 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Viorel 112.4K Reputation points
    2022-08-13T03:31:27.477+00:00

    This experiment seems to work:

    case WM_SYSCOMMAND:  
        switch( wParam & 0xFFF0 )  
        {  
        case SC_MINIMIZE:  
        {  
            ShowWindow( hWnd, SW_HIDE );  
            DWORD exstyle = GetWindowLong( hWnd, GWL_EXSTYLE );  
            SetWindowLong( hWnd, GWL_EXSTYLE, exstyle | WS_EX_LAYERED );  
            SetLayeredWindowAttributes( hWnd, 0, 128, LWA_ALPHA );  
            ShowWindow( hWnd, SW_SHOWNOACTIVATE );                                                                
      
            return 0;  
        }  
        default:  
            return DefWindowProc( hWnd, message, wParam, lParam );  
        }  
        break;  
    
    0 comments No comments

  2. RLWA32 40,471 Reputation points
    2022-08-13T09:24:22.817+00:00

    Try using this as a start to find the next window that would be activated. It flashes the taskbar button to give a visual clue.

    void FlashNext(HWND hwnd)  
    {  
        HWND hNext{};  
        HWND hFound{};  
      
        hNext = GetWindow(hwnd, GW_HWNDNEXT);  
      
        while (!hFound)  
        {  
            if (IsWindowVisible(hNext) && !(GetWindowLong(hNext, GWL_EXSTYLE) & (WS_EX_TOOLWINDOW | WS_EX_TOPMOST)))  
            {  
                hFound = hNext;  
                break;  
            }  
      
            hNext = GetWindow(hNext, GW_HWNDNEXT);  
        }     
      
        FLASHWINFO fw{ sizeof fw, hFound, FLASHW_TRAY, 1, 0 };  
        FlashWindowEx(&fw);  
        fw.dwFlags = FLASHW_STOP;  
        fw.uCount = 0;  
        FlashWindowEx(&fw);  
    }  
      
    

  3. RLWA32 40,471 Reputation points
    2022-08-13T16:52:12.923+00:00

    FlashNext function updated for minimized windows and cloaked windows (Win8 or greater).

    // DWMA_CLOAKED supported on > Win 7  
    bool IsCloaked(HWND hwnd)  
    {  
        DWORD dwCloaked{};  
        if(IsWindows8OrGreater())  
            DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &dwCloaked, sizeof dwCloaked);  
        return (dwCloaked != 0);  
    }  
      
    void FlashNext(HWND hwnd)  
    {  
        HWND hNext{};  
        HWND hFound{};  
      
        hNext = GetWindow(hwnd, GW_HWNDNEXT);  
      
        while (!hFound && hNext)  
        {  
            if (IsWindowVisible(hNext) && !IsIconic(hNext) && !IsCloaked(hNext) && !(GetWindowLong(hNext, GWL_EXSTYLE) & (WS_EX_TOOLWINDOW | WS_EX_TOPMOST)))  
            {  
                hFound = hNext;  
                break;  
            }  
      
            hNext = GetWindow(hNext, GW_HWNDNEXT);  
        }  
      
        if (hFound)  
        {  
            FLASHWINFO fw{ sizeof fw, hFound, FLASHW_TRAY, 1, 0 };  
            FlashWindowEx(&fw);  
            fw.dwFlags = FLASHW_STOP;  
            fw.uCount = 0;  
            FlashWindowEx(&fw);  
        }  
    }  
      
    

  4. RLWA32 40,471 Reputation points
    2022-08-14T15:07:56.877+00:00

    I took a different approach to dealing with topmost windows in a sample Win32 Desktop application The sample has a menu selection to make itself topmost or non-topmost so you can experiment with those settings. It still flashes a taskbar button but now writes the window handle it finds and the related process path into a listbox.

    The code is based on my observation of Windows behavior and is therefore dependent on implementation details that Microsoft is free to change at any time.

    You can get the sample here - https://1drv.ms/u/s!AmnqrCFBv4nDgkH7nKaWrBQ5o16-?e=ZHitSA

    0 comments No comments