This topic is 2968 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

VC++2008, Win32, Directx9

I'm trying to build a menu dynamically in run-time, based on available video resolutions.

The MENUITEMINFO struct needs a LPWSTR for its dwTypeData. Not a LPCWSTR, but LPWSTR.

I have a line of strings and ints that I can turn into a wstring without hassle, but from there I'm just not sure.

        cout << i << ":  " << painterBBSizes.cx << "x" << painterBBSizes.cy << endl;        MENUITEMINFO        mitemInfo;        std::wstringstream   labelStream;        std::wstring         label;        labelStream << painterBBSizes.cx << " x " << painterBBSizes.cy;        label = labelStream.str();        LPTSTR dest = CT2W(label.c_str());        ERRORPOP(label.c_str());  // Outputs correctly.        ERRORPOP(dest);  // Outputs gibberish.               mitemInfo.cbSize        = sizeof(MENUITEMINFO);        mitemInfo.fMask         = MIIM_TYPE|MIIM_ID|MIIM_DATA;        mitemInfo.fType         = MFT_STRING;        mitemInfo.fState        = NULL;        mitemInfo.wID           = ID_END_THEGREATESTID + 1 + i;        mitemInfo.hSubMenu      = NULL;        mitemInfo.hbmpChecked   = NULL;        mitemInfo.hbmpUnchecked = NULL;        mitemInfo.dwItemData    = NULL;        mitemInfo.dwTypeData    = dest;      // Outputs the same gibberish.                mitemInfo.cch           = sizeof(dest);                  InsertMenuItem(g_menu, ID_END_THEGREATESTID, false, &mitemInfo);

The result is gibberish.
ERRORPOP() requires a LPCWSTR.

Anyone see the problem? Cheers.

##### Share on other sites
Your use of the CT2W macro is the problem. CT2W converts narrow C strings to wide strings, whereas you're handing it a wide string already (std::wstring).

##### Share on other sites
I thought CT2W was effectively the same as CW2W here, which is supposed to convert a wide to a wide, yes, but simply output a non-const LPWSTR. Unless I'm mistaken on the difference between wide and narrow strings.

Anyway, do you have a possible solution you could offer?

Man I hate strings. Ascii strings, char strings, wide strings, tstrings, LPSTR, LPWSTR, LPCWSTR... arrrgh. All this stuff is supposed to make it simpler yet here I am simply trying to make an int appear in text. But no, I have to waste a day dealing with the fact that Microsoft needs a non-const LPWSTR.

Is there not a simple way to take a LPCWSTR string and copy its contents to a new LPWSTR?

Strings. >_<

##### Share on other sites
Just allocate a buffer (using std::vector is probably the simplest way), copy the string bytes into it (not neglecting the terminator bytes), and then pass that buffer instead of your std::wstring.

##### Share on other sites
Thanks for that, I'll give it a try once home.

I did find that simply giving the address of myString worked before (I didn't check the output though), but I wasn't comfortable with throwing array addresses around like that. A vector crossed my mind but I wasn't sure of any of this.

It bugs me that in 2010 we're still throwing buffers around to manage strings. -_- I thought we were past all that.

##### Share on other sites
Quote:
 Original post by DefendIt bugs me that in 2010 we're still throwing buffers around to manage strings. -_- I thought we were past all that.

C++ is past that. A lot of the Win32 API code has been around since Win95 (and some of it before that).

##### Share on other sites
I found too many ways to copy string contents to a vector. This seems the best, so I thought I'd chuck it here and see if anyone wants to confirm or reject that. So does this look like a perfectly good way to turn an int + text into a non-const LPTSTR? Cheers.

        tstringstream       labelStream;        tstring             label;        labelStream     << painterBBSizes.cx << " x etc..";        label           = labelStream.str();            std::vector<TCHAR> dest(label.begin(), label.end());        dest.push_back('\0');                       // Null terminate the string.

And here's the whole for loop I'm using, if anyone wants to glance at it.
[source=c++]    for (UINT i = 0; i < painterBBSizes.size(); i++)     {        MENUITEMINFO        mitemInfo;        tstringstream       labelStream;        tstring             label;        labelStream     << painterBBSizes.cx << " x " << painterBBSizes.cy;        label           = labelStream.str();            std::vector<TCHAR> dest(label.begin(), label.end());        dest.push_back('\0');                       // Null terminate the string.               mitemInfo.cbSize        = sizeof(MENUITEMINFO);        mitemInfo.fMask         = MIIM_TYPE|MIIM_ID|MIIM_DATA;        mitemInfo.fType         = MFT_STRING;        mitemInfo.fState        = NULL;        mitemInfo.wID           = ID_END_THEGREATESTID + 1 + i;        mitemInfo.hSubMenu      = NULL;        mitemInfo.hbmpChecked   = NULL;        mitemInfo.hbmpUnchecked = NULL;        mitemInfo.dwItemData    = NULL;                  mitemInfo.dwTypeData    = &dest[0];         // LPTSTR == TCHAR*. Must be a null terminated,        mitemInfo.cch           = dest.size();      // non-const string. cch size includes the \0.        mitemInfo.hbmpItem      = NULL;            InsertMenuItem(g_menu, ID_END_THEGREATESTID, false, &mitemInfo);    }

##### Share on other sites
Looks fine to me [smile]

##### Share on other sites
Cheers for the help too.

I realised I can just use << ends; instead of push_back('\0') for that null termination too.

1. 1
Rutin
37
2. 2
3. 3
4. 4
5. 5

• 11
• 10
• 13
• 104
• 11
• ### Forum Statistics

• Total Topics
632979
• Total Posts
3009682
• ### Who's Online (See full list)

There are no registered users currently online

×