为什么 C++ ShowWindow() 在隐藏 window 并显示另一个时不能正常工作?

Why is C++ ShowWindow() not working properly when hiding a window and showing another?

我正在用 C++ 编写我的第一个 Win32 应用程序,我正在尝试创建 3 个 windows,根据用户单击的按钮在它们之间进行重定向。我将 windows (window1,window2,window3) 初始化为 children window hwnd 并且仅将 window1 设置为可见。 window1 也有两个按钮,每个按钮应该指向 window2window3.

我试图隐藏 window1 并使用 ShowWindow()[= 显示我想切换到哪个 window 32=] 函数。但是,它不起作用(单击按钮没有任何作用)。你能帮我理解为什么吗?

在我之前的另一段代码中,我没有创建 window1,按钮和另外两个 windows 只是 hwnd 的 children,按下按钮确实显示了正确的 window,但该按钮仍然存在,即使它不属于那个 window。

此外,有没有更有效的方式在windows之间切换(无需一次又一次地删除和创建它们?

谢谢!!!

编辑:我设法解决了我的问题。它源于我已将 windows 1,2 和 3 声明为静态的事实。通过在与 hwnd 相同的 class 下声明它们,我能够处理来自主 WindowProcedure() 下按钮的消息。因为我的程序会很简单,所以我不需要为新程序创建不同的程序 windows,但多亏了评论,现在我也知道该怎么做了!

    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_CREATE:
    
                window1 = CreateWindow("STATIC","Window 1",WS_VISIBLE|WS_BORDER|WS_CHILD,0,0,600,600,hwnd,NULL,NULL,NULL);
                window2 = CreateWindow("STATIC","Window 2",WS_BORDER|WS_CHILD,0,0,600,600,hwnd,NULL,NULL,NULL);
                button2 = CreateWindow(
                                       "BUTTON",
                                       "SECOND WINDOW",
                                       WS_CHILD | WS_VISIBLE | WS_BORDER,
                                       350, 480,
                                       200, 20,
                                       window1, (HMENU) 2, NULL, NULL);
                window3 = CreateWindow("STATIC","Window 3",WS_BORDER|WS_CHILD,0,0,600,600,hwnd,NULL,NULL,NULL);
                button3 = CreateWindow(
                                       "BUTTON",
                                       "THIRD WINDOW",
                                       WS_CHILD | WS_VISIBLE | WS_BORDER,
                                       50, 480,
                                       200, 20,
                                       window1, (HMENU) 3, NULL, NULL);
                break;
    
            case WM_COMMAND:
    
                switch(LOWORD(wParam))
                {
                    case 2:
                        ShowWindow(window1,SW_HIDE);
                        ShowWindow(window2,SW_SHOW);
                        break;
                    case 3:
                        ShowWindow(window1,SW_HIDE);
                        ShowWindow(window3,SW_SHOW);
                        break;
                }
    
            break;
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }

首先,按照创建主窗体的步骤创建一个新的window1

然后为window1创建一个windowprocessforwindow1,在这个函数中处理WM_COMMAND消息。

示例如下:

#include <Windows.h>

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static HWND  window1, window2, button2, window3, button3;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("hello windows");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WindowProcedure;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
    }

    hwnd = CreateWindow(szAppName,
        TEXT("the hello program"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessageW(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        static HINSTANCE hInstance;
        static WNDCLASSEX win1;
    case WM_CREATE:
        hInstance = (HINSTANCE)::GetWindowLong(hwnd, GWL_HINSTANCE);
        win1.hInstance = hInstance;
        win1.lpszClassName = L"Window 1";
        win1.lpfnWndProc = (WNDPROC)windowprocessforwindow1;      /* This function is called by windows */
        win1.style = CS_DBLCLKS;                 /* Catch double-clicks */
        win1.cbSize = sizeof(WNDCLASSEX);
        win1.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        win1.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        win1.hCursor = LoadCursor(NULL, IDC_ARROW);
        win1.lpszMenuName = NULL;                 /* No menu */
        win1.cbClsExtra = 0;                      /* No extra bytes after the window class */
        win1.cbWndExtra = 0;                      /* structure or the window instance */
        win1.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
        if (!RegisterClassEx(&win1))
            return 0;
        window1 = CreateWindowEx(
            0,                   /* Extended possibilites for variation */
            L"Window 1",         /* Classname */
            L"Window 1",       /* Title Text */
            WS_VISIBLE | WS_BORDER | WS_CHILD, /* default window */
            0,       /* Windows decides the position */
            0,       /* where the window ends up on the screen */
            600,                 /* The programs width */
            600,                 /* and height in pixels */
            hwnd,        /* The window is a child-window to desktop */
            NULL,                /* No menu */
            hInstance,       /* Program Instance handler */
            NULL                 /* No Window Creation data */
        );
        window2 = CreateWindow(L"STATIC", L"Window 2", WS_BORDER | WS_CHILD, 0, 0, 600, 600, hwnd, NULL, NULL, NULL);
        button2 = CreateWindow(
            L"BUTTON",
            L"SECOND WINDOW",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            350, 480,
            200, 20,
            window1, (HMENU)2, NULL, NULL);
        window3 = CreateWindow(L"STATIC", L"Window 3", WS_BORDER | WS_CHILD, 0, 0, 600, 600, hwnd, NULL, NULL, NULL);
        button3 = CreateWindow(
            L"BUTTON",
            L"THIRD WINDOW",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            50, 480,
            200, 20,
            window1, (HMENU)3, NULL, NULL);
        ShowWindow(window1, SW_SHOW);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);       /* send a WM_QUIT to the message queue */
        break;
    default:                      /* for messages that we don't deal with */
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
    {
        switch (wParam) {
        case 2:
            ShowWindow(window1, SW_HIDE);
            ShowWindow(window2, SW_SHOW);
            break;
        case 3:
            ShowWindow(window1, SW_HIDE);
            ShowWindow(window3, SW_SHOW);
            break;
        }
    }
    return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:

        return DefWindowProc(handleforwindow1, msg, wParam, lParam);
    }
    return 0;
}