I am trying to initialize MENUITEMINFO for a call to InsertMenuItem. When trying to assign a const string to dwTypeData, I get an error. The code below is from MSDN samples.
I get an error for both types of assignment
mii.dwTypeData = "&Sample text";
mii.dwTypeData = L"&Sample text";
I am using Visual Studio 2019.
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.wID = idCmdFirst + IDM_DISPLAY;
mii.fType = MFT_STRING;
mii.dwTypeData = L"&Sample Text";
mii.fState = MFS_ENABLED;
if (!InsertMenuItem(hMenu, indexMenu, TRUE, &mii))
{
return HRESULT_FROM_WIN32(GetLastError());
}
The error is Error (active) E0144 a value of type "const wchar_t *" cannot be used to initialize an entity of type "wchar_t *"
According Microsoft documentation, the second one should work. https://docs.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings
Edit: This is not solved by I cannot initializate WCHAR because I cannot change the type as suggested in that answer.
Some Windows structs are used to both "Get and Set" and string members in these structs point to mutable strings. This is in direct conflict with the compiler/linker settings that store strings literals in read-only memory.
It is theoretically unsafe to use a string literal with the setter function because it might write to the string (and then restore it back to its original content).
The only known place where this happens is the command line parameter in CreateProcessW
.
In all other places you can probably just cast away const:
MENUITEMINFO mii = { sizeof(mii) };
mii.dwTypeData = const_cast<LPTSTR>(TEXT("&Sample Text"));
Be careful! As Lightness Races in Orbit points out, modifying the data you pass could be a problem down the road. Try this, instead:
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.wID = idCmdFirst + IDM_DISPLAY;
mii.fType = MFT_STRING;
wchar_t text[] = L"&Sample Text";
mii.dwTypeData = text;
mii.fState = MFS_ENABLED;
This way, you should be a wee bit safer - but not completely!! As RbMm points out, it is far better as a general rule to have the dwTypeData
member pointing to a static character array. Somewhere (outside) the function …
static thread_local wchar_t menuText[MAXTEXTLEN];
Then, set up mii with …
wcscpy(menuText, L"&Sample Text");
mii.dwTypeData = menuText;
mii.cch = MAXTEXTLEN; // But not used in this case!
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