【发布时间】:2012-05-06 16:22:25
【问题描述】:
我正在尝试学习如何使顶级 Win32 窗口成为另一个窗口的子窗口。
当我更改窗口的父级时,我仍然会得到难看的圆角,就好像它是一个带有圆角标题栏的顶级窗口一样。为什么?我该如何解决这个问题? (我无法得到WM_UPDATEUISTATE 的帮助,但我也不确定如何正确使用它。)
#include <tchar.h>
#include <windows.h>
#include <commctrl.h>
int _tmain()
{
WNDCLASS wndClass = {
0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
GetSysColorBrush(COLOR_3DFACE), NULL, TEXT("MyWindowClass")
};
ATOM atom = RegisterClass(&wndClass);
HWND hWnd = CreateWindow(MAKEINTATOM(atom), TEXT("Win"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
HWND hWndChild = CreateWindowEx(WS_EX_CLIENTEDGE,
WC_EDIT, TEXT("Control"), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10, 10, 86, 24, NULL, NULL, NULL, NULL);
SetParent(hWndChild, hWnd); // Change the parent
SetWindowLong(hWndChild, GWL_STYLE, // Set child styles
GetWindowLong(hWndChild, GWL_STYLE)
& ~(WS_OVERLAPPED | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
| WS_CHILDWINDOW);
SetWindowPos(hWndChild, NULL, 0, 0, 0, 0, // Refresh
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
| SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_FRAMECHANGED);
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, hWnd, 0, 0)) != 0 && bRet != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
【问题讨论】:
-
子窗口应该是 WS_CHILD 而不是 WS_POP。
-
@HansPassant:对,这就是为什么我在创建后使用
SetWindowLong来更改样式。还是我错过了什么? -
这是非常不规则的。最好从一开始就将窗口创建为子窗口-最初将其放在顶级窗口父级中。然后,您可以将其移至新的父级,而无需摆弄所有样式。
-
@RaymondChen:是的,但问题是,当窗口开始时不是是一个孩子,你怎么做呢?我真的不介意代码是否复杂,只要它有效。 (这甚至可能吗?我认为
SetParent的存在意味着它是......) -
@RaymondChen:或者,如果您愿意,让我提出一个不同的问题:在创建窗口后应该不修改窗口的哪些属性? (换句话说,
CreateWindowEx的哪些参数我可以推迟到以后,我必须提供哪些参数就在那里才能正确操作?)根据您的回复,我假设hwndParent是其中之一,并且(显然)类名是其中之一——但还有其他的吗?
标签: c windows winapi visual-c++ parent