将项目插入 CComboBoxEx 和 ReleaseBuffer

Inserting and item into CComboBoxEx and ReleaseBuffer

代码:

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

我的问题是:

在这种情况下使用 GetString 而不是 GetBuffer 更好吗?我看到的唯一问题是 pszTextLPWSTRGetString returns LPCWSTR。如果我应该继续使用 GetBuffer 那么它应该什么时候真正发布?在 InsertItem 调用之前还是之后?

根据CSimpleStringT::GetBuffer

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before you use any other CSimpleStringT member methods.

您没有修改字符串,因此不需要调用 ReleaseBuffer

但是正如你所说,最好使用GetString,至少你表明你不打算修改它。

Windows API 中有一个常见的模式,您会一遍又一遍地看到:const 的结构不如看起来可能的结构正确。毫无疑问,其中一些是疏忽,但不是这个:COMBOBOXEXITEM 用于插入和查询项目的数据。

pszText 成员的文档中部分暗示了这一点:

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.

遗憾的是,文档中省略了合同的第二部分。设置项的文本时,控件会复制传入的字符串,既不会取得指向数据的所有权,也不会修改它。换句话说:当使用COMBOBOXEXITEM结构插入一个项时,可以假定所有指针都指向const.

接下来,传递从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);
}