Jump to content
  • Advertisement
Sign in to follow this  
Defend

String issues and MENUITEMINFO

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Defend
It 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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!