[Webinar] Streamline your web hosting managementRegister Today

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3753
  • Last Modified:

MFC/C++: convert combo box entry to cstring / int

I need to convert the currently selected item from a combo box into a cstring, int, and float. What's the best way?

For example,

      int selectedIndex = myComboBox.GetCurSel();

      // convert to string, int, and float, these don't work
      CString dataString   =   myComboBox.GetItemData(selectedIndex);
      int dataInt   =   myComboBox.GetItemData(selectedIndex);
      float dataFloat   =   myComboBox.GetItemData(selectedIndex);
3 Solutions
Instead of GetItemData, it would probably be easier to use GetLBText.  You will still need to convert the string to int or float using atoi and atof, though MFC might also have a conversion function as well.  I just am not so familiar with MFC so I don't know off hand.

GetItemData is not really what you want any way, it return a 32 bit value that you have previously associated with the data at the specified index.

GetItemData() Is used if you previously used SetItemData(), if not, you should use GetLBText(myComboBox.GetCurSel(), buffer).

If you used SetItemData, when you query the value with GetItemData, you simply get a DWORD, that can represent an Int or a pointer to anything.

If you have any trouble, write again.
>>>> Instead of GetItemData, it would probably be easier to use GetLBText.  

That is not an alternative. You use GetItemData instead of GetLBText if the text returned by GetLBText wouldn't give a unique 'key' to additional additional data associated with each entry of the combobox. GetItemData can return an arbitrary data item you *additionally* added to each entry in the combobox by calling SetItemData(). Typically, you were using that 'technique'' if you want to associate some kind of record or data object with each entry in the combobox, e. g. if you loaded data from a database into class objects and have a combobox where the user can select one of the items loaded. The data item you would associate in that case is the index of the container where you stored the class objects. The advantage of doing so is that you can have a automatically sorted combo box and nevertheless you easily can retrieve every selected combobox entry in your container by first getting the data item (index) and second use the index to access your container:

      int selectedIndex = myComboBox.GetCurSel();
      if (selectedIndex >= 0)
             int selectedContainerIndex = (int)myComboBox.GetItemData(selectedIndex );
             MyDataClass & dataEntry = myDataContainer[selectedContainerIndex];

where myDataContainer for instance is declared as

   class MyApp
            std::vector<MyDataClass> myDataContainer;

>>>> I need to convert the currently selected item from a combo box into a cstring, int, and float.

A combobox contains only strings (and optional an associated data item). The 'data item' is a 32 bit DWORD which can't be converted to a CString or a double as these types have a bigger size. Moreover, you can't store the information what type you actually have as there is only one data item. In times where pointers turn to 64bit pointers by modern compilers, it isn't appropriate to store pointers. Especially as you can't store pointers to native C types where you would have the same problem of not knowing  the pointer type after retrieving with GetItemData. So, the best (or only) way to use the 'item data' is to store an index or handle (32bit integer) to some other container as I showed above. That way you can store the additional type information, e. g. like that:


struct MyData
      char *  szLabel;
      int       datatyp;
      void*   ptrData;    

      {  switch( datatyp)  {
              case CSTRING: delete (CString*)ptrData; break;
              case INTEGER: delete (int*)ptrData; break;
              case FLOAT: delete (float*)ptrData; break; }

    MyData  dataArr[] = { { "entry 1", CSTRING, new CString("any text"), },
                                       { "entry 2", INTEGER, new int(1234), }
                                       { "entry 3", INTEGER, new int(987), }
                                       { "entry 4", CSTRING, new CString("any more text"), },
                                       { "entry 5", FLOAT, new float(123.456), }

    for (int i = 0; i < sizeof(dataArr)/sizeof(dataArr[0]); ++i)
          // AddString returns the combobox index of the add entry which must not be
          // the same as i in case of a sorted combobox
          int idx = myComboBox.AddString(dataArr[i].szLabel);  
          myComboBox.SetItemData(idx, i);

       int intdata = 0;
       CString strdata;
       float floatdat = 0.0;

       int selIdx = myComboBox.GetCurSel();
       if (selIdx >= 0)
             int idx = (int)myComboBox.GetItemData(selIdx );
             MyData & md = dataArr[idx];
             switch( md.datatyp)  
              case CSTRING:  strdata =  *((CString*)md.ptrData); break;
              case INTEGER:  intdata  = *((int*)md.ptrData); break;
              case FLOAT:     floatdata = *((float*)md.ptrData); break; }

Regards, Alex

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now