Reputation: 77
I'd like to create a Windows app consisting of a main parent window and several child windows. Here is an excerpt of the code I have so far:
...
// -----> CHILD WINDOWS <-----
HWND hWnd_child1 = CreateWindowW(L"STATIC", L"Child 1", WS_CHILD,
0, 0, 100, 80, hParentWnd, nullptr, hInstance, nullptr);
if (!hWnd_child1) {
MessageBox(NULL, L"CreateWindowW Child 1", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
HWND hWnd_child2 = CreateWindowW(L"STATIC", L"Child 2", WS_CHILD,
10, 10, 160, 120, hParentWnd, nullptr, hInstance, nullptr);
if (!hWnd_child2) {
MessageBox(NULL, L"CreateWindowW Child 2", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
HWND hWnd_child3 = CreateWindowW(L"STATIC", L"Child 3", WS_CHILD,
20, 20, 160, 120, hParentWnd, nullptr, hInstance, nullptr);
if (!hWnd_child3) {
MessageBox(NULL, L"CreateWindowW Child 3", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
ShowWindow(hWnd_child3, nCmdShow);
SetWindowPos(hWnd_child2, HWND_TOP, 10, 10, 100, 80, NULL);
ShowWindow(hWnd_child2, nCmdShow);
SetWindowPos(hWnd_child1, HWND_TOP, 0, 0, 100, 80, NULL);
ShowWindow(hWnd_child1, nCmdShow);
ShowWindow(hParentWnd, nCmdShow);
UpdateWindow(hParentWnd);
// -------------------
...
The problem is with the SetWindowPos()
function. I can't understand how it really works. I thought that calling it like this:
ShowWindow(hWnd_child3, nCmdShow);
SetWindowPos(hWnd_child2, HWND_TOP, 10, 10, 100, 80, NULL);
ShowWindow(hWnd_child2, nCmdShow);
SetWindowPos(hWnd_child1, HWND_TOP, 0, 0, 100, 80, NULL);
ShowWindow(hWnd_child1, nCmdShow);
Would move the Child 1
window to the top of all the app windows (as the doc says for the HWND_TOP
option: Places the window at the top of the Z order
).
BUT, the windows are still drawned in the creation order:
Shouldn't SetWindowPos()
move firstly Child 2
over Child 3
, and next Child 1
over Child 2
, making the windows laid up in the reverse order than they were created, with Child 1
on top?
Upvotes: 2
Views: 5562
Reputation: 9545
Make the child windows all have the window style WS_CLIPSIBLINGS along with WS_CHILD etc.
From Microsoft's documentation:
If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window.
Basically if the child windows do not clip each other then the order in which they are painted (which is arbitrary) determines the visual z-order.
Below for instance is your code with the message box stuff removed, using WS_VISIBLE instead of ShowWindow, adding a border for visibility, and using WS_CLIPSIBLINGS.
BOOL CreateChildren(HWND hParentWnd) {
HWND hWnd_child1 = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", L"Child 1", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
0, 0, 100, 80, hParentWnd, nullptr, g_hInstance, nullptr);
HWND hWnd_child2 = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", L"Child 2", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
10, 10, 160, 120, hParentWnd, nullptr, g_hInstance, nullptr);
HWND hWnd_child3 = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", L"Child 3", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
20, 20, 160, 120, hParentWnd, nullptr, g_hInstance, nullptr);
SetWindowPos(hWnd_child2, HWND_TOP, 10, 10, 100, 80, NULL);
SetWindowPos(hWnd_child1, HWND_TOP, 0, 0, 100, 80, NULL);
UpdateWindow(hParentWnd);
return TRUE;
}
which yields
child1 is on top.
Upvotes: 3