如何将子控件放置在组框中?

Bob*_*nes 4 c user-interface winapi

当我启用通用控件视觉样式支持 (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);
Run Code Online (Sandbox Code Playgroud)

编辑:单选按钮也会出现此问题

编辑:我没有使用任何对话框/资源,仅使用 CreateWindow/Ex。

我正在 Visual C++ 2008 Express SP1 下使用通用清单文件进行编译

截图http://img.ispankcode.com/black_border_issue.png

efo*_*nis 6

问题在于将组框作为控件的父级。Groupbox 不应该有任何子级,将它们用作父级会导致各种错误(包括绘画、键盘导航和消息传播)。只需将按钮的 CreateWindow 调用中的父级从group_box更改为hwnd(即对话框)。

我猜您使用组框作为父项是为了轻松地将其他控件放置在其中。执行此操作的正确方法是获取组框客户区的位置并将其映射到对话框的客户区。然后,放置在生成的 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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这同样适用于选项卡控件。他们也不是为父母而设计的,并且会表现出类似的行为。