在文档变得不受保护后访问受保护的组件

时间:2015-07-15 01:33:54

标签: c# ms-word vsto office-interop word-2010

我希望修改DocumentOpen事件中的文档,在适当的位置向现有文本添加一些内容控件并更改格式。这样可以正常工作,但在受保护的文档不受保护后触发DocumentOpen事件时会变得更复杂:

word_protected

点击"启用编辑"开始"取消保护"一个文档,以及我此时已经定义过的DocumentOpen事件。由于事件似乎在打开默认的不受保护的窗口之前触发,因此仍然认为创建内容控件不可用。一个简单的例子,当文档处于不受保护的过程中时不会成功:

private void ThisAddIn_Startup(object sender, EventArgs e)
{
    Application.DocumentOpen += application_DocumentOpen;
}

private void application_DocumentOpen(Document doc)
{
    doc.ContentControls.Add(
        WdContentControlType.wdContentControlRichText,
        doc.Range(doc.Content.Start, doc.Content.End - 1));
}

有没有办法快速执行不受保护的过程,可以这么说,仍然可以执行我的代码?或者在文档编辑可用时可预测地触发的另一个事件?我已经查看了与保护模式in the Microsoft documentation相关的事件,但没有看到任何符合我需求的事件。遗憾的是,Document.Unprotect()和更改Document.ActiveWindow.View.Type也没有用,因为"保护模式"似乎是一个完全不同的,不可编辑的窗口。要求在打开文档时或在此后尽快进行这些格式修改。

1 个答案:

答案 0 :(得分:0)

它还不错,但我最终通过定义一个包含我想要执行的代码的委托来解决这个问题,该委托与每个文档的容器相关联,并检查委托是否可以在{ {1}}:

public class DocumentContainer
{
    public Action ProtectedDeferredExecution { get; set; }

    public DocumentContainer(Action deferred)
    {
        ProtectedDeferredExecution = deferred;
    }
}

public partial class ThisAddIn
{
    private Dictionary<Document, DocumentContainer> DocumentContainerDict { get; set; }

    private void ThisAddIn_Startup(object sender, EventArgs e)
    {
        DocumentContainerDict = new Dictionary<Document, DocumentContainer>();
        Application.WindowActivate += application_WindowActivate;
        Application.DocumentOpen += application_DocumentOpen;
        Application.DocumentBeforeClose += application_DocumentClose;
    }

    private void application_DocumentOpen(Document doc)
    {
        // define code that is unsafe when document is protected
        Action initialization = () =>
        {
            doc.ContentControls.Add(
                WdContentControlType.wdContentControlRichText,
                doc.Range(doc.Content.Start, doc.Content.End - 1));
        };

        // if the current window isn't "protected", able to execute the unsafe code
        if (Application.ActiveProtectedViewWindow == null)
        {
            initialization();
            initialization = null;
        }

        // send either the unsafe delegate or null to the constructor
        DocumentContainerDict.Add(doc, new VersioningDocumentContainer(initialization));
    }

    private void application_WindowActivate(Document doc, Window wn)
    {
        // skip execution if the window is still protected or isn't the view we want
        if (wn.View.Type != WdViewType.wdPrintView || Application.ActiveProtectedViewWindow != null)
        {
            return;
        }

        DocumentContainer container;

        // find the document container, if any, and the delegate to execute
        if (DocumentContainerDict.TryGetValue(doc, out container)
            && container.ProtectedDeferredExecution != null)
        {
            container.ProtectedDeferredExecution();
            container.ProtectedDeferredExecution = null;
        }
    }

    // clean up
    private void application_DocumentClose(Document doc, ref bool cancel)
    {
        DocumentContainerDict.Remove(doc);
    }
}

其他元数据也可以很容易地在这个容器中定义(这是我用它做的),所以我为每个使用该加载项创建的文档创建一个。