捕获新创建的模态对话框的窗口句柄

Posted

技术标签:

【中文标题】捕获新创建的模态对话框的窗口句柄【英文标题】:Capturing the window handle of a newly created modal dialog 【发布时间】:2016-06-30 20:30:56 【问题描述】:

我正在使用和改进一个名为 FFC 的开源 MFC 类似工作的库。有时该库会将错误的窗口句柄与对话框对象相关联,这意味着稍后在查找正确的句柄时无法找到 C++ 对象。特别是,当应用程序打开其根窗口时会发生这种情况,这是一个通过调用 DoModal 打开的对话框。

在其 DoModal 函数中,FFC 库使用一种...“令人惊讶”的方式将句柄附加到对话框对象。它将“this”指针存储在全局变量中,并在调用 DialogBox 函数之前挂钩要在所有窗口消息上调用的函数。它注册的这个钩子函数假定它接收到的第一条消息的句柄是全局变量中窗口的句柄,并将该句柄附加到它。

有时,这行得通。通常 - 我不知道这是因为 McAfee 扫描仪在我的工作计算机上所做的侵入性操作,还是因为我的程序从控制台窗口启动,或其他原因 - 许多不相关的消息将在消息实际用于之前被捕获模态对话框通过。

起初我以为是因为 FFC 不确定它要查找的消息是“WM_CREATE”。我添加了这个检查,但它没有解决问题。原来一个或多个虚假消息也是 WM_CREATE 消息!在获得真正的对话框之前,它收到的第一个 WM_CREATE 是一个窗口句柄,其中包含空白窗口文本和矩形 0,0-0,0。

那么这真的是获取模式对话框句柄的正确或规范方法吗?这似乎不可靠。 (注意,因为对话框是模态的,所以不能使用 CreateWindowEx 的返回值,因为 DialogBox 函数在模态对话框关闭之前不会返回。) MFC 真的是这样吗?有没有更好的办法?我可以将一些数据与对话框相关联,或者查找应该与之相关联的数据以确保我有正确的窗口句柄吗? (例如检查传递给对话框调用的模板参数,如果我能以某种方式从句柄中取回它。)

【问题讨论】:

MFC 的源代码随 Visual Studio 一起提供。自己看看吧。 哦,顺便说一句,MFC 不需要检查特定消息。它设置了一个钩子,调用CreateWindowEx(或它的一个朋友),让钩子回调设置实例指针,然后解除当前线程的钩子。所有这一切都允许操作系统在它认为合适的时候重新排序消息,并且当第一条消息到达时,无论在任何给定版本的 Windows 上可能是什么,MFC 都会有一个正确附加到窗口句柄的实例指针。如果您看到虚假消息妨碍您,您可能违反了线程关联规则:GUI 需要是单线程的。 【参考方案1】:

我确信这是在书中发表的,但 MFC 设置了一个 windows 挂钩 (WH_CBT),然后在挂钩中查找 HCBT_CREATEWND 代码以将 C++ 对象与 HWND 结合。

【讨论】:

以上是关于捕获新创建的模态对话框的窗口句柄的主要内容,如果未能解决你的问题,请参考以下文章

如何在WPF中进行模态对话?

如何创建一个模态的对话框

创建自定义 fltk 对话框/模态窗口

模态对话框如何调用父窗口的JS函数?

如何显示与 TrsteelCkeditorBundle 集成的 FMElfinderBundle 的模态对话框或弹出窗口?

Qt的模态对话框和非模态对话框 经常使用setAttribute (Qt::WA_DeleteOnClose)