子窗口Z顺序

时间:2013-07-18 11:38:30

标签: winapi

我在MSDN中看到它说:

如果创建的窗口是子窗口,则其默认位置位于Z顺序的底部。如果创建的窗口是顶级窗口,则其默认位置位于Z顺序的顶部(但在所有最顶层窗口的下方,除非创建的窗口本身位于最顶层)。 (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx

然而,另一份文件说: 当应用程序创建一个窗口时,系统会将它放在同一类型窗口的z顺序顶部http://msdn.microsoft.com/en-us/library/windows/desktop/ms632599(v=vs.85).aspx

正如我测试的那样,

btn1 = ::CreateWindow(L"button", L"OK", WS_TABSTOP|BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD
                    , 10, 10, 50, 30, hWnd, (HMENU)51, hInst, NULL);
btn2 = ::CreateWindow(L"button", L"Cancel", WS_TABSTOP|WS_CHILD|BS_PUSHBUTTON|WS_VISIBLE
                    , 20, 20, 70, 30, hWnd, (HMENU)52, hInst, NULL);

新创建的子窗口(例如:我在窗口中创建了两个按钮并且它们重叠,我可以看到稍后创建的按钮覆盖了创建的第一个按钮)

MSDN中的第一个声明是否与我的测试相矛盾。

2 个答案:

答案 0 :(得分:8)

文档准确无误。您正被另一个问题绊倒,您允许子窗口在其他子窗口中绘制自己。所以现在绘画顺序很重要。

您可以通过将WS_CLIPSIBLINGS样式标志添加到CreateWindowEx调用来解决此问题。您现在看到确定按钮位于顶部。修正:

btn1 = ::CreateWindow(L"button", L"OK", 
           WS_TABSTOP|BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS,
           10, 10, 50, 30, hWnd, (HMENU)51, hInst, NULL);
// etc, use it as well on other child windows

答案 1 :(得分:2)

您不应该太依赖子窗口的显示方式以及最后绘制的窗口。如果我运行你的示例代码,我会得到一个OK按钮,它与Cancel按钮重叠。如果我将鼠标移到按钮上,则“确定”按钮进入前景并覆盖“取消”按钮。

我曾经遇到过重叠子控件的类似问题。然后我发现微软说Overlapping Controls Are Not Supported by Windows

顺便说一句,如果您真的想看到Z顺序,请使用GetTopWindowGetNextWindow。或者更简单的方法:运行Microsoft Spy++