私がここで説明したようIOleMessageFilter
を実装する:TInterfacedObjectを使用して既存のインターフェースIMessageFilterを拡張する方法は?
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`
(解答でUPDATE#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;
この正確なデルファイコードは、Web上の他の多くのサイトにあります。ここまでは順調ですね。私はの代わりにクラス名をTOleMessageFilter
に変更しました。
しかし、使い方はちょっと面倒です。私がしたいことはインターフェイスなどとして宣言されるように、Filter
ある
var
Filter: TOleMessageFilter;
Filter := TOleMessageFilter.Create;
Filter.RegisterFilter;
...
Filter.RevokeFilter;
Filter.Free;
IOleMessageFilter
。
var
Filter: IOleMessageFilter;
Filter := TOleMessageFilter.Create as IOleMessageFilter;
Filter.RegisterFilter;
...
Filter.RevokeFilter;
Filter := nil;
であり、自動解放の恩恵を受けるTInterfacedObject
です。
どのように私はTOleMessageFilter = class(TInterfacedObject, IOleMessageFilter)
として実装され、まだIMessageFilter
は(RegisterFilter()
方法で使用される期待するCoRegisterMessageFilter()
でも、それを使うことができているIMessageFilter
から「派生」が、まだ新しい方法RegisterFilter()
とRevokeFilter()
を持って、新しいIOleMessageFilter
を作成してください)?
私は宣言しようとしている:
:私としてもTOleMessageFilter
を宣言しようとしてい
:
IOleMessageFilter = interface(IMessageFilter)
procedure RegisterFilter;
procedure RevokeFilter;
end;
TOleMessageFilter = class(TInterfacedObject, IOleMessageFilter)
...
end;
をしかし、その後CoRegisterMessageFilter
を呼び出すと、エラーがスローされます。
Interface not supported.
はEDIT
TOleMessageFilter = class(TInterfacedObject, IMessageFilter, IOleMessageFilter)
どちらが「うまくいくか」はわかりますが、正しいアプローチであるかどうかはわかりません。
@ whosrdaddy、あなたは 'TOleMessageFilter = class(TInterfacedObject、IMessageFilter、IOleMessageFilter)'を意味しますか? 'RegisterFilter'と' RevokeFilter'メソッドを含む 'IOleMessageFilter'と? – zig
いいえ、私は答えを書いています;)患者さん、 – whosrdaddy