c++ - 有什么方法可以将 CString 以外的对象添加到 MFC 中的 CComboBox 中吗?

标签 c++ mfc overriding controls ccombobox

我正在尝试将具有成员变量 CString 的对象添加到 CCombobox。我不能只添加字符串,因为我正在尝试与一个工具交互,该工具要求我有另一个成员变量,而不仅仅是一个字符串作为 CComboBox 中的列表项。以下是我正在尝试做的事情。

CComboBox::AddString(myOwnObject);

我只想显示 myOwnObject 的字符串,但要将整个对象放在列表框中,以便其他工具可以访问其他成员变量。

最佳答案

CComboBox Class包装原生 Combo Box控制。这是一个相当基本的实现,可以满足最常见的用例:显示供用户选择的字符串。

如果您需要额外的功能,您可以使用 CComboBoxEx Class反而。它公开了底层的全套操作 ComboBoxEx控制。特别是,项目可以配置为根据任意信息在运行时检索项目的字符串表示形式。

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

struct CustomItemData {
    CStringW m_Name;
    int m_SomeInteger;
};

项目数据可以任意复杂,并包含您希望存储的任何信息。用项目填充 CComboBoxEx 需要调用 CComboBoxEx::InsertItem ,传递一个适当填充的 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被发送到控件 parent,因此通知处理程序必须放在父窗口(通常是对话框)的实现中。处理程序使用 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 )。这允许父窗口将通知消息反射(reflect)回相应的子控件以供处理。它有时很有用,但不是实现此问题的解决方案所必需的。


如果您不需要在运行时完全控制显示字符串的构造,您可以使用简单的CComboBox 控件,并附加附加信息调用CComboBox::SetItemDataCComboBox::SetItemDataPtr ,如 πάντα ῥεῖ's answer 中所示.

关于c++ - 有什么方法可以将 CString 以外的对象添加到 MFC 中的 CComboBox 中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30534319/

相关文章:

c++ - 在 std::remainder() 调用 double 后检测到零

c++ - 在 DirectX、C++ 中映射缓冲区

c++ - 用于测量延迟的计时器

java - OOP 继承扩展

c++ - vector 初始化的 vector

c++ -::PostMessage 在我切换到另一个程序时不起作用

mfc - 使用不受信任的格式字符串安全地调用 strftime

winapi - 支持 ARM 上的 Windows 10 桌面应用程序 - MFC 和 COM 以及 OPOS 工作吗?

c++ - C++ 协方差/覆盖/循环问题

c# - new 和 override 的区别?