如何从常量字符串初始化 LPWSTR?

How to initialize LPWSTR from a const string?

本文关键字:初始化 LPWSTR 字符串 常量      更新时间:2023-10-16

我正在尝试初始化MENUITEMINFO以调用InsertMenuItem。尝试将常量字符串分配给 dwTypeData 时,出现错误。下面的代码来自 MSDN 示例。

两种类型的分配都出错

mii.dwTypeData = "&Sample text";
mii.dwTypeData = L"&Sample text";

我正在使用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());
}

错误是 错误(活动(E0144 类型为"const wchar_t *"的值不能用于初始化类型为"wchar_t *"的实体

根据文档Microsoft,第二个应该可以工作。 https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings

编辑:我无法初始化WCHAR无法解决此问题,因为我无法按照该答案中的建议更改类型。

某些 Windows 结构用于"获取和设置",这些结构中的字符串成员指向可变字符串。这与将字符串文本存储在只读内存中的编译器/链接器设置直接冲突。

从理论上讲,将字符串文本与 setter 函数一起使用是不安全的,因为它可能会写入字符串(然后将其恢复到其原始内容(。

发生这种情况的唯一已知位置是CreateProcessW中的命令行参数。

在所有其他地方,您可能可以抛弃 const:

MENUITEMINFO mii = { sizeof(mii) };
mii.dwTypeData = const_cast<LPTSTR>(TEXT("&Sample Text"));

小心!正如Lightness Races in Orbit指出的那样,修改你传递的数据可能是一个问题。试试这个,改为:

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;

这样,你应该更安全一点 - 但不是完全!!正如RbMm指出的那样,作为一般规则,让dwTypeData成员指向静态字符数组要好得多。某处(外部(功能...

static thread_local wchar_t menuText[MAXTEXTLEN];

然后,使用 ...

wcscpy(menuText, L"&Sample Text");
mii.dwTypeData = menuText;
mii.cch = MAXTEXTLEN; // But not used in this case!