Reputation: 19157
Code:
m_cbReminderInterval.ResetContent();
for (int i = 1; i <= m_iMaxReminderInterval; i++)
{
COMBOBOXEXITEM cmbItem = {};
CString strNumber;
strNumber.Format(_T("%d"), i);
cmbItem.mask = CBEIF_TEXT;
cmbItem.iItem = static_cast<INT_PTR>(i) - 1;
cmbItem.pszText = strNumber.GetBuffer(_MAX_PATH);
strNumber.ReleaseBuffer(); // TODO: When should I release the buffer - NOW or AFTER the InsertItem call?
m_cbReminderInterval.InsertItem(&cmbItem);
}
My question is:
Is it better to use GetString
instead of GetBuffer
in this context? The only issue I see is that pszText
is LPWSTR
whereas GetString
returns LPCWSTR
. If I should continue to use GetBuffer
then when should it actually be released? Before or after the InsertItem
call?
Upvotes: 2
Views: 149
Reputation: 51479
There's a common pattern in the Windows API you'll see over and over again: Structures that are less const
-correct than what would appear to be possible. Undoubtedly, some of them are oversights, but not this one: COMBOBOXEXITEM
is used both to insert and query an item's data.
This is hinted to, in part, in the documentation for the pszText
member:
A pointer to a character buffer that contains or receives the item's text. If text information is being retrieved, this member must be set to the address of a character buffer that will receive the text.
The second part of the contract is omitted from the documentation, sadly. When setting an item's text, the control makes a copy of the string passed in, and neither takes ownership over the pointed to data, nor modifies it. In other words: When using the COMBOBOXEXITEM
structure to insert an item, all pointers can be assumed to point to const
.
Following that, it is perfectly valid to pass the pointer received from GetString()
:
for (int i = 1; i <= m_iMaxReminderInterval; i++)
{
COMBOBOXEXITEM cmbItem = {};
CString strNumber;
strNumber.Format(_T("%d"), i);
cmbItem.mask = CBEIF_TEXT;
cmbItem.iItem = static_cast<INT_PTR>(i) - 1;
cmbItem.pszText = const_cast<TCHAR*>(strNumber.GetString());
m_cbReminderInterval.InsertItem(&cmbItem);
}
Upvotes: 4
Reputation: 11311
According to CSimpleStringT::GetBuffer
:
If you use the pointer returned by
GetBuffer
to change the string contents, you must callReleaseBuffer
before you use any otherCSimpleStringT
member methods.
You are not modifying the string, so you don't need to call ReleaseBuffer
.
But as you said, it's better to use GetString
, at least you indicate your intent to NOT modify it.
Upvotes: 1