【发布时间】:2018-04-05 10:50:10
【问题描述】:
我想按照这里的描述实现IOleMessageFilter:
How to: Fix 'Application is Busy' and 'Call was Rejected By Callee' Errors
我找到了一个运行良好的 Delphi 实现:
`EOleException: Call was rejected by callee` while iterating through `Office.Interop.Word.Documents`
(请参阅答案中的更新#1)
实现如下所示:
type
TOleMessageFilter = class(TInterfacedObject, IMessageFilter)
public
// IMessageFilter
function HandleInComingCall(dwCallType: Longint; htaskCaller: HTask;
dwTickCount: Longint; lpInterfaceInfo: PInterfaceInfo): Longint;stdcall;
function RetryRejectedCall(htaskCallee: HTask; dwTickCount: Longint;
dwRejectType: Longint): Longint;stdcall;
function MessagePending(htaskCallee: HTask; dwTickCount: Longint;
dwPendingType: Longint): Longint;stdcall;
// TOleMessageFilter
procedure RegisterFilter;
procedure RevokeFilter;
end;
implementation
function TOleMessageFilter.HandleInComingCall(dwCallType: Integer; htaskCaller: HTask; dwTickCount: Integer; lpInterfaceInfo: PInterfaceInfo): Longint;
begin
Result := 0;
end;
function TOleMessageFilter.MessagePending(htaskCallee: HTask; dwTickCount, dwPendingType: Integer): Longint;
begin
Result := 2 //PENDINGMSG_WAITDEFPROCESS
end;
function TOleMessageFilter.RetryRejectedCall(htaskCallee: HTask; dwTickCount, dwRejectType: Integer): Longint;
begin
Result := -1;
if dwRejectType = 2 then
Result := 99;
end;
procedure TOleMessageFilter.RegisterFilter;
var
OldFilter: IMessageFilter;
NewFilter: IMessageFilter;
begin
OldFilter := nil;
NewFilter := TOleMessageFilter.Create as IMessageFilter;
CoRegisterMessageFilter(NewFilter,OldFilter);
end;
procedure TOleMessageFilter.RevokeFilter;
var
OldFilter: IMessageFilter;
NewFilter: IMessageFilter;
begin
OldFilter := nil;
NewFilter := nil;
CoRegisterMessageFilter(NewFilter,OldFilter);
end;
这个确切的 Delphi 代码可以在网络上的许多其他网站上找到。到目前为止,一切都很好。我只将类名更改为TOleMessageFilter 而不是IOleMessageFilter。
然而,这种用法有点烦人。
var
Filter: TOleMessageFilter;
Filter := TOleMessageFilter.Create;
Filter.RegisterFilter;
...
Filter.RevokeFilter;
Filter.Free;
我想要的是,Filter 被声明为接口,例如IOleMessageFilter。
var
Filter: IOleMessageFilter;
Filter := TOleMessageFilter.Create as IOleMessageFilter;
Filter.RegisterFilter;
...
Filter.RevokeFilter;
Filter := nil;
并且有自动释放TInterfacedObject的好处。
如何创建一个新的IOleMessageFilter,它“派生”自IMessageFilter,但仍有新方法RegisterFilter() 和RevokeFilter(),实现为TOleMessageFilter = class(TInterfacedObject, IOleMessageFilter),并且仍然可以与@ 一起使用987654337@ 需要 IMessageFilter(在 RegisterFilter() 方法中使用)?
我已尝试声明:
IOleMessageFilter = interface(IMessageFilter)
procedure RegisterFilter;
procedure RevokeFilter;
end;
TOleMessageFilter = class(TInterfacedObject, IOleMessageFilter)
...
end;
但随后调用CoRegisterMessageFilter 会引发错误:
不支持接口。
编辑:
我也尝试将TOleMessageFilter 声明为:
TOleMessageFilter = class(TInterfacedObject, IMessageFilter, IOleMessageFilter)
哪种“似乎”可行,但我不确定这是正确的方法。
【问题讨论】:
-
@whosrdaddy,你的意思是
TOleMessageFilter = class(TInterfacedObject, IMessageFilter, IOleMessageFilter)?和IOleMessageFilter包含RegisterFilter和RevokeFilter方法? -
不行,请耐心等待,我正在写一个答案;)