如何使用 Windows API 重新打开已关闭的 window
How to reopen a closed window with the Windows API
我在主 window ( hwnd ) 中制作了一个按钮,当你点击一个按钮时,它会打开新的 window ( hwndSec ),它可以由主 window!
当我点击一个按钮时,hwndSec 出现了!当我点击其他按钮时,它可以被修改......但是当我关闭它并尝试再次打开它时它没有响应!所以按钮变得无用了!
这是单个按钮的简单示例,仅用于打开 window 然后尝试再次打开它。
我为 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
);
我做了两个window程序:
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WindowProcedureSec (HWND, UINT, WPARAM, LPARAM);
当我点击一个按钮时,我调用这个函数:
ShowWindow(hwndSec,SW_SHOW);
然后第二个 window 正常出现,当我关闭 window 它不会再次出现。
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;
}
当 window 被关闭时,它会收到一条 WM_CLOSE
消息。如果该消息传递给 DefWindowProc()
,默认行为是 销毁 window:
An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE
message and calling the DestroyWindow
function only if the user confirms the choice.
By default, the DefWindowProc
function calls the DestroyWindow
function to destroy the window.
这在 MSDN 上有进一步讨论:
因此,每次您想要在关闭后显示它时,您都必须使用 CreateWindow/Ex()
重新创建您的辅助 window:
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);
}
如果您不想这样做,则需要让辅助 window 处理 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;
}
我在主 window ( hwnd ) 中制作了一个按钮,当你点击一个按钮时,它会打开新的 window ( hwndSec ),它可以由主 window!
当我点击一个按钮时,hwndSec 出现了!当我点击其他按钮时,它可以被修改......但是当我关闭它并尝试再次打开它时它没有响应!所以按钮变得无用了!
这是单个按钮的简单示例,仅用于打开 window 然后尝试再次打开它。
我为 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
);
我做了两个window程序:
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WindowProcedureSec (HWND, UINT, WPARAM, LPARAM);
当我点击一个按钮时,我调用这个函数:
ShowWindow(hwndSec,SW_SHOW);
然后第二个 window 正常出现,当我关闭 window 它不会再次出现。
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;
}
当 window 被关闭时,它会收到一条 WM_CLOSE
消息。如果该消息传递给 DefWindowProc()
,默认行为是 销毁 window:
An application can prompt the user for confirmation, prior to destroying a window, by processing the
WM_CLOSE
message and calling theDestroyWindow
function only if the user confirms the choice.By default, the
DefWindowProc
function calls theDestroyWindow
function to destroy the window.
这在 MSDN 上有进一步讨论:
因此,每次您想要在关闭后显示它时,您都必须使用 CreateWindow/Ex()
重新创建您的辅助 window:
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);
}
如果您不想这样做,则需要让辅助 window 处理 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;
}