假设hCtl
是创建没有 WS_VISIBLE标志的控件的句柄,例如:
HWND hCtl = CreateWindowEx(0, WC_STATIC, L"some text",
WS_CHILD | SS_NOTIFY, // no WS_VISIBLE flag
0, 0, 0, 0, hWndParent, (HMENU)IDC_STATIC1, g_hInst, 0);
是否有比以下更直接的方式让它可见?
void make_visible(HWND hCtl, HWND hWndParent) {
SetWindowLongPtr(hCtl, GWL_STYLE,
GetWindowLongPtr(hCtl, GWL_STYLE) | WS_VISIBLE);
RECT rc{};
GetClientRect(hCtl, &rc);
MapWindowRect(hCtl, hWndParent, &rc);
InvalidateRect(hWndParent, &rc, TRUE);
UpdateWindow(hWndParent);
//ShowWindow(hCtl, SW_SHOW); // no use: does not update window
//SetWindowPos(hCtl, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); // no use: does not update window
}
答案 0 :(得分:3)
要使子控件可见,请像这样调用SetWindowPos
:
SetWindowPos(hCtl, 0, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
应删除您拨打MapWindowRect
,InvalidateRect
,UpdateRect
等的代码。
也许你遇到的真正问题是你创建了零宽度和高度的静态控件。
答案 1 :(得分:2)
使窗口可见的常规方法只是函数ShowWindow。没有必要处理标志等等。通常使用SW_SHOW
作为子窗口的参数。检查其他值并使用您认为合适的值。
如果窗口有一个可见的矩形,并且没有被另一个窗口覆盖,它将显示出来。甚至不需要UpdateWindow调用。窗口将显示在下一个绘制周期中。如果您的控件的大小为0,0,0,0(因为它已创建),它将永远不会显示。
如果窗口位于不同的线程上以避免阻塞,还有一个ShowWindowAsync函数可供使用。
BTW:我不明白您尝试使父窗口区域无效。如果存在子窗口剪辑(WS_CLIPCHILDREN
),则它无效。
答案 2 :(得分:2)
我相信你的问题是你明确地设置WS_VISIBLE
样式然后然后调用ShowWindow
,这会让Windows感到困惑,认为窗口已经可见并且不需要重新粉刷。
只需致电ShowWindow
即可。 There should be no need to explicitly set WS_VISIBLE
yourself因为ShowWindow
already does it。你不应该强行重绘你的控制。
此外,如果您发现某些内容需要明确地使您的控件无效,那么只需执行InvalidateRect(hCtl, NULL)
即可,而不必担心GetClientRect
和MapWindowRect
。