有什么方法可以将 CString 以外的对象添加到 MFC 中的 CComboBox 中吗?
Is there any way to add an object other than CString to a CComboBox in MFC?
我正在尝试将具有成员变量 CString
的对象添加到 CCombobox
。我不能只添加字符串,因为我正在尝试与一个工具交互,该工具要求我有另一个成员变量,而不仅仅是一个字符串作为 CComboBox
中的列表项。以下是我正在尝试做的事情。
CComboBox::AddString(myOwnObject);
我只想显示 myOwnObject
的字符串,但要将整个对象放在列表框中,以便其他工具可以访问其他成员变量。
"I think what needs to be done is to override CComboBox::AddString
"
不,恰恰相反,你不覆盖CComboBox::AddString
,
但实施您的 其他对象类型 以获得适当的 conversion operator:
operator const CString& () const { return myCStringMember; }
您可能还想使用 CComboBox::SetItemData()
函数来存储关联的 class 实例的 this
指针。
您可以使用 `CComboBox::AddString()`` 的 return 值,来获取调用
所需的索引
int SetItemData(
int nIndex, // <<< Fill in result of AddString
DWORD_PTR dwItemData
);
应该看起来像这样(假设你已经实现了上面提到的转换运算符):
MyOwnObject myOwnObject("MyOwnObject1");
int newItemIndex = comboBox.AddString(myOwnObject);
if(newItemIndex > 0) {
comboBox.SetItemData(newItemIndex,(DWORD_PTR)&myOwnObject)
}
CComboBox Class wraps a native Combo Box控件。这是一个相当基本的实现,可以满足最常见的用例:显示供用户选择的字符串。
如果您需要额外的功能,您可以使用 CComboBoxEx Class instead. It exposes the full set of operations of the underlying ComboBoxEx 控件。特别是,项目可以配置为在运行时根据任意信息检索项目的字符串表示形式。
以下假设您的自定义项目数据布局如下:
struct CustomItemData {
CStringW m_Name;
int m_SomeInteger;
};
项目数据可以是任意复杂的,并包含您希望存储的任何信息。用项目填充 CComboBoxEx
需要调用 CComboBoxEx::InsertItem, passing an appropriately filled COMBOBOXEXITEM structure:
// CustomItemData's lifetime must exceed that of the CComboBoxEx; don't use a
// stack-based (automatic) variable.
CustomItemData* pcid = new CustomItemData( myName, myInteger );
CCOMBOBOXEXITEM cbei = { 0 };
cbei.mask = CBEIF_TEXT | CBEIF_LPARAM;
cbei.iItem = currentIndex; // The zero-based index of the item.
cbei.pszText = LPSTR_TEXTCALLBACK; // The control will request the information by using
// the CBEN_GETDISPINFO notification codes.
cbei.lParam = reinterpret_cast<LPARAM>( pcid ); // Assign custom data to item.
myComboBox.InsertItem( &cbei );
此时,ComboBox 控件填充了项目,并将向应用程序请求显示信息。 CBEN_GETDISPINFO is sent to the control parent, so the notification handler must be placed into the parent's window (usually a dialog) implementation. The handler is connected to the notification message using the ON_NOTIFY 宏:
// Inside the parent's message map:
ON_NOTIFY( CBEN_GETDISPINFO, IDC_MY_COMBOBOX, GetCBDispString )
// Message handler inside the parent's class
void CMyDlg::GetCBDispString( NMHDR* pNMHDR, LRESULT* pResult ) {
NMCOMBOBOXEX* pncbe = reinterpret_cast<NMCOMBOBOXEX*>( pNMHDR );
COMBOBOXEXITEM& cbei = pncbe->ceItem;
if ( cbei.mask & CBEIF_TEXT ) {
// Text is requested -> fill the appropriate buffer.
const CustomItemData& cd = *reinterpret_cast<const CustomItemData*>( cbei.lParam );
wcscpy( cbei.pszText, cd.m_Name );
// Prevent future callbacks for this item. This is an optional optimization
// and can be used, if the m_Name member doesn't change.
cbei |= CBEIF_DI_SETITEM;
}
// Mark notification as handled
*pResult = 0;
}
有时需要将 CBEN_GETDISPINFO
回调放在自定义 ComboBox 实现中。 MFC 提供了必要的基础结构来实现消息反射(参见 TN062: Message Reflection for Windows Controls)。这允许父 window 将通知消息反映回相应的子控件以进行处理。它有时很有用,但不是实施此问题的解决方案所必需的。
如果您不需要在运行时完全控制显示字符串的构造,您可以使用简单的 CComboBox
控件,并附加调用 CComboBox::SetItemData or CComboBox::SetItemDataPtr, as illustrated in .[= 的附加信息22=]
我正在尝试将具有成员变量 CString
的对象添加到 CCombobox
。我不能只添加字符串,因为我正在尝试与一个工具交互,该工具要求我有另一个成员变量,而不仅仅是一个字符串作为 CComboBox
中的列表项。以下是我正在尝试做的事情。
CComboBox::AddString(myOwnObject);
我只想显示 myOwnObject
的字符串,但要将整个对象放在列表框中,以便其他工具可以访问其他成员变量。
"I think what needs to be done is to override
CComboBox::AddString
"
不,恰恰相反,你不覆盖CComboBox::AddString
,
但实施您的 其他对象类型 以获得适当的 conversion operator:
operator const CString& () const { return myCStringMember; }
您可能还想使用 CComboBox::SetItemData()
函数来存储关联的 class 实例的 this
指针。
您可以使用 `CComboBox::AddString()`` 的 return 值,来获取调用
所需的索引int SetItemData(
int nIndex, // <<< Fill in result of AddString
DWORD_PTR dwItemData
);
应该看起来像这样(假设你已经实现了上面提到的转换运算符):
MyOwnObject myOwnObject("MyOwnObject1");
int newItemIndex = comboBox.AddString(myOwnObject);
if(newItemIndex > 0) {
comboBox.SetItemData(newItemIndex,(DWORD_PTR)&myOwnObject)
}
CComboBox Class wraps a native Combo Box控件。这是一个相当基本的实现,可以满足最常见的用例:显示供用户选择的字符串。
如果您需要额外的功能,您可以使用 CComboBoxEx Class instead. It exposes the full set of operations of the underlying ComboBoxEx 控件。特别是,项目可以配置为在运行时根据任意信息检索项目的字符串表示形式。
以下假设您的自定义项目数据布局如下:
struct CustomItemData {
CStringW m_Name;
int m_SomeInteger;
};
项目数据可以是任意复杂的,并包含您希望存储的任何信息。用项目填充 CComboBoxEx
需要调用 CComboBoxEx::InsertItem, passing an appropriately filled COMBOBOXEXITEM structure:
// CustomItemData's lifetime must exceed that of the CComboBoxEx; don't use a
// stack-based (automatic) variable.
CustomItemData* pcid = new CustomItemData( myName, myInteger );
CCOMBOBOXEXITEM cbei = { 0 };
cbei.mask = CBEIF_TEXT | CBEIF_LPARAM;
cbei.iItem = currentIndex; // The zero-based index of the item.
cbei.pszText = LPSTR_TEXTCALLBACK; // The control will request the information by using
// the CBEN_GETDISPINFO notification codes.
cbei.lParam = reinterpret_cast<LPARAM>( pcid ); // Assign custom data to item.
myComboBox.InsertItem( &cbei );
此时,ComboBox 控件填充了项目,并将向应用程序请求显示信息。 CBEN_GETDISPINFO is sent to the control parent, so the notification handler must be placed into the parent's window (usually a dialog) implementation. The handler is connected to the notification message using the ON_NOTIFY 宏:
// Inside the parent's message map:
ON_NOTIFY( CBEN_GETDISPINFO, IDC_MY_COMBOBOX, GetCBDispString )
// Message handler inside the parent's class
void CMyDlg::GetCBDispString( NMHDR* pNMHDR, LRESULT* pResult ) {
NMCOMBOBOXEX* pncbe = reinterpret_cast<NMCOMBOBOXEX*>( pNMHDR );
COMBOBOXEXITEM& cbei = pncbe->ceItem;
if ( cbei.mask & CBEIF_TEXT ) {
// Text is requested -> fill the appropriate buffer.
const CustomItemData& cd = *reinterpret_cast<const CustomItemData*>( cbei.lParam );
wcscpy( cbei.pszText, cd.m_Name );
// Prevent future callbacks for this item. This is an optional optimization
// and can be used, if the m_Name member doesn't change.
cbei |= CBEIF_DI_SETITEM;
}
// Mark notification as handled
*pResult = 0;
}
有时需要将
CBEN_GETDISPINFO
回调放在自定义 ComboBox 实现中。 MFC 提供了必要的基础结构来实现消息反射(参见 TN062: Message Reflection for Windows Controls)。这允许父 window 将通知消息反映回相应的子控件以进行处理。它有时很有用,但不是实施此问题的解决方案所必需的。
如果您不需要在运行时完全控制显示字符串的构造,您可以使用简单的
CComboBox
控件,并附加调用 CComboBox::SetItemData or CComboBox::SetItemDataPtr, as illustrated in