I have the following block of code:
for( CarsPool::CarRecord &record : recs->GetRecords())
{
LVITEM item;
item.mask = LVIF_TEXT;
item.cchTextMax = 6;
item.iSubItem = 0;
item.pszText = (LPSTR)(record.getCarName().c_str()); //breakpoint on this line.
item.iItem = 0;
ListView_InsertItem(CarsListView, &item);
item.iSubItem = 1;
item.pszText = TEXT("Available");
ListView_SetItem(CarsListView, &item);
item.iSubItem = 2;
item.pszText = (LPSTR)CarsPool::EncodeCarType(record.getCarType());
ListView_SetItem(CarsListView, &item);
}
The information from Visual Studio Debugger is here:
Why isn't the program able to read the characters from string?
A test has shown me that it works in this way:
MessageBox(hWnd, (LPSTR)(record.getCarName().c_str()), "Test", MB_OK);
getCarName
likely returns a temporary. After the assignment the temporary object is destroyed and the pointer item.pszText
points to invalid memory. You must ensure that the string object is valid during the call to ListView_InsertItem
.
std::string text(record.getCarName());
item.iSubItem = 0;
item.pszText = const_cast<LPSTR>(text.c_str());
item.iItem = 0;
ListView_InsertItem(CarsListView, &item);
The const_cast
is an artifact of the fact that the Windows API uses the same structure to set and retrieve information. When invoking ListView_InsertItem
the structure is immutable, however there is no way to reflect that in the language.
It looks like you're trying to use the value of a C++ "string" in a C/Win32 call.
stdstring.c_str() is the correct way to do it.
... BUT ...
You should strcpy() the string to a temp variable, then make the Win32 call with the temp variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With