Solved

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

Posted on 2008-06-25
3
3,483 Views
Last Modified: 2013-11-20
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);
0
Comment
Question by:Fippy_Darkpaw
3 Comments
 
LVL 3

Accepted Solution

by:
Darrylsh earned 100 total points
ID: 21869374
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.
0
 
LVL 4

Assisted Solution

by:anmalaver
anmalaver earned 25 total points
ID: 21869420
Hi

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.
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 25 total points
ID: 21890002
>>>> 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:


enum { INTEGER, FLOAT, CSTRING };

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

      ~MyData()
      {  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
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now