c# - Form.ShowDialog(IWin32Window) 是否应该与任何窗口句柄一起使用?

标签 c# .net winforms modal-dialog bho

当使用 System.Windows.Forms.ShowDialog(IWin32Window) 时,我是否应该能够传入一个代表任何窗口句柄的 IWin32Window 并使其成为模态的到那个窗口?

作为 Internet Explorer 7 扩展的一部分,我试图打开一个关于 Internet Explorer 选项卡的窗口模式。它不是当前选定的选项卡,但我可以获取选项卡的 hwnd 确定。但是,当我将其传递给 ShowDialog 时,我的表单会显示出来,但它对任何内容都不是模态的:我仍然可以在 Internet Explorer 中执行操作,包括在应该是所有者的选项卡中。我的表单显示为 float 在 Internet Explorer 窗口上方并保持在顶部,因此它不像是作为普通表单打开的那样,但它不是正确的模式。

使用 Spy++ ,我可以找到我的表单,并且它的所有者句柄已正确设置。

这是否意味着出了什么问题,或者我做错了什么?如何使我的表单正确地模态化?

仅供引用,我正在使用这个包装类从 hwnd 创建一个 IWin32Window(感谢 Ryan!):

/// <summary>
/// Wrapper class so that we can return an IWin32Window given a hwnd
/// </summary>
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

更新:使用 Internet Explorer 7 和 .NET 2.0

更新:更多地使用 Spy++ 和它公开的句柄,我发现如果我使用不同的 hwnd 然后我可以使我的窗口模态到选项卡:

我按照 IWebBrowser2.HWND doc 的建议使用选项卡的 hwnd ,在 Spy++ 中显示为类 TabWindowClass。它有一个类 Shell DocObject View 的子类,后者有一个 Internet_Explorer_Server 的子类。如果我使用 Internet Explorer_Serverhwnd 那么它会正常工作,例如,当我在其他选项卡上单击鼠标时,Internet Explorer 会正常 react 。当我在感兴趣的选项卡上单击鼠标时,它会播放 windows d'oh 声音并且不执行任何操作。

我还不知道如何以编程方式获取 Internet_Explorer_Server hwnd,但它应该是可能的。

此外,尽管如此,在使用其他窗口句柄时,我通常能够使我的窗体模式适用于其他应用程序和对话框。所以我想我的问题的答案是“很多但不是所有句柄”......这可能取决于应用程序?

更新:另一个旁注:我想让我的表单模态到选项卡而不是整个窗口的最初原因是,当从我的表单打开 MessageBox 时,将表单作为所有者传递,MessageBox 不会总是在我的表单顶部打开。如果一个新的 Internet Explorer 选项卡刚刚打开但未处于事件状态,则 MessageBox 将被隐藏并且该选项卡将开始闪烁。但是,由于 Internet Explorer 在我的表单打开模式下被禁用,因此无法切换到该选项卡,因此 Internet Explorer 将被卡住。我认为打开选项卡的表单模式可以解决这个问题,但我发现另一种解决方案是避免使用 MessageBox:如果我使用第二个表单和 ShowDialog(this) 从我的第一个表单然后第二个表单正确打开到前面。因此,在某些情况下,Form.ShowDialog() 似乎比 MessageBox.Show() 效果更好。更多讨论在 Problems with modal dialogs and messageboxes .

最佳答案

ShowDialog() 做了两件重要的事情。它开始泵送消息循环,因此它以模态方式对调用代码起作用。并且它通过 EnableWindow(false) API 调用禁用应用程序中的任何其他窗口。后者是您的情况没有发生的事情。考虑到需要禁用的窗口不是 WF 窗口,这并不奇怪。

您可能需要自己调用 EnableWindow()。请务必在对话框关闭之前重新启用它,否则 Windows 将寻找另一个应用程序的窗口以提供焦点。

关于c# - Form.ShowDialog(IWin32Window) 是否应该与任何窗口句柄一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/581855/

相关文章:

C# COM 端口通信 - USB 转串行适配器出现错误

.net - 如何连续循环DataGridView行?

c# - 有没有办法在 WinForm 表中有交替的行颜色

c# - 在 AutoCAD .Net 插件中执行多线程作业

C# 似乎无法正确地将图像添加到 ziarchive

C# HttpWebRequest 验证/指定使用的密码

c# - 为什么这个 .NET Core 包与我的 PCL 不兼容?

c# - 验证是否存在可用网络连接的最简单方法是什么?

c# - 最佳实践 - 不同的程序模型/使用变量以编程方式决定表单如何创建

c# - 未针对 REST 调用触发 PreRequestHandlerExecute 事件