c++ - 如何使用 SetWindowPos 函数?
问题描述
我想创建一个由主父窗口和几个子窗口组成的 Windows 应用程序。这是我到目前为止的代码摘录:
...
// -----> 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);
// -------------------
...
问题出在SetWindowPos()
功能上。我无法理解它是如何工作的。我以为这样称呼它:
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);
将窗口移动Child 1
到所有应用程序窗口的顶部(正如文档所说的 HWND_TOP
选项:) Places the window at the top of the Z order
。
但是,窗口仍然按创建顺序绘制:
不应该SetWindowPos()
先移动Child 2
,Child 3
然后Child 1
移动Child 2
,使窗户以与创建时相反的顺序放置,Child 1
在顶部?
解决方案
使子窗口都具有窗口样式 WS_CLIPSIBLINGS 以及 WS_CHILD 等。
来自微软的文档:
如果未指定 WS_CLIPSIBLINGS 并且子窗口重叠,则在子窗口的客户区域内绘制时,可以在相邻子窗口的客户区域内绘制。
基本上,如果子窗口不相互剪辑,那么它们被绘制的顺序(这是任意的)决定了视觉 z 顺序。
例如,下面是您的代码,其中删除了消息框内容,使用 WS_VISIBLE 而不是 ShowWindow,添加可见性边框,并使用 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;
}
推荐阅读
- electron - 识别初级电子窗口
- facebook - 用于获取喜欢计数的 Facebook API
- firebase - 在使用 firebase 动态链接时,我是否需要为电子商务应用中的每个产品手动创建动态链接?
- javascript - 当我在数据表中添加按钮(打印)时,lengthChange 不显示
- dart - text justify 不能与 RichText 一起正常工作
- python - 双击将 txt 文件添加到自定义 PyQt 编辑器
- android - 预期为 BEGIN_OBJECT,但在第 1 行第 1 列路径为 STRING - Laravel 到改造 2
- php - 下单成功后更改第 n 个订单的用户角色
- html - 如何从后端 Django MarkdownX 渲染到 Vue.js 前端的 html?
- google-chrome - 添加到主屏幕迷你信息栏未在某些设备上显示