WinAPI - Determine if a window has maximize/restore capability

Problem: Determining if a window (by, say, hWnd) has the capability of being maximized or restored. Purpose of this is to programmatically send maximize/restore events to windows (for automation) but exclude windows which can't handle it.

Please consider the following two example windows while trying to determine this from GetWindowLong with GWL_STYLE:


a) The Discord client app (it is built with Electron). It has styles:

  • WS_CAPTION
  • WS_SIZEBOX

It does NOT have styles:

  • WS_SYSMENU
  • WS_MAXIMIZEBOX

This window does display a restore/maximize button and behaves properly when SW_MAXIMIZE/SW_RESTORE are posted to it.


b) The "Are you sure you want to quit?" prompt in InteliJ IDEA. It has styles:

  • WS_CAPTION
  • WS_SIZEBOX
  • WS_SYSMENU

It does NOT have style:

  • WS_MAXIMIZEBOX

This window does NOT display a restore/maximize button and does NOT behave properly when SW_MAXIMIZE/SW_RESTORE are posted to it (it crashes the whole IDE).


So, given these two examples, the following facts are true:

1) A window with WS_SIZEBOX style may not respond to SW_MAXIMIZE/SW_RESTORE messages properly (wasn't designed to);

2) A window without WS_SYSMENU nor WS_MAXIMIZEBOX may still respond to SW_MAXIMIZE/SW_RESTORE messages properly (draws system menu and/or buttons itself in a non-standard way)

3) Both of them have a native system menu that opens via title bar secondary-click and they correctly list maximize/restore as enabled or disabled (whatever matches their capability).

Given those two facts, how do I actually determine if a window can or cannot handle being maximized/restored? It seems it is not possible from window style alone, but I can't find anything in the Win32 API WinAPI to do this.

Note that I am deciding on whether to send SW_MAXIMIZE/SW_RESTORE by calling GetWindowPlacement and checking the showCmd.

Also note that I am using Java/JNA but I understand C++ or C# perfectly fine if you want to share code snippets.

1 answer

  • answered 2018-01-14 08:41 Barmak Shemirani

    You can use GetWindowLongPtr to get window style, example:

    LONG style = GetWindowLongPtr(hwnd, GWL_STYLE);
    if(style & WS_MAXIMIZEBOX)
        printf("WS_MAXIMIZEBOX\n");
    

    But that's not necessarily useful. A window with max button could be in non-max position, you don't want to change its state. Instead you can show the window based on creation flag instead. Example:

    #include <Windows.h> 
    
    void show(HWND hwnd)
    {
        WINDOWPLACEMENT place;
        memset(&place, 0, sizeof(WINDOWPLACEMENT));
        place.length = sizeof(WINDOWPLACEMENT);
        GetWindowPlacement(hwnd, &place);
    
        switch(place.showCmd)
        {
        case SW_SHOWMAXIMIZED:
            ShowWindow(hwnd, SW_SHOWMAXIMIZED);
            break;
        case SW_SHOWMINIMIZED:
            ShowWindow(hwnd, SW_RESTORE);
            break;
        default:
            ShowWindow(hwnd, SW_NORMAL);
            break;
        }
    
        SetForegroundWindow(hwnd);
    }
    
    int main()
    {
        HWND hwnd = FindWindowW(L"Notepad", 0);
        if (hwnd)
            show(hwnd);
        return 0;
    }