Com组件的使用,多多帮助.(200分)

  • 主题发起人 主题发起人 cnzzlp
  • 开始时间 开始时间
C

cnzzlp

Unregistered / Unconfirmed
GUEST, unregistred user!
导入一个dll,此组件是测服务器端和客户端之间的带宽.com方面不熟,请大家帮助应该如果使用,分不够再加.谢谢了.

unit CBandWidthLib_TLB;

// ************************************************************************ //
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************ //

// PASTLWTR : 1.2
// File generated on 2006-7-17 17:15:52 from Type Library described below.

// ************************************************************************ //
// Type Lib: D:/NetTest/CBandWidth.dll (1)
// LIBID: {D1C11CCF-35C4-4227-BA72-4E4D96B018DF}
// LCID: 0
// Helpfile:
// HelpString: CBandWidth 1.0 类型库
// DepndLst:
// (1) v2.0 stdole, (C:/WINDOWS/system32/STDOLE2.TLB)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, OleServer, StdVCL, Variants;


// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
CBandWidthLibMajorVersion = 1;
CBandWidthLibMinorVersion = 0;

LIBID_CBandWidthLib: TGUID = '{D1C11CCF-35C4-4227-BA72-4E4D96B018DF}';

DIID__IBandTestEvents: TGUID = '{2ADC5FC3-CD4F-47EC-A629-7A6A5A1F636B}';
IID_IBandTest: TGUID = '{DFAEAAE1-3A8D-4903-80A6-4028A791C830}';
CLASS_BandTest: TGUID = '{470A7DA3-6DFA-4021-8344-19B40E94BD58}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
_IBandTestEvents = dispinterface;
IBandTest = interface;
IBandTestDisp = dispinterface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
BandTest = IBandTest;


// *********************************************************************//
// DispIntf: _IBandTestEvents
// Flags: (4096) Dispatchable
// GUID: {2ADC5FC3-CD4F-47EC-A629-7A6A5A1F636B}
// *********************************************************************//
_IBandTestEvents = dispinterface
['{2ADC5FC3-CD4F-47EC-A629-7A6A5A1F636B}']
procedure OnGetValve(lstart: Integer;
lstop: Integer;
const sBandWidth: WideString);
dispid 1;
end;


// *********************************************************************//
// Interface: IBandTest
// Flags: (4544) Dual NonExtensible OleAutomation Dispatchable
// GUID: {DFAEAAE1-3A8D-4903-80A6-4028A791C830}
// *********************************************************************//
IBandTest = interface(IDispatch)
['{DFAEAAE1-3A8D-4903-80A6-4028A791C830}']
procedure StartTest;
safecall;
procedure setOption(const sType: WideString;
const sValue: WideString);
safecall;
end;


// *********************************************************************//
// DispIntf: IBandTestDisp
// Flags: (4544) Dual NonExtensible OleAutomation Dispatchable
// GUID: {DFAEAAE1-3A8D-4903-80A6-4028A791C830}
// *********************************************************************//
IBandTestDisp = dispinterface
['{DFAEAAE1-3A8D-4903-80A6-4028A791C830}']
procedure StartTest;
dispid 1;
procedure setOption(const sType: WideString;
const sValue: WideString);
dispid 2;
end;


// *********************************************************************//
// The Class CoBandTest provides a Create and CreateRemote method to
// create instances of the default interface IBandTest exposed by
// the CoClass BandTest. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoBandTest = class
class function Create: IBandTest;
class function CreateRemote(const MachineName: string): IBandTest;
end;


implementation

uses ComObj;

class function CoBandTest.Create: IBandTest;
begin

Result := CreateComObject(CLASS_BandTest) as IBandTest;
end;


class function CoBandTest.CreateRemote(const MachineName: string): IBandTest;
begin

Result := CreateRemoteComObject(MachineName, CLASS_BandTest) as IBandTest;
end;


end.
 
流程是: setoption-->starttest-->怎么onGetValue得到值?
 
先创建一个CoBandTest对象他的构造函数返回一个IBandTest接口,使用这个接口调用它的借口方法StartTest
 
帮你提前
 
var
Form1: TForm1;
MyBand :IBandTest;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin

MyBand.setOption('c','192.168.19.150');
MyBand.StartTest;//测试带宽,以后不知道怎么调onGetValue得到数据.

end;


procedure TForm1.FormCreate(Sender: TObject);
begin

MyBand := CoBandTest.Create;
// MyBand.in

end;
 
最近正在学习COM+
帮顶并听课:)
 

QueryInterface得到接口
 
To: lqcros
能详细些不?这方面的确不太清楚,
 
请参考:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=860750
 
同意楼上,已经可以解决你的问题。
 
我现在还不确定我定义接口的操作是否正确.?
to:楼上两位老兄,我还迷茫中..
 
com,com+不熟悉
 
楼上已经有人指出了方法
而且给出了URL
建议楼主多参考资料
 
在 Import Type Libary 的时候,选择“Install”,
这时你在组件面板里面找到的对应组件,它有你的事件。

像使用VCL一样使用它。
 
