哪个问题阻止ShowWindow工作?

时间:2019-08-21 07:24:41

标签: c++ winapi showwindow

我尝试创建一个窗口,将其最小化时将其隐藏。最小化窗口时,应将其隐藏。我的问题在哪里?是什么导致ShowWindow无法正常工作?

#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 个答案:

答案 0 :(得分:1)

您的对话过程在响应FALSE之后返回WM_SYSCOMMAND。对其进行更改,使其返回TRUE,这样就不会运行默认操作,也不会最小化窗口。

wParam在这种情况下应按位与AND与0xFFF0

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

请参阅文档:

  

DLGPROC callback function
  通常,如果对话框过程已处理,则应返回TRUE。   消息,如果没有则为FALSE。如果对话框中的步骤   返回FALSE,对话框管理器执行默认对话框   操作以响应该消息。

     

WM_SYSCOMMAND
  在WM_SYSCOMMAND消息中,wParam的四个低阶位   参数由系统内部使用。获得正确的   测试wParam的值的结果时,应用程序必须结合   通过使用按位与,将值0xFFF0与wParam值   运算符。

请注意,DialogBox在此示例中更好(它不需要消息循环)。如果必须使用CreateDialog,请按如下所示更改消息循环:

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

答案 1 :(得分:0)

如果wParam等于SC_MINIMIZE或SC_RESTORE(SW_HIDE或SW_RESTORE为nCmdShow),则使用ShowWindow并在Func中返回TRUE。

答案 2 :(得分:-1)

您的意思是:ShowWindow(hDialog,SW_SHOWNORMAL)吗?然后,您需要将SW_SHOWNORMAL更改为其他值,例如SW_MINIMIZE。

编辑:(找到它!)-我也看不到初始化HWND hDialog变量的地方!?

您用于注册窗口的方法不可用于创建/注册窗口或类似的方法。 看到: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registershellhookwindow

[此功能不适用于一般用途。它可能会在Windows的后续版本中更改或不可用。]

要创建窗口,您首先应该创建一个Windows系统类来注册消息处理和窗口过程。

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

然后您可以创建HWND。

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