从功能区添加新文档后关闭文档时,InteropServices.ComException

时间:2019-05-31 18:27:05

标签: ms-word vsto

我正在尝试编写一个使用CustomTaskPane的Word加载项。我能够创建CustomTaskPane并在打开的文档之间进行同步,只要在添加新文档或打开现有文档时使用Word菜单,就不会出错。但是,如果我通过调用Globals.ThisAddIn.Application.Documents.Add()的功能区按钮添加新文档,则在关闭文档时开始获取COMExceptions。

问题似乎是当我使用CtpMainRibbon.cs中的按钮单击事件而不是通过Word菜单添加新文档时,Globals.ThisAddIn.Application.ActiveWindow属性在关闭打开的文档后无效。在获取CurrentCustomTaskPane属性时,ActiveWindow在System.Runtime.InteropServices.COMException: 'This command is not available because no document is open.'返回一个Microsoft.Office.Interop.Word.ApplicationClass.get_ActiveWindow()。我已经搜索了错误,但是大多数问题是当人们尝试在服务器或ASP.net页面上使用Word Interop时,但是我在开发机器上遇到了这个问题。另外,如果我使用Document.Add()方法,则“显示”按钮的检查状态无法正确显示(如果我在一个文档中打开了CustomTaskPane,然后单击功能区上的“新建文档”按钮,则新文档的“显示”按钮为

如果我切换到其他窗口然后再切换回新文档,则该按钮的“已选中”状态将更新为“未选中”。

我尝试遍历Globals.ThisAddIn.CustomTaskPanes以查看ctp.Window.Hwnd属性之间是否存在不匹配,但据我所知,每个ctp.Window都有自己的唯一{{1 }}。即使还有其他文档和窗口打开,我也会收到消息。

这是2个相关的代码文件。我使用CurrentCustomTaskPane,以便功能区按钮可以与任务窗格的Visible属性同步。

ThisAddIn.cs:

Hwnd

CtpWordRibbon.cs:

private const string TaskPaneTitle = "Main Custom Task Panel";
public static CustomTaskPane CurrentCustomTaskPane
{
    get
    {
        return Globals.ThisAddIn.CustomTaskPanes
              .FirstOrDefault(ctp => !ctp.Control.IsDisposed && 
                Globals.ThisAddIn.Application.ActiveWindow != null && 
                ReferenceEquals(ctp.Window, Globals.ThisAddIn.Application.ActiveWindow) && 
                ctp.Title == TaskPaneTitle);
    }
}

private void InternalStartup()
{
    Startup += ThisAddIn_Startup;
    Shutdown += ThisAddIn_Shutdown;
}

private void ThisAddIn_Startup(object sender, EventArgs e)
{
    if (Application.Documents.Count > 0)
    AddNewTaskPane(Application.ActiveDocument);
    Word.ApplicationEvents4_Event event4 = Application;
    event4.NewDocument += OnNewDocument;
    event4.DocumentOpen += OnDocumentOpen;
    event4.WindowActivate += ApplicationOnWindowActivate;
}

private static void ThisAddIn_Shutdown(object sender, EventArgs e) { }

private void OnNewDocument(Word.Document doc) => AddNewTaskPane(doc);

private void OnDocumentOpen(Word.Document doc) => AddNewTaskPane(doc);

private void ApplicationOnWindowActivate(Word.Document doc, Word.Window wn) => SetRibbonButtonToggle();

private void AddNewTaskPane(Word._Document doc)
{
    RemoveOrphanedTaskPanes();
    CustomTaskPane newPane = CustomTaskPanes.Add(new MainCustomTaskPanel(), TaskPaneTitle, doc.ActiveWindow);
    newPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionLeft;
    newPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
    newPane.Width = 700;
    newPane.VisibleChanged += TaskPaneOnVisibleChanged;
}

private void TaskPaneOnVisibleChanged(object sender, EventArgs e) => SetRibbonButtonToggle();

private void SetRibbonButtonToggle()
{
    if (CurrentCustomTaskPane != null)
    Globals.Ribbons.CtpWordRibbon.RbnButtonShowTaskPane.Checked = CurrentCustomTaskPane.Visible;
}

private void RemoveOrphanedTaskPanes()
{
    foreach (CustomTaskPane ctp in CustomTaskPanes)
    {
        if (ctp.Window == null || ctp.Control.IsDisposed)
            CustomTaskPanes.Remove(ctp);
    }
}

Word处理通过Word菜单添加新文档和使用private void RbnButtonShowCtp_Click(object sender, RibbonControlEventArgs e) { if (ThisAddIn.CurrentCustomTaskPane != null) ThisAddIn.CurrentCustomTaskPane.Visible = ((RibbonToggleButton)sender).Checked; } private void RbnButtonCreateNewDocument_Click(object sender, RibbonControlEventArgs e) { Globals.ThisAddIn.Application.Documents.Add(); } 方法添加文档之间的方式显然有区别。在实际访问它之前,如何检查Application.Documents.Add()属性是否将引发COMException?还是有更好的方法通过功能区创建新文档,或处理ActiveDocument事件以使我不会收到这些错误?

0 个答案:

没有答案