2011-12-24 9 views
5

ここに、IAdviseSinkインターフェイスを実装して、私のTForm1クラスに新しく作成されたMSWordドキュメントのイベントをキャッチするコードを示します。コードを実行している間はエラーはありませんが、ドキュメントを保存したり閉じたりしても、イベントを捕捉することはできません。 MSWord文書用にIAdviseSinkを正しく設定するにはどうすればよいですか?MSWordドキュメントイベントを捕捉するためのIAdviseSinkセットアップ

 

    var 
     Form1 : TForm1; 
     doc_ole_obj : IOleObject; 
     word : IDispatch; 
     Connection: LongInt; 

    implementation 

    //------------ Setup IAdviseSink 
    procedure TForm1.Setup; 
    begin 
    word := CreateOleObject('Word.Application'); 
    OleVariant(word).Visible := True; 

    IUnknown(OleVariant(word).Documents.Open('file.doc')).QueryInterface(IOleObject,doc_ole_obj); 
    doc_ole_obj.Advise(IAdviseSink(Self), Connection); 
    end; 

    //------------- catch Sink events 
    procedure TForm1.OnSave; 
    begin 
     Caption := 'saved at ' + TimeToStr(Now); 
    end; 
 
+0

この設定では、ドキュメントを閉じるときにOnCloseが正常に発生します。新しい名前で再度保存すると、 'OnRename' OnRename 'が発生します。何がありますか? –

+1

'OnClose'の例[here](http://stackoverflow.com/a/2886747/243614)、他のイベントをテストしていません。 –

答えて

0

編集:

この回答を気にしません。教育的な目的のためにそれを残す。なぜキャストIAdviseSink(Self)


あなたがフォームのクラス宣言でインターフェースを宣言した場合:

TForm1 = class(TForm, IAdviseSink) 
    ... 
end; 

、あなたがする必要はありません。

キャストを使用するという事実と、単にコンパイラにシャットダウンするよう指示するハードキャストは、あなたがしなかったことを示している可能性があります。そして、それはあなたのフォームがIAdviseSinkを実装していないため、OnSaveメソッドを呼び出すことが何もないことを発見するディスパッチメカニズムを引き起こす可能性があります。上記は問題ではない理由の


説明:

私はSertacのコメントを理解していなかった「しかし、その後のコードはコンパイルされないでしょう」最初に。彼はIAdviseSinkは、フォームのクラス宣言の一部でなくて、

doc_ole_obj.Advise(IAdviseSink(Self), Connection); 

ラインは、[DCCのエラー] Unit1.pas(41)を引き起こすことを意味:E2010互換性のないタイプ: 'IAdviseSink' と 'TForm1'

IAdviseSink(Self)は、明らかに、TForm(SomePointer) isのようなシンプルなハードキャストではありません。これは基本的にSomePointerをシャットダウンしてTFormとして扱うようにコンパイラに指示します。その後、インタフェースキャストは、実際にキャストされているインスタンスがインタフェースをサポートしているかどうかをコンパイラに確認するように促します。それを知らなかった。毎日何か新しいことを学ぶ。

+3

しかし、コードはコンパイルされませんでした.. –

+0

@Sertac:どうしてそうではありませんか?それは私のマシン(D2010)で正常にコンパイルされます。 –

+0

私はキャストを意味しませんでした。フォームがIAdviseSinkを実装していなかった場合、 'Advise(Self..'はコンパイルされませんでした。)' Advise(IAdviseSink(Self)、..'はここに*互換性のない型.. *を与えません –

0

ない正確な答えが...

あなたが車輪の再発明し、自分自身を-thing全体Adviseをしたい特別な理由はありますか? Delphiに同梱されているWord2000-unitのTWordDocumentラッパークラスを使用しないでください(この場合は、ConnectTo()を呼び出してイベントハンドラを割り当ててください)。しかし、DocumentオブジェクトにはOnSaveイベントがありません(少なくとも、TLBの2000バージョンにはありません。これは、お使いのアプリが複数のバージョンのOfficeと互換性を持つようにするには、一般的には共通の分母です)。 ApplicationオブジェクトにはBeforeDocumentSave -eventがありますが...

関連する問題