VSTO窗体在Excel内弹窗置顶

  • 发布时间:2017年2月16日 15:13
  • 作者:杨仕航
  • 分类标签: VSTO
  • 阅读(12300)
  • 评论(0)

一般在VSTO打开一个窗体用show方法。如下图(一个简单的测试项目):

20170216/20170216143626693.png

Ribbon上有个按钮,该按钮点击事件是打开一个FormTest窗体。

代码看上去没什么问题,测试运行看看效果。

20170216/20170216143919227.png

细心的同学可以发现,任务栏上面有两个Excel窗口的标志。

若此时再点击一下Excel的单元格,这个FormTest窗体会被Excel挡住。

通常Excel内自己窗口的弹窗不会被Excel本身挡住,就像查找替换窗体。

20170216/20170216144312056.png

留意任务栏的Excel窗口标志,只有一个!

那我们要如何才能实现和查找替换窗口一样的效果呢?在Excel内弹窗置顶。


这里先说说两种临时解决方案。

1)用ShowDialog方法打开窗体。不过该方法会导致无法在打开窗体的时候,操作Excel单元格。

2)设置窗体的TopMost属性为True。

20170216/20170216144712794.png

但该属性是全局置顶,而不是Excel内部置顶。

20170216/20170216144820374.png

可以从上图看出,遮住了记事本的窗口。而且任务栏的Excel窗口标志还是两个。


正确的解决方法如下。使用窗体Show方法的第2个方法

20170216/20170216145111293.png

I开头的名称都表示该类型是一个接口。我们需要给这个窗口指定一个所有者。

通俗点说,告诉它的父亲是谁。由它父亲控制和管理,让其在内部打开。


为了方便统一管理,新建一个类,该类继承IWin32Window接口。代码如下:

using System;
using System.Windows.Forms;

//命名空间自行修改
namespace ExcelAddin1
{
    /// <summary>
    /// IWin32Window接口类,为了实现弹出的窗体在Excel内
    /// </summary>
    public class ClsWinWrap:IWin32Window
    {
        private IntPtr m_Handle;

        //构造函数,参数是父窗口的句柄
        public ClsWinWrap(IntPtr handle)
        {
            this.m_Handle = handle;
        }

        //构造函数,参数是父窗口的句柄
        public ClsWinWrap(int handle)
        {
            this.m_Handle = new IntPtr(handle);
        }

        public IntPtr Handle
        {
            get { return m_Handle; }
        }

        //打开窗体,Show参数使用该类自身
        public void Show(Form frm)
        {
            frm.Show(this);
        }

        //模式打开窗体,Show参数使用该类自身
        public DialogResult ShowDialog(Form frm)
        {
            return frm.ShowDialog(this);
        }
    }
}


继承该IWin32Window接口,只需要有Handle属性即可。

Handle是父窗体的句柄。Excel的Application句柄很容易获取,使用方法如下:

//Globals.ThisAddIn.Application.Hwnd 获取Excel Application的句柄
ClsWinWrap clsWinWrap = new ClsWinWrap(Globals.ThisAddIn.Application.Hwnd);

FormTest form = new FormTest();
clsWinWrap.Show(form);  //打开窗口,指定它的父亲是Excel

效果如下:

20170216/20170216150456485.png

打开窗体之后,点击单元格。Excel不会遮住该窗体,该窗体也不是全局置顶(记得TopMost设置为False)。也可以编辑单元格。

但任务栏还是又标志显示。

这个再设置几个属性即可。我通常把窗体设置为不可改变大小,去掉最大化最小化按钮,去掉图标和任务栏显示。

20170216/20170216151035435.png

设置完成之后,再打开测试。其效果就和查找替换框一致。

20170216/20170216151129215.png

上一篇:VSTO窗体在Word内弹窗置顶

下一篇:Excel绘制心形图(情人节特辑)

相关专题: VSTO的那些坑   

评论列表

智慧如你,不想发表一下意见吗?

新的评论

清空