现在的位置: 首页 > 综合 > 正文

HOWTO: 在Office应用程序中显示MessageBox或Modal Form

2013年07月01日 ⁄ 综合 ⁄ 共 1049字 ⁄ 字号 评论关闭

 

在一个WinForm程序中,MessageBox有如下特点:存在一个与之相关的"宿主"窗体,即MessageBox在此窗体及其上的控件的事件处理程序中弹出,并且,当MessageBox关闭后,焦点自动切换到"宿主"窗体.Modal Form(模态窗体)有相同的特点.

但是如果WinForm程序中启动了Office应用程序,并且在处理Office对象模型中的某些事件时,你需要显示MessageBox或Modal Form,则会遇到一些问题.

举例来说,在一个WinForm程序,编程在Excel中增加一个CommandBarButton(工具栏按钮),然后处理此对象的Click事件,假如在此对象中需要弹出一个MessageBox,就会发现当关闭MessageBox时,焦点并不会切换到Excel应用程序上.那么焦点切换到哪个窗口了呢?

假如在这个窗口中存在如下两个Form:Form1和Form2,假如Excel应用程序是在Form2或Form2上的控件的事件中启动,则焦点会切换到Form2上.

这说明MessageBox把Form2认作"宿主"窗体,但它的这个行为违反了我们对程序的期愿,那么,我们能不能自己指定MessageBox的"宿主"窗体呢?通过查阅MSDN,我们可以看到MessageBox.Show有一个重载形式:
MessageBox.Show(IWin32Window, ...);

很显然,我们需要这个重载,但Office对象模型中并没有一个方法可以返回IWin32Window类型的对象,这是一个问题,不是吗?

以下是解决这个问题的方法:
public class WindowWrap : IWin32Window
{
private Intptr m_Handle;
public Intptr Handle
{
   get{ return m_Handle; }
}

public WindowWrap(Intptr handle)
{
   m_Handle = handle;
}
}

看清楚了吗,我们仅仅需要的就是一个Handle.

[DllImport("USER32.DLL")]
public static extern Intptr FindWindow(lpClassName, lpWindowName);

通过引入Win32 API,我们可以轻松的得到Excel应用程序主窗体的句柄,好了,我想你知道该怎么做了:)

 

标题中还提到了Modal Form,看到下面这个方法了吗:)

Form.ShowDialog(IWin32Window,...

抱歉!评论已关闭.