这是我尝试设置的代码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;
Edit:
别介意这个答案。将其保留用于教育目的。
为什么选演员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”
The IAdviseSink(Self)
显然不是一个简单的硬演员TForm(SomePointer)
is,它基本上告诉编译器关闭并将 SomePointer 视为 TForm。然后,接口强制转换会提示编译器检查正在强制转换的实例是否确实支持该接口。不知道。每天学些新东西。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)