【问题标题】:Are there any Win32 functions I can use to get the count / itemdata from a CComboBoxEx control?是否有任何 Win32 函数可用于从 CComboBoxEx 控件获取计数/项目数据?
【发布时间】:2021-11-23 19:33:34
【问题描述】:

我的父对话框有一个CComboBoxEx 控件(映射到一个名为CDatesComboBoxEx 的派生类)。

在应用程序的一部分中,此对话框显示一个弹出模式对话框。而且,在模态对话框中,它需要访问日期组合中的信息。

我决定做的(效果很好)是在弹出对话框的构造函数中传递我的组合地址。所以我现在可以执行以下操作:

  • m_pComboDates->GetCount()
  • m_pComboDates->GetItemDataPtr(i)

我想知道这里有没有办法使用本机 Win32 代码?

  • 我们可以访问父母句柄 (GetParent()->GetSafeHWnd())。
  • 我们知道父对话框上控件的 ID (IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING)。

那么有没有可能以某种方式直接获取计数和商品数据?


我知道有这些宏:

但是:

  1. 这些宏可以与CComboBoxEx 控件一起使用吗?还有...
  2. 鉴于我之前描述的上下文,我们如何在组合中获得 HWND

实际上,我想我误解了那些“宏”的目的。我可以像这样得到组合句柄:

HWND hDatesCombo = ::GetDlgItem(
    GetParent()->GetSafeHwnd(), IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING);

但是,ComboBox_GetCount 不返回值。其他人也不行。所以我有点困惑。


根据答案,这点现在很好:

HWND hDatesCombo = ::GetDlgItem(GetParent()->GetSafeHwnd(), IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING);
int iNumDates = static_cast<int>(::SendMessage(hDatesCombo, CB_GETCOUNT, 0, 0));

在我的for 循环中,我正在这样做:

LRESULT itemData = ::SendMessage(hDatesCombo, CB_GETITEMDATA, static_cast<WPARAM>(i), 0);
auto* pEntry = static_cast<CChristianLifeMinistryEntry*>((LPVOID)itemData);

这是我能找到的唯一施放方法。如果我尝试static_cast&lt;LPVOID&gt;,它也不会工作。

【问题讨论】:

  • ComboBox_GetCount 返回一个值。这是损坏的文档。当您信任 .NET 开发人员生成本机平台 API 文档时,这就是您所得到的。 每个预处理器宏的文档都被破坏到无用的地步。非常感谢你,微软。
  • 尝试GetOwner() 而不是GetParent()。另外,您是否在弹出对话框的构造函数中传递了主对话框? CPopupMyDlg dlg(this) ComboBoxEx 是从 ComboBox 派生的,所以所有的函数/消息/宏都应该是一样的。这些宏的“目的”只是为了方便,它们只是发送正确的消息。
  • 最后一点:为什么要将 C 风格转换与 C++ 转换结合起来?不,您不能使用static_castLRESULT 获取指针,但您可以只使用reinterpret_cast&lt;CChristianLifeMinistryEntry*&gt;(itemData)。这将有效地使用 C 风格的演员表,但在你的代码中(如果你需要的话)追踪 reinterpret_cast 比去寻找 C 风格的演员表要容易得多。
  • 我只是惊呆了,它警告使用 reinterpret_cast不是关于使用 C 样式转换。在您的情况在您的链接文档中给出的示例中,您将必须使用其中一个。
  • 您有什么理由不去查看 MFC 源代码吗? MFC 所做的只是最终访问 Win32 API。如果您查看 MFC 源代码,您将看到使用 WIN32 调用所需的所有内容。

标签: winapi visual-c++ mfc ccombobox


【解决方案1】:

我想知道这里是否可以使用本机 Win32 代码?

是的,有。 SendMessage 函数(及其返回值)正是您所需要的……

获得组合框的HWND 后,您可以发送CB_GETCOUNT message 询问它包含多少项:

HWND hDatesCombo = ::GetDlgItem(GetParent()->GetSafeHwnd(), IDC_COMBOBOXEX_OCLM_WEEK_OF_MEETING);
LRESULT nItems = ::SendMessage(hDatesCombo, CB_GETCOUNT, 0, 0);

并且,要获取与特定条目关联的项目数据,请发送CB_GETITEMDATA 消息,并将相关项目的(从零开始的)索引作为wParam 参数:

//...
LRESULT *ItemData = new LRESULT[static_cast<size_t>(nItems)];
for (int i = 0; i < nItems; ++i) {
    ItemData[i] = ::SendMessage(hDatesCombo, CB_GETITEMDATA, static_cast<WPARAM>(i), 0);
}
//...
delete[] ItemData; // When you're done with the data list

当然,如果您的项目数据是指针(例如,如果您有一个带有 1CBS_HASSTRINGS 样式的所有者绘制的组合),则需要修改第二个代码 sn-p因此,在必要时添加相关的reinterpret_cast 操作。 (注意LRESULTWPARAM 类型都被定义为适合存储指针。)


1 链接的 M/S 文档页面对于这是否适用于所有者绘制的组合 with不带 @ 有点模糊987654335@风格。

【讨论】:

  • 谢谢。 但是这是否适用于 CComboBoxEx 控件?我尝试了您的 CB_GETCOUNT 代码作为开始,它返回 0。所以我不确定这些宏是否与 CComboBoxEx 兼容。
  • 我在这里看到了类似的讨论stackoverflow.com/q/51071401/2287576
  • 假设你是对的,我们如何才能从弹出窗口中的位置到达GetComboBoxCtrl
  • CComboBoxEx 使用 SetItem 等。但它确实有我正在使用的方法。
  • 查看 MFC 标头/源代码,我发现 CComboBoxEx()GetCount() 成员基本上就是这样的:return (int)::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0);。 (加上IsWindow() 检查。)所以,不明白为什么我建议的代码不起作用。 [[ CComboBoxEx 不会覆盖其基础CComboBoxGetCount() 成员。 ]]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
相关资源
最近更新 更多