在Office应用中打开WPF窗体并且让子窗体显示在Office应用上

在.NET主程序中,我们可以通过创建 ExcelApplication 对象来打开一个Excel应用程序,如果我们想在Excle里面再打开WPF窗口,问题就不那么简单了。

我们可以简单的实例化一个WPF窗体对象然后在Office应用程序的窗体上打开这个新的WPF窗体,此时Office应用的窗体就是WPF的宿主窗体。然后宿主窗体跟Office应用并不是在一个UI线程上,子窗体很可能会在宿主窗体后面看不到。这个时候需要调用Win32函数,将Office应用的窗体设置为WPF子窗体的父窗体,这个函数的形式定义如下:

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

由于Office应用程序是非托管程序,WPF窗体是托管程序,.NET提供了一个 WindowInteropHelper 包装类,它可以将一个托管程序窗体包装得到一个窗口句柄,之后,就可以调用上面的Win32函数 SetParent 设置窗口的父子关系了。

下面方法是一个完整的方法,可以通过反射实例化一个WPF窗体对象,然后设置此WPF窗体对象为Office应用程序的子窗体,并正常显示在Office应用程序上。

   /// <summary>
        /// 在Excle窗口上显示WPF窗体
        /// </summary>
        /// <param name="assemplyName">窗体对象所在程序集</param>
        /// <param name="paramClassFullName">窗体对象全名称</param>
        public static void ExcelShowWPFWindow(string assemplyName, string paramClassFullName)
        {
            Application.Current.Dispatcher.Invoke(new Action(() => {
                try
                {
                    Assembly assembly = Assembly.Load(assemplyName);
                    Type classType = assembly.GetType(paramClassFullName);
                    object[] constuctParms = new object[] { };
                    dynamic view = Activator.CreateInstance(classType, constuctParms);
                    Window winBox = view as Window;
                    var winBoxIntreop = new WindowInteropHelper(winBox);
                    winBoxIntreop.EnsureHandle();
                    //将Excel句柄指定为当前窗体的父窗体的句柄,参考 https://blog.csdn.net/pengcwl/article/details/7817111
                    //ExcelApp 是一个Excle应用程序对象
                    var excelHwnd = new IntPtr(OfficeApp.ExcelApp.Hwnd);
                    winBoxIntreop.Owner = excelHwnd;
                    SetParent(winBoxIntreop.Handle, excelHwnd);
                    winBox.ShowDialog();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打开窗口错误:"+ex.Message);
                }
            }));
        }
    }

     

猜你喜欢

转载自www.cnblogs.com/bluedoctor/p/8946215.html