【问题标题】:MessageBox closing without user action无需用户操作即可关闭消息框
【发布时间】:2015-06-27 13:35:20
【问题描述】:

我有针对 .NET 4.0 客户端配置文件的 VB.NET 解决方案,其中包括 Excel 和 PowerPoint 加载项。每个程序集都有一个单独的程序集,第三个程序集的代码对两者都是通用的。因此,通用程序集是其他两个程序集的依赖项。

有时,当 common 程序集中的代码打开 MessageBox 时,它会在没有用户输入的情况下自动关闭,但不是可预测或可靠的。似乎 调用 程序集(即 Excel 插件)已从通用程序集中夺回对 UI 的控制权(可能与线程有关?),或者调用汇编代码在显示 MessageBox 时继续执行。

我在解决方案的各个完全独立的部分中观察到了这种行为,但无法弄清楚问题出在哪里。同样,这种情况并非一直发生,我无法可靠地重现这种情况。我正在 Office 2013 中的 Windows 8.1 上对此进行测试。

很遗憾,确实没有任何相关代码可以发布,除了:

MessageBox.Show(...)

我希望有人可以提供一些关于这里可能发生的事情的见解,并提供修复。

编辑

在下面合并 Hans 的建议后,我的代码现在是:

MessageBox.Show(New WindowWrapper(handle), [Message], [Caption], MessageBoxButtons.OK, [Icon])

其中句柄 [Integer] = Excel.Application.Hwnd 和:

Public Class WindowWrapper
  Implements IWin32Window
  Private hwnd As IntPtr

  Public Sub New(handle As IntPtr)
    hwnd = handle
  End Sub
  Public Sub New(handle As Integer)
    hwnd = New IntPtr(handle)
  End Sub

  Public ReadOnly Property Handle As IntPtr Implements IWin32Window.Handle
    Get
      Return hwnd
    End Get
  End Property
End Class

还是有同样的问题。

【问题讨论】:

    标签: c# .net vb.net excel .net-assembly


    【解决方案1】:
      MessageBox.Show(...)
    

    这并不是一个非常有用的 sn-p。它所表明的只是你没有注意最关键的论点。 尤其是所以在 Office 插件中,绝对必须使用,最难正确使用。

    它是 owner 参数。

    非常非常重要。一个对话框必须有一个所有者才能正确操作。微软让不直接指定它变得太容易了。如果您使用没有 owner 参数的重载,那么它会自行寻找所有者。结果通常很好。但你并不总是会喜欢它找到的那个,你对 UI 的控制越少,你就越不可能开心。 Office 插件中的一个明显问题,它控制蹲下。

    它使用 GetActiveWindow() 返回的窗口。如果碰巧是由 Office 程序创建的窗口随后关闭,您将不会感到高兴。这也会关闭消息框。请记住,消息框是模态的,但只会禁止用户输入。它不会以任何方式阻止程序关闭窗口。

    是的,当您在工作线程上调用它时,您永远不会高兴。 GetActiveWindow() 具有线程关联性,活动窗口是每个线程的属性。不会有任何其他窗口,因此桌面成为对话框所有者。没有关闭它的风险,但你会遇到令人讨厌的 Z 顺序问题。任何其他线程拥有的 Windows(例如由 Office 程序创建的线程)都不会被禁用。或者换句话说,消息框窗口很容易消失在主窗口后面。不会被用户再次找到,他没有线索去寻找它。

    必须指定所有者,不要走捷径。一个明显的选择是 Office 应用程序的主窗口,例如 Excel 中 Application.Hwnd 属性返回的主窗口。创建 IWin32Window 实现的示例代码is here

    【讨论】:

    • 谢谢,汉斯。什么是“所有者”论点? msdn.microsoft.com/en-us/library/tewzaxwc(v=vs.100).aspx 的文档中没有描述。
    • 正确,错误的过载。向左看,注意带有 IWin32Window 参数的那些。
    • 知道了。也不知道楼主的说法。我认为这是我最初问题的答案。现在,我需要弄清楚如何创建一个 IWin32Window 参数(我查看了您提供的原始链接,无法理解此上下文中的 C# 代码)。任何将 MessageBox.Show() 与 owner 参数一起使用的 VB.NET 示例都会有所帮助(搜索了一下,但到目前为止一无所获)。
    • 看起来很有希望之后,这个答案最终没有解决问题,我仍然遇到消息框在没有用户交互的情况下被关闭/关闭/隐藏的问题。
    • 如果不发布复制代码,您将无法获得更多帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多