我需要在这种情况下调用 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
.
我一直在寻找 here 关于 CSimpleStringT::GetBufferSetLength
。
它说:
If you use the pointer returned by
GetBufferSetLength
to change the string contents, call ReleaseBuffer to update the internal state ofCSimpleStringT
before you use any otherCSimpleStringT
methods.The address returned by
GetBufferSetLength
may not be valid after the call to ReleaseBuffer because additionalCSimpleStringT
operations can cause theCSimpleStringT
buffer to be reallocated. The buffer is not reassigned if you do not change the length of theCSimpleStringT
.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 callingSetMenuItemInfo
.