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);

编辑:问题发生在单选按钮和上

编辑:我没有使用任何对话框/资源,只有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(实际上是一个通用容器)上,然后将其添加到组框中。

值得一试!

相关内容

  • 没有找到相关文章

最新更新