Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无需用户操作即可关闭MessageBox_C#_.net_Vb.net_Excel_.net Assembly - Fatal编程技术网

C# 无需用户操作即可关闭MessageBox

C# 无需用户操作即可关闭MessageBox,c#,.net,vb.net,excel,.net-assembly,C#,.net,Vb.net,Excel,.net Assembly,我有针对.NET 4.0客户端配置文件的VB.NET解决方案,其中包括Excel和PowerPoint的加载项。每一个都有一个单独的程序集,第三个程序集的代码对两者都是通用的。因此,公共程序集是其他两个程序集的依赖项 有时,当common程序集中的代码打开一个MessageBox时,它会在没有用户输入的情况下自动关闭,但这是不可预测或不可靠的。似乎调用程序集(即Excel外接程序)已从通用程序集夺回了对UI的控制权(可能与线程有关?),或者调用程序集代码只是在显示MessageBox时继续执行

我有针对.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])
其中handle[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
还是有同样的问题

  MessageBox.Show(...)
这并不是一个非常有用的片段。它只表明你没有注意到最关键的论点。尤其是在Office插件中,使用起来绝对必要,最难正确使用

这是所有者的论点

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

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

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


您必须指定所有者,不要使用快捷方式。一个明显的选择是Office应用程序的主窗口,就像Excel中Application.Hwnd属性返回的窗口一样。创建iwin32窗口实现的示例代码。

谢谢,Hans。“所有者”的论点是什么?文档中没有对其进行描述。对,错过载。向左看,注意那些接受IWin32Window参数的,明白了。甚至都不知道主人的争论。我想这就是我原来问题的答案。现在,我需要弄清楚如何创建一个IWin32Window参数(我查看了您提供的原始链接,在这种情况下无法理解C代码)。任何将MessageBox.Show()与owner参数一起使用的VB.NET示例都会很有帮助(搜索了一段时间,但到目前为止没有找到任何结果)。看起来很有希望,但这个答案最终没有解决问题,我仍然遇到一个问题,消息框在没有用户交互的情况下被关闭/取消/隐藏。如果不发布复制代码,您将无法获得更多帮助。