C++ 在MFC中,有没有办法将CString以外的对象添加到CComboBox中?

C++ 在MFC中,有没有办法将CString以外的对象添加到CComboBox中?,c++,mfc,overriding,controls,ccombobox,C++,Mfc,Overriding,Controls,Ccombobox,我试图将一个具有成员变量CString的对象添加到cmbobox中。我不能只添加字符串,因为我正在尝试与一个工具接口,该工具要求我拥有另一个成员变量,而不仅仅是一个字符串作为cmbobox中的列表项。下面是我想做的 CComboBox::AddString(myOwnObject); 我只想显示myOwnObject的字符串,但要使整个对象位于listbox中,以便其他工具可以访问其他成员变量 我认为需要做的是重写CmboBox::AddString 不,反过来说,您不重写ECCOMBOX::

我试图将一个具有成员变量CString的对象添加到cmbobox中。我不能只添加字符串,因为我正在尝试与一个工具接口,该工具要求我拥有另一个成员变量,而不仅仅是一个字符串作为cmbobox中的列表项。下面是我想做的

CComboBox::AddString(myOwnObject);
我只想显示myOwnObject的字符串,但要使整个对象位于listbox中,以便其他工具可以访问其他成员变量

我认为需要做的是重写CmboBox::AddString

不,反过来说,您不重写ECCOMBOX::AddString, 但实现其他对象类型以具有适当的:

您可能还想使用该函数来存储关联类实例的this指针

您可以使用'CComboBox::AddString`的返回值来获取调用所需的索引

int SetItemData( 
    int nIndex, // <<< Fill in result of AddString
    DWORD_PTR dwItemData  
 );
我认为需要做的是重写CmboBox::AddString

不,反过来说,您不重写ECCOMBOX::AddString, 但实现其他对象类型以具有适当的:

您可能还想使用该函数来存储关联类实例的this指针

您可以使用'CComboBox::AddString`的返回值来获取调用所需的索引

int SetItemData( 
    int nIndex, // <<< Fill in result of AddString
    DWORD_PTR dwItemData  
 );
包装本机控件。它是一个相当基本的实现,满足最常见的用例:显示字符串供用户选择

如果需要其他功能,可以使用。它公开了基础控件的完整操作集。特别是,可以将项配置为在运行时基于任意信息检索项的字符串表示形式

以下假设您的自定义项数据布局如下:

struct CustomItemData {
    CStringW m_Name;
    int m_SomeInteger;
};
项目数据可以是任意复杂的,并且包含您希望存储的任何信息。使用项填充CComboxex需要调用并传递适当填充的:

此时,ComboBox控件将填充项目,并将从应用程序请求显示信息。将发送到控件父级,因此必须将通知处理程序放置在父级窗口中,通常是一个对话框实现。处理程序使用宏连接到通知消息:

有时需要将CBEN_GETDISPINFO回调放在自定义ComboBox实现中。MFC提供了实现消息反射所需的基础设施,请参见。这允许父窗口将通知消息反射回相应的子控件进行处理。它有时可能有用,但不需要实现此问题的解决方案

如果您不需要在运行时完全控制构建显示字符串,可以使用简单的cmbobox控件,并附加额外的信息调用或,如中所示。

包装本机控件。它是一个相当基本的实现,满足最常见的用例:显示字符串供用户选择

如果需要其他功能,可以使用。它公开了基础控件的完整操作集。特别是,可以将项配置为在运行时基于任意信息检索项的字符串表示形式

以下假设您的自定义项数据布局如下:

struct CustomItemData {
    CStringW m_Name;
    int m_SomeInteger;
};
项目数据可以是任意复杂的,并且包含您希望存储的任何信息。使用项填充CComboxex需要调用并传递适当填充的:

此时,ComboBox控件将填充项目,并将从应用程序请求显示信息。将发送到控件父级,因此必须将通知处理程序放置在父级窗口中,通常是一个对话框实现。处理程序使用宏连接到通知消息:

有时需要将CBEN_GETDISPINFO回调放在自定义ComboBox实现中。MFC提供了实现消息反射所需的基础设施,请参见。这允许父窗口将通知消息反射回相应的子控件进行处理。它有时可能有用,但不需要实现此问题的解决方案


如果您不需要在运行时完全控制构建显示字符串,可以使用简单的cmbobox控件,并附加额外的信息调用,或者,如中所示。

我考虑过这样做,但这不就是去掉字符串,而不是将整个对象添加到列表中吗,在这里使用点运算符和强制转换有什么区别?@Jameswr.11我不理解你的问题。你可能应该在你的帖子中给出一个代码示例,以澄清你想做什么。我重写了这个问题。基本上,有吗
是否可以将整个对象添加到ccombobox中,但仍然只显示该对象的字符串成员变量?@Jameswr.11您的问题没有太大改进,对不起。我想过这样做,但这不就是去掉字符串,而不是将整个对象添加到列表中吗?还有,在这里使用点运算符和强制转换有什么区别?@Jameswr.11我不理解你的问题。你可能应该在你的帖子中给出一个代码示例,以澄清你想做什么。我重写了这个问题。基本上,是否有任何方法可以将整个对象添加到cmbobox,但仍然只显示该对象的字符串成员变量?@Jameswr.11您的问题没有太大改进,抱歉。
// 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 );
// 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;
}