Which problem prevents ShowWindow from working?

1.3k Views Asked by At

I try to create a window, which is hidden when it is minimized. The Window should be hidden, when it's minimized. Where is my problem? What prevents ShowWindow from working?

#define _WIN32_WINNT 0x0600

#include <Windows.h>
#include <CommCtrl.h>
#pragma comment(lib,"ComCtl32.lib")
#include <tchar.h>
#include <stdlib.h>
#include <string>
#include "resource.h"
#pragma comment(linker, \
  "\"/manifestdependency:type='Win32' "\
  "name='Microsoft.Windows.Common-Controls' "\
  "version='6.0.0.0' "\
  "processorArchitecture='*' "\
  "publicKeyToken='6595b64144ccf1df' "\
  "language='*'\"")

//Fenster des Dialogs
HWND hDialog;

INT_PTR CALLBACK Func(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) {
    switch(uMsg) {
        case WM_SYSCOMMAND:
            if(wParam==SC_MINIMIZE) {
                ShowWindow(hDialog,SW_HIDE);
            }
            break;
        case WM_CLOSE:
            DestroyWindow(hwndDlg);
            return TRUE;
        case WM_DESTROY:
            DeregisterShellHookWindow(hDialog);
            PostQuitMessage(0);
            return TRUE;
    }
    return FALSE;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {
    InitCommonControls();
    hDialog=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,Func);
    SendMessage(hDialog,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(NULL,(LPCWSTR)IDI_APPLICATION));
    RegisterShellHookWindow(hDialog);
    ShowWindow(hDialog,SW_SHOWNORMAL);
    MSG msg={0};
    BOOL ret=0;
    while((ret = GetMessage(&msg, 0, 0, 0)) != 0) {
        if(ret==-1) {
            break;
        }
        if(!IsDialogMessage(hDialog,&msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return 0;
}
3

There are 3 best solutions below

1
On

Using ShowWindow and returning TRUE in Func if wParam equals SC_MINIMIZE or SC_RESTORE (with SW_HIDE or SW_RESTORE as nCmdShow) works.

2
On

Do you mean: ShowWindow(hDialog,SW_SHOWNORMAL) ? Then you would need to change SW_SHOWNORMAL to some other value like SW_MINIMIZE.

EDIT: (found it!)--Also i cant see where you initialized the HWND hDialog variable!?

The method youre using to register the window is not to be used to create/register windows or something like that. See: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registershellhookwindow

[This function is not intended for general use. It may be altered or unavailable in subsequent versions of Windows.]

To create a window you should first create a windows system class to register your message handling and the window procedure.

HINSTANCE hinstance = GetModuleHandle(NULL); // NULL will give you the main
                                             // applications module handle.

WNDCLASSEX wc;

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = wndProc; // window procedure
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "YourSystemClassNameHere(not the window title)";
wc.cbSize = sizeof(WNDCLASSEX);

RegisterClassEx(&wc);

Then you can create HWNDs.

HWND hwnd = CreateWindowEx(
        WS_EX_APPWINDOW | WS_EX_PALETTEWINDOW,
        "YourSystemClassNameHere(not the window title)",
        title,
        WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP | WS_CAPTION,
        positionX, positionX, width, height, NULL, NULL, hinstance, NULL);
3
On

Your dialog procedure is returning FALSE after responding to WM_SYSCOMMAND. Change it so that it returns TRUE, this way it won't run the default action, it won't minimize the window.

wParam in this case should be bitwised AND against 0xFFF0

if((wParam & 0xFFF0) == SC_MINIMIZE) {
    ShowWindow(hwnd, SW_HIDE);
    return TRUE; //<- add this
}
break; //<- return false...

See documentation:

DLGPROC callback function
Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not. If the dialog box procedure returns FALSE, the dialog manager performs the default dialog operation in response to the message.

WM_SYSCOMMAND
In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.

Note that DialogBox is better for this example (it won't need a message loop). If you must use CreateDialog, then change the message loop as follows:

INT_PTR CALLBACK Func(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM) 
{
    switch(uMsg)
    {
    case WM_SYSCOMMAND:
        if((wParam & 0xFFF0) == SC_MINIMIZE)
        {
            ShowWindow(hwnd, SW_HIDE);
            return TRUE;
        }
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        return TRUE;
    }
    return FALSE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) 
{
    HWND hDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Func);
    ...
    while(GetMessage(&msg, NULL, 0, 0) && IsWindow(hDialog))
    {
        if(!IsDialogMessage(hDialog, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return 0;
}