Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly use DDX (Data Exchange) with the CComboBox Control?

The MFC offers a function called DDX_CBIndex to get the Index of the current selected ComboBox item. But in most cases I'm not interested about the index, instead I want to get the 32 bit application-supplied value, which I get when calling GetItemData. Therefore I always have to override OnOk and use GetCurSel and GetItemData to retrieve this value.

Is there a more elegant way to get/set the CComboBox item not depending on the index but depending on the application-supplied 32 bit value?

Thank you!

like image 672
Christian Ammer Avatar asked Nov 07 '25 04:11

Christian Ammer


2 Answers

I had a partial solution to this problem, but using the suggestion of @taspeotis, I wrote this, which seems to work pretty well.

    template <class T>
void DDX_CBData(CDataExchange* pDX, int nIDC, T& data)
{
    HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
    if (pDX->m_bSaveAndValidate)
    {
        int index = static_cast<int>(::SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0L));
        data = (index == CB_ERR ? NULL : reinterpret_cast<T>(::SendMessage(hWndCtrl, CB_GETITEMDATA, index, 0L)));
    }
    else
    {
        int count = static_cast<int>(::SendMessage(hWndCtrl, CB_GETCOUNT, 0, 0L));
        for (int i = 0; i != count; ++i)
        {
            if (reinterpret_cast<T>(::SendMessage(hWndCtrl, CB_GETITEMDATA, i, 0L)) == data)
            {
                ::SendMessage(hWndCtrl, CB_SETCURSEL, i, 0L);
                return;
            }
        }
        ::SendMessage(hWndCtrl, CB_SETCURSEL, -1, 0L);
    }
}
like image 58
Randy Coulman Avatar answered Nov 09 '25 03:11

Randy Coulman


Why not write one implementation and then use it in DoDataExchange? For example, MyDDX_CBUserData?

like image 37
ta.speot.is Avatar answered Nov 09 '25 01:11

ta.speot.is



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!