在 CComboBoxEx 和 ReleaseBuffer 中插入和项目
Posted
技术标签:
【中文标题】在 CComboBoxEx 和 ReleaseBuffer 中插入和项目【英文标题】:Inserting and item into CComboBoxEx and ReleaseBuffer 【发布时间】:2021-10-15 18:19:05 【问题描述】:代码:
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
更好吗?我看到的唯一问题是pszText
是LPWSTR
而GetString
返回LPCWSTR
。如果我应该继续使用GetBuffer
,那么它应该什么时候真正发布呢?在InsertItem
通话之前还是之后?
【问题讨论】:
【参考方案1】:您会一遍又一遍地看到 Windows API 中的一个常见模式:const
-正确的结构比看起来可能的结构要少。毫无疑问,其中一些是疏忽,但不是这个:COMBOBOXEXITEM
用于插入和查询项目的数据。
pszText
成员的文档部分暗示了这一点:
指向包含或接收项目文本的字符缓冲区的指针。如果正在检索文本信息,则必须将此成员设置为将接收文本的字符缓冲区的地址。
遗憾的是,文档中省略了合同的第二部分。设置项的文本时,控件会复制传入的字符串,并且既不会获得指向数据的所有权,也不会修改它。换句话说:当使用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);
【讨论】:
也感谢您的回答和澄清。一个问题......在底层结构中,成员变量设计为LPWSTR pszText
。我应该使用LPWSTR
作为铸造类型吗?由于我使用此代码构建 32 位和 64 位。
这并不完全正确。 COMBOBOXEXITEM
实际上并不存在。它映射到W
或A
变体,具体取决于是否定义了UNICODE
预处理器符号。同样,CString
实际上并不存在。它映射到CStringA
或CStringW
,这取决于一些更复杂的预处理器符号评估。由于您对任一类型都使用通用文本映射,因此 TCHAR*
是正确且兼容的类型。就个人而言,我会使用CStringW
和COMBOBOXEXITEMW
,以及对应的字符串类型wchar_t*
。【参考方案2】:
根据CSimpleStringT::GetBuffer
:
如果你使用
GetBuffer
返回的指针来改变字符串内容,你必须在使用任何其他CSimpleStringT
成员方法之前调用ReleaseBuffer
。
你没有修改字符串,所以你不需要调用ReleaseBuffer
。
但正如你所说,最好使用GetString
,至少你表明你不打算修改它。
【讨论】:
谢谢。因此,简单地使用:cmbItem.pszText = strNumber.GetString();
并删除strNumber.ReleaseBuffer()
应该是可以接受的。我会试试的。
@AndrewTruckle 请注意,ReleaseBuffer
只能在 GetBuffer
之后调用。 GetString
只是给你指向 CString 缓冲区的指针,仅此而已。以上是关于在 CComboBoxEx 和 ReleaseBuffer 中插入和项目的主要内容,如果未能解决你的问题,请参考以下文章