Search code examples
visual-c++comboboxmfc

Mapping CDialog CComboBox controls to an enum class object instead of int?


This question is a spin off this one (Is it possible to map CDialog RADIO controls to an enum class object instead of int?) and I am hoping that we can have a similar solution.

I have a few instances in my dialogs where I am representing an enum class as a drop-down list of options in a CComboBox (instead of using radio buttons).

Here is an example:

enum class ReportMode {
    Meeting = 0,
    Weekly
};

Currently my CComboBox is mapped to an int:

DDX_CBIndex(pDX, IDC_COMBO_REPORT_MODE, m_iReportMode);

I delved into the SDK for DDX_CBIndex:

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

Solution

  • Based on the answer supplied to the linked question, I beleive this to be correct:

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