【问题标题】:IAdviseSink setup for catching MSWord document events用于捕获 MSWord 文档事件的 IAdviseSink 设置
【发布时间】:2012-01-27 08:40:42
【问题描述】:

这是我尝试设置在我的TForm1 类中实现的IAdviseSink 接口的代码,用于捕获新创建的MSWord 文档的一些事件。代码运行时我没有任何错误,但是在保存文档或关闭文档时我无法捕获任何事件。 如何为 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;

【问题讨论】:

  • 通过该设置,当我关闭文档时,OnClose 在这里很好地触发,当我保存文档时,'OnRename' 触发,当我再次使用新名称保存时,'OnRename' 触发。什么给了?
  • 'OnClose' 示例here,但我还没有测试其他事件..

标签: delphi events ms-word ole-automation


【解决方案1】:

不完全是答案,但是...

您是否有特别的原因要重新发明轮子并自己完成整个Advise-事情?为什么不直接使用与 Delphi 捆绑在一起的 Word2000-unit 中的 TWordDocument 包装类(在这种情况下,您所要做的就是调用 ConnectTo() 并分配您的事件处理程序)?但是,Document 对象没有OnSave 事件(至少在 2000 版本的 TLB 中没有,如果您希望您的应用程序与多个版本的 Office 兼容,这通常是一个很好的共同点)。 Application 对象确实有一个 BeforeDocumentSave 事件,不过...

【讨论】:

    【解决方案2】:

    编辑:

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


    为什么选择演员IAdviseSink(Self)

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

    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) 那样简单的硬转换,它基本上告诉编译器关闭并将 SomePointer 视为 TForm。然后,接口转换提示编译器检查正在转换的实例是否实际支持该接口。不知道那个。每天学习新东西。

    【讨论】:

    • @Sertac:为什么不呢?它在我的机器(D2010)上编译得很好。
    • 我不是说演员。如果表单没有实现 IAdviseSink,则 Advise(Self.. 将无法编译。 Advise(IAdviseSink(Self), .. 都没有给出 'Incompatible types..' 这里。
    • @Sertac:啊,我明白你的意思了。所以接口转换并没有我想象的那么难......应该开始更多地使用接口......
    猜你喜欢
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多