用于捕获MSWord文档事件的IAdviseSink设置

And*_*yna 5 delphi events ms-word ole-automation

下面是我尝试IAdviseSink在我的TForm1类中设置接口以捕获新创建的MSWord文档的一些事件的代码.代码运行时我没有任何错误,但我无法捕获任何事件,同时保存文档或关闭它.如何IAdviseSink正确设置MSWord文档?


    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;

Mar*_*ema 0

编辑:

别介意这个答案。将其保留用于教育目的。


为什么是演员阵容IAdviseSink(Self)

如果您在 Form 的类声明中声明了接口:

TForm1 = class(TForm, IAdviseSink)
   ...
end;
Run Code Online (Sandbox Code Playgroud)

,你不应该这样做。

事实上,您使用了强制转换(以及只是告诉编译器关闭的硬强制转换),可能表明您没有这样做。这很可能会导致调度机制发现您的表单没有实现 IAdviseSink,因此没有任何内容可以调用 OnSave 方法。


解释为什么上述不是问题:

起初我不明白 Sertac 的评论“但是代码无法编译”。他的意思是,如果不IAdviseSink成为表单类声明的一部分,则该行

doc_ole_obj.Advise(IAdviseSink(Self), Connection);
Run Code Online (Sandbox Code Playgroud)

会导致 [DCC 错误] Unit1.pas(41): E2010 不兼容的类型:“IAdviseSink”和“TForm1”

显然这IAdviseSink(Self)不是一个简单的硬转换TForm(SomePointer),它基本上告诉编译器关闭并将 SomePointer 视为 TForm。然后,接口强制转换会提示编译器检查正在强制转换的实例是否确实支持该接口。不知道。每天学些新东西。