【问题标题】:GetDlgItem() returns invalid handle in vc++ 2019 for a project build on 2008GetDlgItem() 在 vc++ 2019 中为 2008 年构建的项目返回无效句柄
【发布时间】:2022-01-11 08:45:54
【问题描述】:

我最近将一个 Visual Studio 8.0 项目转换为 Visual Studio 2019,但在某些项目上调用 GetDlgItem 时遇到问题。以下代码失败。

PPOtypeComboHndl[0] = GetDlgItem(Hndl, IDC_PPO_TYPE1);
assert(PPOtypeComboHndl[0] != NULL);
LOG_INFO() << "PPOtypeComboHndl Hndl value is " << PPOtypeComboHndl[0];

000000 中记录的值似乎不正确。

我在调用上述代码的表单的资源文件中看到此代码。

COMBOBOX        IDC_PPO_TYPE1,140,247,54,13,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP

我相信调用GetDlgItem() 控制项处理无效。这在项目的 8.0 版本中不是问题。 IDC_PPO_TYPE1 似乎是此表单上的有效资源。这似乎是将项目从 8.0 转换到 2019 时的问题。

【问题讨论】:

  • 没有minimal reproducible example,我们无法评估您的设置有什么问题。我们看不到您的资源是什么样子,或者其中定义了什么。我们看不到您的代码在创建对话框或尝试访问 ComboBox 时的样子。如果我不得不猜测,要么IDC_PPO_TYPE1 定义不正确,要么Hndl 没有指向您期望的对话框。
  • 我不知道你从哪里调用了哪个函数。 MFC 使用CWnd* control = GetDlgItem(IDC_PPO_TYPE1);,例如,您可以在CDialog::OnInitDialog 之后调用它。然后是 Windows API HWND hwnd_control = ::GetDlgItem(m_hWnd, IDC_PPO_TYPE1) 其中m_hWnd 是父窗口的句柄,你必须确保父窗口已创建,句柄可以使用::IsWindow(m_hWnd) 进行测试
  • 谢谢 - 我确实将事件发送给我的事件处理程序,所以我相信 Hndl 值是正确的。但我无法在控件 UI 项中设置默认值
  • 很可能您使用了错误的Hndl 或使用了错误的时间。使用::IsWindow(Hndl)::GetWindowText(Hndl, title, 100); 检查它是正确的对话框。您还可以使用 Visual Studio 工具菜单中的 Spy++ 来检查窗口句柄是否与 Hndl
  • GetDlgItem() 呼叫后立即呼叫GetLastError()GetDlgItem() 是系统调用(不是 MFC),不应失败。对话框句柄或控件 ID 错误。在代码中与GetDlgItem() 调用相同的位置记录它们,并将记录的值与SpyXX 实用程序中显示的值进行比较(选择 Spy->Find Window,将目标拖到对话窗口并检查其属性 - 句柄和子项)。你必须找出他们在哪里得到了错误的值。

标签: c++ visual-studio winapi visual-studio-2015 mfc


【解决方案1】:

看来您已经对解决方案有了预感:

我认为控制项处理无效

这可能是你的问题。

来自documentation

只要hDlg参数指定了父窗口和子窗口 窗口有一个唯一的标识符(由 hMenu 参数指定 创建子项的 CreateWindow 或 CreateWindowEx 函数 window),GetDlgItem 返回子窗口的有效句柄。

您必须确保hDlg 是对话框的有效句柄,并且如果IDC_PPO_TYPE1 是唯一的,请检查头文件。也许您添加了一些东西并且标识符发生了冲突?

【讨论】:

  • 谢谢 - 是的,从日志中我可以看到 GetDlgItem 中使用的 hDlg 是有效的。而且物品的ID是唯一的
  • 除了 GetDlgItem 之外还有其他方法来获取 conreol 的句柄 - 是否有任何 Win API?
  • 如果我没记错的话,理论上你可以通过EnumChildWindow 循环访问这些项目,因为按钮和其他控件是作为窗口实现的。我不知道这是否适用于所有对话框项。我可能错了,已经有一段时间了。但是 GetDlgItem 是做你想做的事情的正确函数,在我看来你可能不正确地使用它 - 无论是在错误的时间,还是使用不正确的参数。
  • 我的建议是创建一个可以编译和测试的最小工作示例。请发布有关如何创建重现您的问题的最小项目的说明。
  • 非常感谢 @roccobaroccoSC - EnumChildWindow API 帮了我大忙 - 非常感谢您的有效输入
猜你喜欢
  • 2010-12-10
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2014-08-02
相关资源
最近更新 更多