简单的COM/DCOM问题的一个例题如下所示,不是很懂,谁给讲一下,顺便放分!,

madyak 2003-05-27 03:57:32
delphi 5开发人员指南,748页实现COM客户端的事件处理:如下代码
...
TEventSink = class(TObject, IUnknown, IDispatch)
private
FController: TMainForm;
{ IUnknown }
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
{ IDispatch }
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
public
constructor Create(Controller: TMainForm);
end;


上面代码是基于D5的,很麻烦,由于D6,D7对COM做了改进,于是在D7下改为如下:

TEventSink = class(TComponent, IUnknown, IDispatch)
private
FController: TMainForm;

function QueryInterface(const IID: TGUID; out obj): HResult; stdcall;
function Invoke(DispID: integer; const IID: TGUID; LocateID: integer;
Flags: word; var Params; varResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
public
constructor Create(Controller: TMainForm);
end;

经简单测试,能够正常运行!

疑惑点,
1.这样改行不行?及原因?
2.TComponent类已实现了上面所有private域的函数!
但改进的方法中又实现了一次QueryInterface及Invoke来满一些需要,看上去即不是重载也不是覆盖,是隐藏了以前实现的方法吗?
这种情况怎么处理较好?


...全文
43 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
blueshu 2003-05-27
  • 打赏
  • 举报
回复
接分
myling 2003-05-27
  • 打赏
  • 举报
回复
TComponent类已实现了上面所有private域的函数!

_______________________________________________________________________


确实。但是仔细看看原先声明的是在protected域呀,

而且 QueryInterface还是个 virtual 的:-)
chechy 2003-05-27
  • 打赏
  • 举报
回复
我猜想IDispatch应该是从IUnknown继承的。所以,你甚至不需要在你的类中完成IUnknown的这些方法。
TComponent应该完成呢IComponent这个接口,IComponent应该是从IDispatch继承的,所以你很多方法都不需要完成了。
madyak 2003-05-27
  • 打赏
  • 举报
回复
TEventSink = class(TObject, IUnknown, IDispatch)
是事件接收器!
yyfzy 2003-05-27
  • 打赏
  • 举报
回复
UP
Taken 2003-05-27
  • 打赏
  • 举报
回复
来学习的,帮你up
madyak 2003-05-27
  • 打赏
  • 举报
回复
TEventSink = class(TComponent, IUnknown, IDispatch)是实现接收器的类,由自动化服务器调用
function Invoke(DispID: integer; const IID: TGUID; LocateID: integer;
Flags: word; var Params; varResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
直接用TComponent的实现不行,因为我要根据传入的DispID调度号来分配自定义事件
是这样实现的
function TEventSink.Invoke(DispID: integer; const IID: TGUID; LocateID: integer;
Flags: word; var Params; varResult, ExcepInfo, ArgErr: Pointer):
HResult;
var
V: OleVariant;
begin
Result := S_OK;
case DispID of
201:
begin
// First parameter is new string
V := OleVariant(TDispParams(Params).rgvarg^[0]);
FController.OnServerMemoChanged(V);
end;
202: FController.OnClear;
end;
end;

而以前的TComponent是这样实现的
function TComponent.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
begin
if FVCLComObject = nil then
Result := E_NOTIMPL
else
Result := IVCLComObject(FVCLComObject).Invoke(DispID, IID, LocaleID,
Flags, Params, VarResult, ExcepInfo, ArgErr);
end;

还有
function QueryInterface(const IID: TGUID; out obj): HResult; stdcall;
也存在这种情况.

我也试过了,如果不再实现一次,有些事件不能触发!

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