方法1:
如果CBandWidth.dll 不是你自己开发的,而是一个成熟的产品,那么采用darnis的方法就可以最简单的使用这个com组件。
通过delphi的IDE,在菜单project-〉Import Type Libary 中,选择
[TestComEventServer Library]后,“Install”,可以将该com当作
控件导入,控件默认在ActiveX控件页上,客户端事件都已经建好!

这种方法的缺点:
1)如果是自己编制com组件,则每次修改server端后,发布同步比较麻烦!
2)即使服务端事件被描述成function(带返回值),导入的控件也只是procedure, 不能使用事件返回值。
-------------------------------------
方法2:就是采用http://www.delphibbs.com/delphibbs/dispq.asp?lid=860750 里面wbcp2000给出的代码,略加修改,可以达到完全自主的控制该com组件的运行时自动触发客户端的自己定义的事件。修改后代码参考下面:其实就是在客户端构造一个事件接受器,通过该接受器TEventSink达到自己触发客户端事件的目的。
unit CliMain;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,
//////本例子中添加
ActiveX, CBandWidthLib_TLB, ComObj;

type
TEventSink = class;

TForm1 = class(TForm)
Button1: TButton;

procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
MyBand: IBandTest;
//com 接口
FEventSink: TEventSink;
FCookie: Integer;

//这里描述服务端的事件,它们将被在客户端被激发
procedure OnGetValve(lstart: Integer;
lstop: Integer;
const sBandWidth: WideString);

public
{ Public declarations }
end;


TEventSink = class(TObject, IUnknown, IDispatch)
private
FController: TForm1;
//<-- 这里改成 容器Form的类型
{ 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: TForm1);
//<-- 这里改成 容器Form的类型
end;


var
MainForm: TForm1;

implementation

uses ActiveX;

//{$R *.DFM}

//------------------------------------------------------------------------------
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin

MyBand := IBandTest.Create;
FEventSink := TEventSink.Create(Self);
InterfaceConnect(MyBand, _IBandTestEvents, FEventSink, FCookie);
//这里绑定事件接受器
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin

//释放
InterfaceDisconnect(FEventSink, _IBandTestEvents, FCookie);
//
FEventSink.Free;
FEventSink := nil;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin

MyBand.setOption('c','192.168.19.150');
MyBand.StartTest;//测试带宽,以后不知道怎么调onGetValue得到数据.

//下面OnGetValve事件将被触发
//。。。
end;





//------------------------------------------------------------------------------
//这里是将在本地客户端被激发的事件 //^^^9^^^^
procedure TForm1.OnGetValve(lstart: Integer;
lstop: Integer;
const sBandWidth: WideString);
begin

//在客户端被激发的事件中

end;








//------------------------------------------------------------------------------
{ TEventSink }
constructor TEventSink.Create(Controller: TForm1);
begin

FController := Controller;
inherited Create;
end;


{ TEventSink.IUnknown }

function TEventSink._AddRef: Integer;
begin

// No need to implement, since lifetime is tied to client
Result := -1;
end;


function TEventSink._Release: Integer;
begin

// No need to implement, since lifetime is tied to client
Result := -1;
end;


function TEventSink.QueryInterface(const IID: TGUID;
out Obj): HResult;
begin

// First look for my own implementation of an interface
// (I implement IUnknown and IDispatch).
if GetInterface(IID, Obj) then

Result := S_OK
// Next, if they are looking for outgoing interface, recurse to return
// our IDispatch pointer.
else
if IsEqualIID(IID, _IBandTestEvents) then
//客户端事件接口
Result := QueryInterface(IDispatch, Obj)
// For everything else
, return an error.
else

Result := E_NOINTERFACE;
end;


{ TEventSink.IDispatch }

function TEventSink.GetIDsOfNames(const IID: TGUID;
Names: Pointer;
NameCount, LocaleID: Integer;
DispIDs: Pointer): HResult;
begin

Result := E_NOTIMPL;
end;


function TEventSink.GetTypeInfo(Index, LocaleID: Integer;
out TypeInfo): HResult;
begin

Pointer(TypeInfo) := nil;
Result := E_NOTIMPL;
end;


function TEventSink.GetTypeInfoCount(out Count: Integer): HResult;
begin

Count := 0;
Result := S_OK;
end;


function TEventSink.Invoke(DispID: Integer;
const IID: TGUID;
LocaleID: Integer;
Flags: Word;
var Params;
VarResult, ExcepInfo,
ArgErr: Pointer): HResult;
var
V1, V2, V3: OleVariant;
begin

Result := S_OK;
case DispID of
-1: Exit;
// DISPID_UNKNOWN
1:
begin

//注意:参数顺序是《反》的。
V1 := OleVariant(TDispParams(Params).rgvarg^[2]);
V2 := OleVariant(TDispParams(Params).rgvarg^[1]);
V3 := OleVariant(TDispParams(Params).rgvarg^[0]);

//在这里接受服务端的触发操作后,自己再调用客户端的事件。
FController.OnGetValve(V1, V2, V3);
end;

end;

end;


end.
 
多人接受答案了。
 
后退
顶部