ShowWindow within WM_CREATE
The way I see it, one use of a Window Procedure's WM_CREATE message is to relieve the caller of the burden of executing static code at window initialization. My window is to execute some code in the WM_CREATE message, including the ShowWindow function. I also want the ShowWindow to behave properly according to the nCmdShow parameter in WinMain. So here is pseudo-code to show how I have things set up:
int g_nCmdShow;
WinMain(..., int nCmdShow)
{
g_nCmdShow = nCmdShow;
...
CreateWindow(..., WM_OVERLAPPEDWINDOW, ...)
...
}
WndProc()
{
...
WM_CREATE:
...
ShowWindow(hWnd, g_nCmdShow);
.开发者_C百科..
...
}
So I set up the program to run Minimized (using Windows XP I created a shortcut to the .exe, and set up the properties of it accordingly), and it displays on the taskbar minimized but it does not restore when I click on it. Likewise, if I run it Maximized, it does not behave correctly when I click the maximize button (to un-maximize it).
What is the correct way to use nCmdShow-compatible ShowWindow within the WM_CREATE message?
The problem is that the window's restore bounds get affected by this. They become the size of the window after WM_CREATE returns. You would have to modify your code to re-establish those restore bounds:
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 300, 200, NULL, NULL, hInstance, NULL);
WINDOWPLACEMENT wp;
GetWindowPlacement(hWnd, &wp); // <= Note wp.rcNormalPosition after this call!
RECT rc = {100, 100, 400, 300};
wp.rcNormalPosition = rc;
SetWindowPlacement(hWnd, &wp);
You're not ahead by doing it this way.
If you absolutely have to keep it in the WndProc, try
case WM_CREATE:
PostMessage(hwnd,WM_APP,0,0);
break;
case WM_APP:
ShowWindow(hwnd,SW_SHOW);
break;
But if this is so important, why not just have a helper function that creates the window and calls ShowWindow? MyWindowType_Create(...) etc
Having the window show itself, or set its own position, is a bad design choice that goes against how WinAPI was meant to be used. The right place to do these decisions is in the code that creates the window. It's already reflected in the fact that the CreateWindow
is responsible for the initial window placement and WS_VISIBLE
style.
In your code you should call ShowWindow
in WinMain
, which will also eliminate the need for the g_nCmdShow
global:
WinMain(..., int nCmdShow)
{
...
hWnd = CreateWindow(..., WM_OVERLAPPEDWINDOW, ...)
ShowWindow(hWnd, nCmdShow);
...
}
WndProc()
{
...
WM_CREATE:
...
...
}
WM_CREATE
is rather responsible for initializing window-class specific behavior. Creating child windows or initializing internal data structures and the cbWndExtra
slots are examples of that (e.g. think of implementing a list-box).
Can you handle WM_WINDOWPOSCHANGED
and override the window size the first time the window is restored? Use GetWindowPlacement
to find out if the window got restored.
精彩评论