当我启用公共控件视觉样式支持(InitCommonControls())并且我使用除Windows经典主题之外的任何主题时,组框内的按钮将显示为带方形角的黑色边框。
Windows经典主题显示正常,以及当我关闭视觉样式时。
我正在使用以下代码:
group_box = CreateWindow(TEXT("BUTTON"), TEXT("BS_GROUPBOX"),
WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_GROUP,
10, 10, 200, 300,
hwnd, NULL, hInstance, 0);
push_button = CreateWindow(TEXT("BUTTON"), TEXT("BS_PUSHBUTTON"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
40, 40, 100, 22,
group_box, NULL, hInstance, 0);
编辑:问题发生在单选按钮和上
编辑:我没有使用任何对话框/资源,只有CreateWindow/Ex。
我在Visual C++2008 Express SP1下进行编译,使用一个通用清单文件
屏幕截图http://img.ispankcode.com/black_border_issue.png
问题是将groupbox作为控件的父级。Groupboxes不应该有任何孩子,将他们作为父母使用会导致各种错误(包括绘画、键盘导航和消息传播)。只需将按钮的CreateWindow调用中的父项从group_box更改为hwnd(即对话框)。
我猜你使用了groupbox作为父控件,以便在其中轻松定位其他控件。正确的方法是获取groupbox客户端区域的位置,并将其映射到对话框的客户端区域。放置在结果RECT中的所有内容都将显示在组框中。由于分组框实际上没有客户端区域,因此可以使用以下方法进行计算:
// Calculate the client area of a dialog that corresponds to the perceived
// client area of a groupbox control. An extra padding in dialog units can
// be specified (preferably in multiples of 4).
//
RECT getClientAreaInGroupBox(HWND dlg, int id, int padding = 0) {
HWND group = GetDlgItem(dlg, id);
RECT rc;
GetWindowRect(group, &rc);
MapWindowPoints(0, dlg, (POINT*)&rc, 2);
// Note that the top DUs should be 9 to completely avoid overlapping the
// groupbox label, but 8 is used instead for better alignment on a 4x4
// design grid.
RECT border = { 4, 8, 4, 4 };
OffsetRect(&border, padding, padding);
MapDialogRect(dlg, &border);
rc.left += border.left;
rc.right -= border.right;
rc.top += border.top;
rc.bottom -= border.bottom;
return rc;
}
请注意,这同样适用于Tab控件。他们也不是为人父母,会表现出类似的行为。
这里只是猜测,但看起来您继承了主题的静态边缘或客户端边缘样式。我从资源编辑器创建了大部分对话框,并在那里设置了这些属性。
在您的情况下,您可以将CreateWindow替换为CreateWindowEx来设置这些扩展样式,这些样式可能是CreateWindow中的默认样式。具体检查WS_EX_STATICEDGE, WS_EX_WINDOWEDGE and WS_EX_CLIENTEDGE
编辑:我假设这不会发生,因为你的按钮是对话框中的默认控件,它也会产生黑边。
显然,分组框并不意味着对控件进行分组(作为父级hwnd)
因此,为了消除黑边界/绘画问题,我必须将组框子类化,并实现WM_PAINT和WM_PRINTCLIENT
是的,黑色背景带有单选按钮和分组框。虽然我不确定这是否适用于VC++2008,但当时VB6主题应用程序的解决方案是先将单选控件放在PictureBox(实际上是一个通用容器)上,然后将其添加到组框中。
值得一试!