winapivisual-c++mfcccombobox

Are there any Win32 functions I can use to get the count / itemdata from a CComboBoxEx control?


My parent dialog has a CComboBoxEx control (which is mapped to a derived class called CDatesComboBoxEx).

In one part of the application this dialog displays a popup modal dialog. And, inside the modal dialog, it needs access to information from the dates combo.

What I decided to do (which works fine) is pass the address of my combo in the constructor of the popup dialog. So I can now do things like:

I was wondering if there was any way to use native Win32 code here instead?

So is it possible to somehow directly get the count and item data?


I know that there are these macros:

But:

  1. Can these be macros be used with CComboBoxEx control? And ...
  2. How do we get the HWND on the combo given the context I previously described?

Actually, I think I missunderstood the purpose of those "macros". I can get the combo handle like this:

HWND hDatesCombo = ::GetDlgItem(
    GetParent()->GetSafeHwnd(), IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING);

But, ComboBox_GetCount does not return a value. Nor the others. So I am somewhat confused.


Based on the answer, this bit is now fine:

HWND hDatesCombo = ::GetDlgItem(GetParent()->GetSafeHwnd(), IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING);
int iNumDates = static_cast<int>(::SendMessage(hDatesCombo, CB_GETCOUNT, 0, 0));

And inside my for loop I am doing this:

LRESULT itemData = ::SendMessage(hDatesCombo, CB_GETITEMDATA, static_cast<WPARAM>(i), 0);
auto* pEntry = static_cast<CChristianLifeMinistryEntry*>((LPVOID)itemData);

That is the only way I can find to cast it. If I try static_cast<LPVOID> it won't work either.


Solution

  • I was wondering if there was any way to use native Win32 code here instead?

    Yes, there is. The SendMessage function (and its returned value) is what you need …

    Once you have the HWND of your combo-box, you can send it the CB_GETCOUNT message to ask it how many items it contains:

    HWND hDatesCombo = ::GetDlgItem(GetParent()->GetSafeHwnd(), IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING);
    LRESULT nItems = ::SendMessage(hDatesCombo, CB_GETCOUNT, 0, 0);
    

    And, to get the item data associated with a particular entry, send the CB_GETITEMDATA message, with the (zero-based) index of the item in question as the wParam argument:

    //...
    LRESULT *ItemData = new LRESULT[static_cast<size_t>(nItems)];
    for (int i = 0; i < nItems; ++i) {
        ItemData[i] = ::SendMessage(hDatesCombo, CB_GETITEMDATA, static_cast<WPARAM>(i), 0);
    }
    //...
    delete[] ItemData; // When you're done with the data list
    

    Of course, if your item data are pointers (such as if you have an owner-drawn combo with1 the CBS_HASSTRINGS style), you would need to modify the second code snippet accordingly, adding relevant the reinterpret_cast operations where necessary. (Note that both the LRESULT and WPARAM types are defined as being suitable for storing pointers.)


    1 The linked M/S documentation page is a bit fuzzy on whether this applies to owner-drawn combos with or without the CBS_HASSTRINGS style.