Visio Interop应用程序事件导致意外行为

时间:2016-03-08 12:35:15

标签: c# .net office-interop visio

我正在尝试使用Visio Application事件。在实例化新的Application对象并设置任何事件(即BeforeDocumentClose)时,这似乎导致在最小化后无法恢复Visio窗口。

我正在使用VS / C#2013,Windows窗体,Visio 2013(在Windows 7上)。虽然我的主要代码项目是使用Add-Ins在各种办公应用程序之间进行大量实现交换,但以下简单代码再现了同样的问题。它是一个Windows窗体项目(添加了对Microsoft.Office.Interop.Visio的引用)。

using Visio = Microsoft.Office.Interop.Visio;

Visio.Application app;
bool initialised = false;

private void visioButton_Click(object sender, EventArgs e)
{
    init();

    app.Documents.Add("c:\\test.vst"); // creates new document from template
}

void init()
{
    if (!initialised)
    {
        // only initialise once
        app = new Visio.Application();
        app.BeforeDocumentClose += app_BeforeDocumentClose;
        initialised = true;
    }
}

void app_BeforeDocumentClose(Visio.Document doc)
{
}

问题#1:这是主要问题。创建一个或多个Visio文档后,Visio窗口在最小化后未最大化。就我所见,没有抛出异常。 Windows只是发出声音错误'ping'。

问题#2:这是次要问题。创建两个或多个Visio文档,将鼠标悬停在Windows任务栏上,预览窗口显示等待光标而不是正常文档预览。

条件:问题#1仅在应用程序上使用事件时发生。文档,页面/形状事件不会导致任何问题。所有事件都被捕获。问题#2总是会发生,但这对我来说不那么重要。

我一直在寻找这个问题,但找不到与之相关的任何内容,所以非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

我不太清楚是什么导致Visio无法响应恢复,但您可以尝试使用" AddAdvise"代替:

[ComVisible(true)]
public partial class Form1 : Form, Visio.IVisEventProc
{
    public Form1()
    {
        InitializeComponent();
    }

    Visio.Application app;
    bool initialised = false;

    private void button1_Click(object sender, EventArgs e)
    {
        init();

        app.Documents.Add("C:\\test.vst"); // creates new document from template
    }

    void init()
    {
        if (!initialised)
        {
            // only initialise once
            app = new Visio.Application();
            // app.BeforeDocumentClose += app_BeforeDocumentClose;
            app.EventList.AddAdvise(DocCloseEventCode, this, null, null);
            initialised = true;

            Application.DoEvents();
        }
    }

    const short DocCloseEventCode = unchecked((short)Visio.VisEventCodes.visEvtDoc + (short)Visio.VisEventCodes.visEvtDel);

    object Visio.IVisEventProc.VisEventProc(short eventCode, object source, int eventID, int eventSeqNum, object subject,object moreInfo)
    {
        if (eventCode == DocCloseEventCode)
            app_BeforeDocumentClose(subject as Visio.Document);

        return null;
    }

    void app_BeforeDocumentClose(Visio.Document doc)
    {
    }
}

答案 1 :(得分:0)

使用Nikolay的建议为多个事件提供完整的解决方案,这里是完整的代码,包括事件和(de)Visio应用程序的初始化,而不使用模板。 (请注意,消息框可能会在后台显示在Visio窗口后面。)

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Visio = Microsoft.Office.Interop.Visio;

namespace VisioInteropTest
{
    [ComVisible(true)]
    public partial class TestForm : Form, Visio.IVisEventProc
    {
        Visio.Application app;
        bool initialised = false;

        // all AddAdvise events:
        // https://msdn.microsoft.com/en-us/library/office/ff768620.aspx
        const short appCloseEventCode = (short)(Visio.VisEventCodes.visEvtApp | Visio.VisEventCodes.visEvtBeforeQuit);
        const short docCloseEventCode = (short)(Visio.VisEventCodes.visEvtDoc | Visio.VisEventCodes.visEvtDel);

        public TestForm()
        {
            InitializeComponent();
        }

        private void visioButton_Click(object sender, EventArgs e)
        {
            if (init())
            {
                app.Documents.Add("");
            }
        }

        bool init()
        {
            if (!initialised)
            {
                app = new Visio.Application();
                app.EventList.AddAdvise(appCloseEventCode, this, null, null);
                app.EventList.AddAdvise(docCloseEventCode, this, null, null);
                initialised = true;
            }
            return initialised;
        }

        object Visio.IVisEventProc.VisEventProc(short eventCode, object source, int eventID, int eventSeqNum, object subject, object moreInfo)
        {
            switch (eventCode)
            {
                case appCloseEventCode: app_BeforeAppClose((Visio.Application)subject); break;
                case docCloseEventCode: app_BeforeDocumentClose((Visio.Document)subject); break;
            }
            return null;
        }

        void app_BeforeAppClose(Visio.Application app)
        {
            initialised = false;
            MessageBox.Show("App closed");
        }

        void app_BeforeDocumentClose(Visio.Document doc)
        {
            MessageBox.Show("Doc closed");
        }

    }
}