Newbie in world of MFC and MS Windows C .
I am trying to populate a ComboBox dynamically. But I am not able to convert the iterator pointer to CString or an std::string. Here is my sample code:
bool single_digit (const int& value) { return (value >= 60); }
int numArr[] = {10,20,30,40};
int size = sizeof(numArr)/sizeof(numArr[0]);
std::list<int> numList (numArr, numArr size);
numList.remove_if(single_digit);
for(std::list<int>::iterator it=numList.begin(); it!=numList.end(); it)
{
std::cout << ' ' <<*it;
/*
std::string s2(*it); //Not sure of conversion to CString or std::string.
string *pelement = &*it;
*/
//End goal: _ccomboBoxnumType.AddString(*it);
}
Can anyone please suggest any other STL to satisfy this requirement?
CodePudding user response:
This is essentially asking how to convert an integer to its string representation. The simplest way to go about this is to call std::to_wstring, that provides an overload taking an int value.
The following code does what you're looking for:
for(std::list<int>::iterator it=numList.begin(); it!=numList.end(); it)
{
// Get value by dereferencing the iterator
int value = *it;
// Convert integer to string
std::wstring display = std::to_wstring(value);
// Extract a C-style string pointer compatible with the interface
wchar_t const* ptr = display.c_str();
_ccomboBoxnumType.AddString(ptr);
}
Of course, you should be using a range-based for loop instead, i.e.
for(auto value : numList)
{
_ccomboBoxnumType.AddString(std::to_wstring(value).c_str());
}
In case this doesn't compile make sure to set the character set to Unicode in the project settings. There's no reason not to.
Update to account for the C 98 requirement
std::to_wstring requires C 11. If that is not something that's available to you, you can get the same functionality through e.g. MFC's CString type by using its Format member. Things get slightly more verbose, but not much:
for(std::list<int>::iterator it=numList.begin(); it!=numList.end(); it)
{
// Get value by dereferencing the iterator
int value = *it;
// Convert integer to CString
CString display;
display.Format(_T("%d"), value);
// CString can implicitly be converted to LPCTSTR
// If you like explicit, pass `display.GetString()` instead
_ccomboBoxnumType.AddString(display);
}
Note that this is using generic-text mappings (in disguise), a holdover from the days when targeting both Windows NT and Windows 9x was relevant. It is not recommended today, but should fit right in to a code base that requires a C 98 compiler.
A few recommendations to follow:
- A
std::listhas unique properties (such as constant time insertion and splicing), at the expense of having to allocate each element on the heap. Since you don't care about any of this, use astd::vectorinstead. - If you need to get the integer value back (e.g. in response to user input) you can store that value inside the Combo Box item. There's
CComboBox::SetItemDatafor that. Alternatively use aCComboBoxExinstead, and set both the text and data in one go by callingCComboBoxEx::InsertItem. - Another approach would be setting the item data only, and request the control to retrieve a string representation on demand. That, too, requires using a
CComboBoxExand settingpszTexttoLPSTR_TEXTCALLBACKin theInsertItemcall. The control parent is now responsible for handling theCBEN_GETDISPINFOnotification, producing a string representation for the given item.
CodePudding user response:
Easy one.
std::string s2 = std::to_string(*it);
Seems your code could be a lot simpler though, there is no need to construct a list
for (int i : numArr)
{
std::string s2 = std::to_string(i);
...
}
