我想实现如下所述的IOleMessageFilter:
我找到了一个很好的Delphi实现:
(见答案中的更新#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),并且仍然能够与期望IMessageFilter (在RegisterFilter()方法中使用)的CoRegisterMessageFilter()一起使用它?
我曾试图声明:
IOleMessageFilter = interface(IMessageFilter)
procedure RegisterFilter;
procedure RevokeFilter;
end;
TOleMessageFilter = class(TInterfacedObject, IOleMessageFilter)
...
end; 但是,调用CoRegisterMessageFilter会引发一个错误:
接口不支持。
编辑:
我还试图将TOleMessageFilter声明为:
TOleMessageFilter = class(TInterfacedObject, IMessageFilter, IOleMessageFilter)这“似乎”有效,但我不确定它是否正确。
发布于 2017-10-24 15:33:47
拆分两个接口,让TOleMessageFilter保持对实际消息筛选器的引用,这是一个额外的好处,您不必再调用RegisterFilter和RevokeFilter了,构造函数/析构函数将这样做:
program SO46913922;
{$APPTYPE CONSOLE}
{$R *.res}
uses
ActiveX,
Windows,
SysUtils;
type
IOleMessageFilter = interface
['{0ECA5DA7-F6C7-4D21-8FD3-872558F88CBE}']
procedure RegisterFilter;
procedure RevokeFilter;
end;
TMessageFilter = 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;
end;
TOleMessageFilter = class(TInterfacedObject, IOleMessageFilter)
private
Filter : IMessageFilter;
procedure RegisterFilter;
procedure RevokeFilter;
public
constructor Create;
destructor Destroy; override;
end;
function TMessageFilter.HandleInComingCall(dwCallType: Integer; htaskCaller: HTask; dwTickCount: Integer; lpInterfaceInfo: PInterfaceInfo): Longint;
begin
Result := 0;
end;
function TMessageFilter.MessagePending(htaskCallee: HTask; dwTickCount, dwPendingType: Integer): Longint;
begin
Result := 2 //PENDINGMSG_WAITDEFPROCESS
end;
function TMessageFilter.RetryRejectedCall(htaskCallee: HTask; dwTickCount, dwRejectType: Integer): Longint;
begin
Result := -1;
if dwRejectType = 2 then
Result := 99;
end;
procedure TOleMessageFilter.RegisterFilter;
var
OldFilter: IMessageFilter;
begin
OldFilter := nil;
Filter := TMessageFilter.Create;
CoRegisterMessageFilter(Filter,OldFilter);
end;
procedure TOleMessageFilter.RevokeFilter;
var
OldFilter: IMessageFilter;
NewFilter: IMessageFilter;
begin
OldFilter := nil;
NewFilter := nil;
CoRegisterMessageFilter(NewFilter,OldFilter);
Filter := nil;
end;
constructor TOleMessageFilter.Create;
begin
RegisterFilter;
end;
destructor TOleMessageFilter.Destroy;
begin
RevokeFilter;
inherited;
end;
var
Filter : IOleMessageFilter;
begin
try
CoInitialize(nil);
Filter := TOleMessageFilter.Create;
Readln; // do something
Filter := nil;
finally
CoUninitialize();
end;
Readln;
end.https://stackoverflow.com/questions/46913922
复制相似问题