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

Time:10-03

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:

  • m_pComboDates->GetCount()
  • m_pComboDates->GetItemDataPtr(i)

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

  • We can get access to the parents handle (GetParent()->GetSafeHWnd()).
  • We know the ID of the control on the parent dialog (IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING).

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.

CodePudding user response:

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.

  • Related