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::list
has 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::vector
instead. - 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::SetItemData
for that. Alternatively use aCComboBoxEx
instead, 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
CComboBoxEx
and settingpszText
toLPSTR_TEXTCALLBACK
in theInsertItem
call. The control parent is now responsible for handling theCBEN_GETDISPINFO
notification, 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);
...
}