关于c ++:如何从const字符串初始化LPWSTR?

How to initialize LPWSTR from a const string?

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

两种类型的作业我都遇到错误

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

我正在使用Visual Studio 2019。

1
2
3
4
5
6
7
8
9
10
  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://docs.microsoft.com/zh-cn/windows/win32/learnwin32/working-with-strings

编辑:这不能通过我无法初始化WCHAR来解决,因为我无法按照该答案中的建议更改类型。


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

从理论上讲,在setter函数中使用字符串文字是不安全的,因为它可能会写入字符串(然后将其还原回其原始内容)。

唯一发生此情况的地方是CreateProcessW中的命令行参数。

在所有其他地方,您可能只丢弃const:

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


小心!正如"轨道中的竞速比赛"所指出的那样,修改您传递的数据可能是一个难题。试试这个,代替:

1
2
3
4
5
6
7
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成员指向静态字符数组作为一般规则要好得多。函数的某处(外部)…

1
static thread_local wchar_t menuText[MAXTEXTLEN];

然后,用...设置mii。

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