Andrew Truckle
Andrew Truckle

Reputation: 19207

Do I need to call ReleaseBuffer in this context?

I have been looking here about CSimpleStringT::GetBufferSetLength.

It says:

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.

I am actually using CString but given this code:

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();

Since I do not modify the underlying data it seems I do not need to call ReleaseBuffer. Correct?

Upvotes: 0

Views: 364

Answers (1)

IInspectable
IInspectable

Reputation: 51511

Short answer: No.

The longer answer is: Don't call GetBuffer/GetBufferSetLength either. Call GetString instead. It will return a pointer to the immutable sequence of characters. This requires a const_cast as well, i.e.

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

This is due to the fact that MENUITEMINFO is used both for setting menu items, as well as reading information back. Since C doesn't allow you to specify transitive constness, the structure is forced to use non-const data members, even when the pointed-to data is never changed. The const_cast is both required as well as safe.

Also note that setting the cch member is not required. As the documentation explains:

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

Upvotes: 3

Related Questions