我需要在这种情况下调用 ReleaseBuffer 吗?

Do I need to call ReleaseBuffer in this context?

我一直在寻找 here 关于 CSimpleStringT::GetBufferSetLength

它说:

If you use the pointer returned by GetBufferSetLength to change the string contents, call ReleaseBuffer to update the internal state of CSimpleStringT before you use any other CSimpleStringT methods.

The address returned by GetBufferSetLength may not be valid after the call to ReleaseBuffer because additional CSimpleStringT operations can cause the CSimpleStringT buffer to be reallocated. The buffer is not reassigned if you do not change the length of the CSimpleStringT.

The buffer memory is automatically freed when the CSimpleStringT object is destroyed.

我实际上使用的是 CString 但给定此代码:

CString strHostLabel = dlgLabels.GetTrimmedHostLabel();
CString strCoHostLabel = dlgLabels.GetTrimmedCoHostLabel();

MENUITEMINFO sInfo{};
sInfo.cbSize = sizeof(MENUITEMINFO);
sInfo.fMask = MIIM_STRING;
sInfo.cch = strHostLabel.GetLength();
sInfo.dwTypeData = strHostLabel.GetBufferSetLength(sInfo.cch);
SetMenuItemInfo(pMnuSwap->GetSafeHmenu(), SwapAssignment::Host, TRUE, &sInfo);
sInfo.cch = strCoHostLabel.GetLength();
sInfo.dwTypeData = strCoHostLabel.GetBufferSetLength(sInfo.cch);
SetMenuItemInfo(pMnuSwap->GetSafeHmenu(), SwapAssignment::Cohost, TRUE, &sInfo);
strHostLabel.ReleaseBuffer();
strCoHostLabel.ReleaseBuffer();

因为我没有修改基础数据,所以我似乎不需要调用 ReleaseBuffer。正确吗?

简答:否

较长的答案是:也不要调用 GetBuffer/GetBufferSetLength。请改为调用 GetString。它将 return 指向不可变字符序列的指针。这也需要 const_cast,即

sInfo.dwTypeData = const_cast<TCHAR*>(strHostLabel.GetString());

这是因为 MENUITEMINFO 既用于设置菜单项,也用于读取信息。由于 C 不允许您指定传递常量,因此结构被迫使用非常量数据成员,即使指向的数据永远不会更改。 const_cast 既是必需的又是安全的。

另请注意,不需要设置 cch 成员。正如 documentation 解释的那样:

[...] cch is ignored when the content of a menu item is set by calling SetMenuItemInfo.