3

VSTOと相互運用機能を使用したMicrosoftWordアドインがあります。DocumentOpenすでに開いているドキュメントに対してイベントが発生した場合、コードに問題が発生します。ドキュメントdoc1を開き、別のドキュメントdoc2を開いてから、もう一度doc1を開こうとすることで、これを一貫して複製することができました。

Doc1はすでに明らかに開いていますが、doc1に対してDocumentOpenイベントが再度発生します。これは意図された設計ですか?もしそうなら、すでに開いているドキュメントに対してイベントが発生しているかどうかを簡単に知る方法はありますか?

private void ThisAddIn_Startup(object sender, System.EventArgs a)
{
  try
  {
    this.Application.DocumentOpen += 
      new MSWord.ApplicationEvents4_DocumentOpenEventHandler(Application_DocumentOpen);

  }
}

private void Application_DocumentOpen(MSWord.Document document)
{
  HandleOpenedDocument(document);
}
4

1 に答える 1

5

ドキュメントを読み、いくつかの経験的研究を行うことで私が知る限り、次の場合にDocumentOpenイベントが発生したように見えます。

  • doc1、doc2、doc1の順に開きます

ただし、次の場合:

  • doc1を開いてからdoc1を再度開くと、イベントはdoc1が最初に開かれたときにのみ発生します。

したがって、ルールは次のようになります。「同じドキュメントを何度も開くと、イベントは1回だけ発生しますが、最近開いたドキュメントとは異なるドキュメントを開くと、新しく開いたドキュメントに対してイベントが発生します。そのドキュメントが実行中のWordのインスタンスですでに開いているかどうかは関係ありません。」

私はドキュメントでこれについての詳細を探していましたが、運がありませんでした。ただし、実際に何が起こっているのかを知りたい場合は、MSDNフォーラムで質問することをお勧めします。MSDNフォーラムでは、一部のMVPが役立つ可能性があります。

次に、あなたは尋ねます:

すでに開いているドキュメントに対してイベントが発生しているかどうかを確認する簡単な方法はありますか?

そして、はい、私は思います:)

基本的に、開いているドキュメントのセットをアプリケーションに保持し、イベントを使用しDocumentOpenDocumentBeforeCloseセットを維持できます。現在開いているドキュメントがわかれば、イベントが発生したときにドキュメントがすでに開いているかどうかを簡単に判断できます。セット内でルックアップを実行するだけで、準備は完了です。

説明のために、Word Interopを使用してこれを実行する方法のサンプル実装を作成しました。私が知る限り、これはほぼ1対1でVSTOにマップされるはずです。コードにいくつかコメントを付けたので、何が起こっているのかを簡単に追跡できるはずです。

using Microsoft.Office.Interop.Word;
using Application = Microsoft.Office.Interop.Word.Application;

namespace WordDocStats
{
    internal class Program
    {
        private static readonly HashSet<Document> OpenDocuments = new HashSet<Document>();

        private static void Main()
        {
            var wordApplication = new Application() { Visible = true };

            // Listen for documents open
            wordApplication.DocumentOpen += WordApplicationDocumentOpen;

            // Listen for documents close
            wordApplication.DocumentBeforeClose += WordApplicationDocumentBeforeClose;

            Console.ReadLine();
            wordApplication.Quit();
        }

        static void WordApplicationDocumentBeforeClose(Document doc, ref bool cancel)
        {
            OpenDocuments.Remove(doc);
            Console.WriteLine(doc.Name + " closed!");
        }

        static void WordApplicationDocumentOpen(Document doc)
        {
            // If this returns true, the doc is not in the set of open documents, hence the doc is not already open
            if(OpenDocuments.Add(doc))
            {
                OpenDocuments.Add(doc);
                Console.WriteLine(doc.Name + " opened...");
            }
            // Otherwise, the doc is already in the set of open documents, hence we know the document is already open
            else
            {
                Console.WriteLine(doc.Name + " is already open!");
            }
        }
    }
}

お役に立てれば!:)

于 2012-11-04T18:02:56.407 に答える