2016-03-08 41 views
0

我正在嘗試使用Visio應用程序事件。當實例化一個新的Application對象並設置任何事件(即BeforeDocumentClose)時,這似乎導致無法在最小化它之後恢復Visio窗口。Visio Interop引起不良行爲的應用程序事件

我使用VS/C#2013,Windows窗體,Visio 2013(在Windows 7上)。雖然我的主要代碼項目是使用加載宏在各種辦公應用程序之間實現巨大的交換,但下面的簡單代碼重現了同樣的問題。它是一個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總是會發生,但這對我來說不那麼重要。

我一直在尋找這個問題的一段時間,但無法找到任何相關的東西,所以任何幫助,非常感謝。

回答

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) 
    { 
    } 
} 
+0

感謝您的回覆。不幸的是,這會在app.EventList.AddAdvise(DocCloseEventCode,this,null,null)中生成一個COMException異常。 – Yost777

+0

你是按原樣複製帖子中的代碼嗎? (注意屬性[ComVisible(true)]。意思是測試,用1個按鈕創建一個新的winforms應用程序,然後從帖子中複製粘貼代碼 – Nikolay

+0

再次感謝Nikolay,你是對的。因爲我還沒有回答任何人的問題,所以無法發表評論,直到我的代表更高爲止。 – Yost777

0

要使用尼古拉的意見,多個事件提供了完整的解決方案,這裏是完整的代碼,包括事件和(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"); 
     } 

    } 
} 
相關問題