8

首先这不是MFC。
这是我一直在处理的 GUI 的裁剪版本:

在此处输入图像描述

如您所见,我已经(尝试)使用以下代码创建了两个不同的组,图标和按钮:

    index->hAddT.hwndIndex[2] = CreateWindowEx(NULL,L"BUTTON",L"Icon",WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
    200,135,120,170,WINDOWHANDLE,(HMENU)IDC_RADIOGROUP,(HINSTANCE)GetWindowLong(WINDOWHANDLE,GWL_HINSTANCE),NULL);

我遇到的问题以及您可能看到的问题是该窗口只有一个单选按钮。这意味着用户不可能从 Icon 组中选择一个单选按钮,从 Button 组中选择一个。我已将每个单选按钮初始化为:

    index->hAddT.hwndIndex[3] = CreateWindowEx(NULL,L"BUTTON",L"Information",WS_CHILD | BS_AUTORADIOBUTTON | WS_VISIBLE,
    205,155,100,20,WINDOWHANDLE,(HMENU)IDC_RADIO1,(HINSTANCE)GetWindowLong(WINDOWHANDLE,GWL_HINSTANCE),NULL);       

如果有意义的话,我想以某种方式将“图标”单选按钮组与“按钮”单选按钮组分开,因此每个组都可以使用一个单选按钮。这怎么可能,是否需要我创建一个新窗口和一个新的回调程序只是为了有一个额外的单选按钮。必须有另一种方法来对子项进行分组。

2 组独立的单选按钮组,形式相同 WINAPI(无 MFC) 该链接对我的目的没有任何用处。

我有我旁边的 Charles Petzold 编写的 Programming For Windows Fifth Edition 作为参考,他在 Group Boxes 部分中指出“Group box 通常用于包围其他按钮控件”,但没有这方面的真实示例。

4

2 回答 2

15

与流行的观点相反,您不需要 groupbox 控件或任何其他此类外部“容器”(groupbox 无论如何都不是,它只是一个按钮工件)。下面描述了如何在不需要组框的情况下执行此操作。如果您想要一个在功能上帮助此处描述的布局的组框,请转发到此答案的编辑 部分,我将在其中解释如何实现 OP 的特定需求。

自动单选按钮“banks”通过使用两个关键窗口样式属性WS_GROUPWS_TABSTOP 工作。为您的两个“银行”执行以下操作,我将它们亲切地称为 Bank1 和 Bank2:

  1. 银行 1:第一个单选按钮应该同时具有WS_GROUP | 控件样式中的 WS_TABSTOP。其余的单选按钮不应该有这些,并且必须按兄弟顺序(这意味着在 DIALOG 脚本中它们立即相互跟随;在动态创建中它们是按顺序创建的)。

  2. Bank1 中最后一个单选按钮之后的第一个子控件应该至少具有 WS_GROUP 样式,并且 WS_GROUP | WS_TABSTOP 如果它是制表符停止的控件。

  3. 银行 2:第一个单选按钮应该同时具有WS_GROUP | 控件样式中的 WS_TABSTOP。其余的单选按钮不应该有这些,并且必须按兄弟顺序(这意味着在 DIALOG 脚本中它们立即相互跟随;在动态创建中它们是按顺序创建的)。

  4. Bank2 中最后一个单选按钮之后的第一个子控件应该至少具有 WS_GROUP 样式,并且 WS_GROUP | WS_TABSTOP 如果它是制表符停止的控件。

像上面这样的布局允许您“选项卡”到单选按钮库,并使用箭头键切换选择。然后,您再次“制表”以离开该银行并前往下一个制表位。请记住,当您点击 Tab(或之前使用 Shift-Tab)时,对话框管理器将始终移动到下一个 WS_TABTOP 子控件。如果要跳转到的控件是自动类型,则选定的控件将是最近 WS_GROUP 中的“选定”控件。

如果有帮助,请拿一个草稿本,在纸上画出来,然后在制表位上贴上“T”,在组属性上贴上“G”,如上所述。一旦可视化,它可能会更清晰。查看对话资源脚本以了解它们如何协同工作以获得更多洞察力。

注意:如果您想使用围绕这些的分组框,您可以。对话框管理器通过将控件关联到基于使用 WS_GROUP 标记的最后一个控件的组来工作,并且此后具有 WS_TABSTOP 的第一个控件被认为是该组的制表符跳转点。首先插入一个 Groupbox(不能是制表符),然后在第一个单选按钮上插入带有 WS_TABSTOP 的单选按钮控件(这次没有 WS_GROUP),也可以。我通常发现只安排我的单选按钮而不依赖于组框更容易。

编辑一张图说一千个字

对于您的图片,我可能会按以下顺序创建以下子项:

  1. “图标”组框,包括 WS_GROUP 样式。
  2. “信息”自动单选按钮,包括 WS_TABSTOP
  3. 所有其他“图标”组单选按钮。不要包括 WS_TABSTOP 或 WS_GROUP。
  4. “按钮”组框,包括 WS_GROUP 样式。这将关闭当前控制组并开始下一个控制组。
  5. “AbortretryIgnore”自动单选按钮,包括 WS_TABSTOP
  6. 所有其他“按钮”组单选按钮。不要包括 WS_TABSTOP 或 WS_GROUP。
  7. “Button”单选按钮之后的下一个控件必须包含 WS_GROUP。这将关闭当前控制组并开始下一个控制组。

显然,所有其他子控件样式、可见性等也需要正确使用,当然,子控件都应该具有唯一的 ID。我假设您已经涵盖了其余部分。

于 2012-11-25T10:33:31.167 回答
0

请注意,这也适用于一组复选框,这是一个有效的用例。

请注意,如果第一个单选按钮可能被禁用(例如,通过运行时条件),您必须使第一个启用的单选按钮具有 WS_TABSTOP 样式。这是一些确保这一点的代码行:

    // Set WS_TABSTOP to the group's first enabled item
    for (HWND hwnd = GetDlgItem(IDC_FIRSTITEM) /*the first*/; hwnd != NULL && !::IsWindowEnabled(hwnd); hwnd = ::GetWindow(hwnd, GW_HWNDNEXT))
    {
        if ((GetWindowLong(hwnd, GWL_STYLE) & WS_GROUP) != 0)
            hwnd = NULL;
    }
    if (hwnd != NULL)
        ModifyStyle(hwnd, 0, WS_TABSTOP, 0);
于 2020-04-15T11:13:10.433 回答