将 CDialog CComboBox 控件映射到枚举类对象而不是 int?

Posted

技术标签:

【中文标题】将 CDialog CComboBox 控件映射到枚举类对象而不是 int?【英文标题】:Mapping CDialog CComboBox controls to an enum class object instead of int? 【发布时间】:2021-10-16 08:17:20 【问题描述】:

这个问题是这个问题 (Is it possible to map CDialog RADIO controls to an enum class object instead of int?) 的衍生问题,我希望我们可以有类似的解决方案。

在我的对话框中有几个实例,我将enum class 表示为CComboBox 中的选项下拉列表(而不是使用单选按钮)。

这是一个例子:

enum class ReportMode 
    Meeting = 0,
    Weekly
;

目前我的CComboBox 映射到int

DDX_CBIndex(pDX, IDC_COMBO_REPORT_MODE, m_iReportMode);

我深入研究了DDX_CBIndex 的 SDK:

void AFXAPI DDX_CBIndex(CDataExchange* pDX, int nIDC, int& index)

    pDX->PrepareCtrl(nIDC);
    HWND hWndCtrl;
    pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
    if (pDX->m_bSaveAndValidate)
        index = (int)::SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0L);
    else

        ::SendMessage(hWndCtrl, CB_SETCURSEL, (WPARAM)index, 0L);

【问题讨论】:

【参考方案1】:

根据提供给链接问题的答案,我认为这是正确的:

template<typename E>
void AFXAPI DDX_CBIndexEnum(CDataExchange* pDX, int nIDC, E& value)

    pDX->PrepareCtrl(nIDC);
    HWND hWndCtrl;
    pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
    if (pDX->m_bSaveAndValidate)
        value = static_cast<E>(::SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0L));
    else
        ::SendMessage(hWndCtrl, CB_SETCURSEL, static_cast<WPARAM>(value), 0L);

【讨论】:

这是正确的,假设满足相同的要求(枚举值必须从零开始,以 1 为增量递增,没有间隙,也没有重复)。此外,就像链接的问答一样,没有错误处理。如果发送CB_GETCURSEL 返回值CB_ERR (-1),那么它也会转换为E 类型。就 C++ 而言,这是合法的,但会对可能不准备查看没有名称的枚举值的客户端代码产生影响。 @IInspectable 当然。由于这是一个下拉列表,因此值是固定的,组合数据未排序。所以我们应该没问题。谢谢。

以上是关于将 CDialog CComboBox 控件映射到枚举类对象而不是 int?的主要内容,如果未能解决你的问题,请参考以下文章

CComboBox MFC 控件出现问题

VC/MFC中的CComboBox控件使用详解

如何将 CDialog::SetDefId 与非按钮控件一起使用?

枚举 CDialog 中子控件的最快方法

CCombobox使用大全

ccombobox怎样设置文字垂直居中