Automation object 问题(100分)

  • 主题发起人 主题发起人 Adanz
  • 开始时间 开始时间
A

Adanz

Unregistered / Unconfirmed
GUEST, unregistred user!
建立一个带事件支持的Automation object COM (进程外.EXE),其中包含一个
主窗口(mainForm).例如Automation object其中有一个事件方法event1.
在Automation object模块中可以正常触发Fire_event1,
但在主窗口中如何触发这个事件呢?
 
引用你得Automation object单元
mainForm.button1.onclick:=你的Comobj(DCOM).事件
 
好象不行,能否说详细点
 
你下载一个EventSinkImp,然后用它来导入类型库。下面是我用过的部分代码。
function TCommClient.DoInvoke (DispID: Integer;
const IID: TGUID;
LocaleID: Integer;
Flags: Word;
var dps: TDispParams;
pDispIds: PDispIdList;
VarResult, ExcepInfo, ArgErr: Pointer): HResult;
type
POleVariant = ^OleVariant;
begin
Result := DISP_E_MEMBERNOTFOUND;
case DispId of
1 :
begin
do
OnData(OleVariant(dps.rgvarg^[pDispIds^[0]]), dps.rgvarg^[pDispIds^[1]].bstrval, dps.rgvarg^[pDispIds^[2]].plval^);
Result := S_OK;
end;
end;
{ case }
end;

procedure TCommClient.DoOnData(aData: OleVariant;
const aSource: WideString;
out aAction: Integer);
var
S : TMemoryStream;
P : Pointer;
L : Integer;
begin
if Assigned(FOnData) then
try
S := TMemoryStream.Create;
try
//将传过来的安全数组转换为TStream类型,触发事件
L := VarArrayHighBound(aData, 1) - VarArrayLowBound(aData, 1) + 1;
P := VarArrayLock(aData);
try
S.Seek(0, soFrombegin
ning);
S.WriteBuffer(P^, L);
finally
VarArrayUnlock(aData);
end;

FOnData (Self, S, aSource, aAction);
finally
S.Free
end;
except
on E: Exceptiondo
begin
TLogFile.WriteLn('数据接收处理出错, 错误信息="%s"', [E.Message]);
end;
end;
end;

下面这部分代码是Server端的,负责触发事件。
procedure TNotifyThread.doExecute;
var
Header: TMessageHeader;
Action: Integer;
S : String;
begin
try
Action := 0;

FData.Clear;
FRecvQueue.Get(FData, Header, False);
S := GetCurrentDir;
//保存当前工作目录, 避免Ondata处理时无意中更改了工作目录
try
try
if Assigned(FOnData) then
FOnData(FData, Header.Source, Action);
except
on E: Exceptiondo
begin
TLogFile.WriteLn('数据接收事件处理失败, 错误信息="%s"', [E.Message]);
end;
end;
finally
SetCurrentDir(S);
//恢复当前工作目录
end;

if Action > 0 then
FRecvQueue.Commit(tmGet)
else
FRecvQueue.RollBack(tmGet);
except
on E: Exceptiondo
begin
FRecvQueue.RollBack(tmGet);
raise;
end;
end;
end;
 
这个问题不涉及到客户端,主要在服务端
因为(我用BCB),服务端生成的Automation object代码在
单独的AutotestImpl.cpp(h)类里面,在里面可以正常引用
主窗口(Form1)的全部操作,但在Form1中却不能引用
AutotestImpl.cpp(h)的事件方法Fire_Event1(...).
我的主要目的是主窗口Form1事件或过程可以引用或触发
AutotestImpl.cpp(h)中的事件方法,从而向客户端发出
相应事件.
客户端Skin事件很顺利.
没有COM方面的专家可以指点?
 
如果象tseug说的那样,那你取看看delphi COM深入编程,那里面有说事件的编写和调用方法
但是你说的那样子的情况我还没试,还不清楚你什么意思:D
 
如果像你说的那样,估计不是COM的问题,你还是看看你的代码之间相互引用的问题吧
 
后退
顶部