如何使用Windows API重新打开关闭的窗口

时间:2016-10-25 16:21:11

标签: c++ winapi button window

我正在主窗口(hwnd)中创建一个按钮,当您单击按钮时,它会打开可由主窗口控制的新窗口(hwndSec)! 当我点击一个按钮时,hwndSec出现了!当我点击其他按钮时,它可以被修改...但是当我关闭它并尝试再次重新打开它时它没有响应!所以按钮变得无用! 这是一个简单的单个按钮示例,只是打开窗口然后再尝试打开它。

我为hwndSec设置的设置:

wincl.hInstance = hInstance;
wincl.lpszClassName = "HwndSecClass";
wincl.lpfnWndProc = WindowProcedureSec;      
wincl.style = CS_DBLCLKS;                 
wincl.cbSize = sizeof (WNDCLASSEX);

/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;                 
wincl.cbClsExtra = 0;                      
wincl.cbWndExtra = 0;                      
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

if (!RegisterClassEx (&wincl))
    return 0;

hwnd = CreateWindowEx (
       0,                   
       wincl.lpszClassName,        
       _T("Window 2"),       
       WS_OVERLAPPEDWINDOW, 
       CW_USEDEFAULT,       
       CW_USEDEFAULT,       
       500,                 
       500,                 
       HWND_DESKTOP,        
       NULL,                
       hInstance,       
       NULL                
       );

我做了两个窗口程序:

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WindowProcedureSec (HWND, UINT, WPARAM, LPARAM);

当我点击一个按钮时,我称这个功能为:

ShowWindow(hwndSec,SW_SHOW);

然后第二个窗口正常显示,当我关闭窗口时,它不会再次出现。

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)                  /* handle the messages */
 {
 case WM_CREATE:
    CreateWindow("BUTTON",
                "open",
                WS_CHILD | WS_VISIBLE ,
                200,100,
                100,50,
                hwnd,
                (HMENU) ID_BUTTON,
                NULL,
                NULL);
    break;
case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case ID_BUTTON :
        //printf("%s",(char*)GetLastError());
        ShowWindow(hwndSec,SW_SHOW);
        break;
    }
    break;
    case WM_DESTROY:
        PostQuitMessage (0);
        break;
    default:
        return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}


LRESULT CALLBACK WindowProcedureSec (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
{
    case WM_DESTROY:
        PostMessage(hwnd, WM_CLOSE, 0, 0);
        break;
    default:
        return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}

1 个答案:

答案 0 :(得分:0)

当窗口关闭时,它会收到WM_CLOSE消息。如果该消息传递给DefWindowProc(),则默认行为是销毁窗口

  

应用程序可以在销毁窗口之前通过处理WM_CLOSE消息并仅在用户确认选择时调用DestroyWindow函数来提示用户进行确认。

     

默认情况下,DefWindowProc函数调用DestroyWindow函数来销毁窗口。

这在MSDN上进一步讨论:

Closing the Window

因此,每次要关闭后,您都必须使用CreateWindow/Ex()重新创建辅助窗口:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    ...
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_BUTTON :
            if (!hwndSec)
            {
                hwndSec = CreateWindowEx(
                    0,
                    _T("HwndSecClass"),
                    _T("Window 2"),
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    500,
                    500,
                    HWND_DESKTOP,
                    NULL,
                    hInstance,
                    NULL
                );
            }
            ShowWindow(hwndSec, SW_SHOW);
            break;
        }
        break;
    ...
    }

    return 0;
}

LRESULT CALLBACK WindowProcedureSec (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        hwndSec = NULL;
        break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

如果您不想这样做,那么您需要让辅助窗口处理WM_CLOSE消息,而不是将其传递给DefWindowProc()。例如,请改为调用ShowWindow(SW_HIDE),然后您可以在需要时调用ShowWindow(SH_SHOW)

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    ...
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_BUTTON :
            ShowWindow(hwndSec, SW_SHOW);
            break;
        }
        break;
    ...
    }

    return 0;
}


LRESULT CALLBACK WindowProcedureSec (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CLOSE:
        ShowWindow(hwnd, SW_HIDE);
        break;

    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    return 0;
}