Assign IDIspatch events with in/out parameters

Hi!

I really need to assign some events in my code through an IDisaptch interface.
At http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20418739.html I've found a class that solved almost all my problems. The events are triggered just fine, however, ALL my events have [in/out] parameters and that code has bugs, since it does not handles it.

I've tried to solve the problem using something like (using an hardcode solution):

function TComEvents.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
var  a : TDISPParams absolute params;
begin
   result:=S_OK;
   a.rgvarg^[0].lval := 123;
 end;
end;


However, it didn't work... the value passed still wasn't changed. Can you please help me?

thanks

Joao Santos



LVL 1
jpcsAsked:
Who is Participating?
 
mocartsConnect With a Mentor Commented:
ok, I think that will be better. you can mail me to helmuts@microlink.lv
0
 
mocartsCommented:
it's because Params is of pointer type..
better use typecasting:
function TComEvents.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
begin
  result:=S_OK;
  TDISPParams(a^).rgvarg[0].lval := 123;
end;
end;

wbr, mo.
0
 
mocartsCommented:
sorr :)
TDISPParams(Params^).rgvarg[0].lval := 123;

mo.
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
jpcsAuthor Commented:
I get the error Pointer type required just after TDISPParams(Params^)
0
 
mocartsCommented:
uff.. I didn't observe ';' in the declaration so I thought it is a pointer type..
you must use Params without dereference char '^'
however I've tested both (TDISPParam(Params).. and var with absolute addressing) variations of code in simple procedure calls and they works well (changes value)
so you must look on the other side. how Params is passed and used?
wbr, mo.
0
 
jpcsAuthor Commented:
Can I send you my test application by email?

Can you tell me your email?
0
 
jpcsAuthor Commented:
Answer from mocarts :
--------------


Hi!
I can't currently connect to EE due to limitations of foreign country internet
traffic..
so, I solved the problem :)
the problem was in fact that OleVariant doesn't handle ByRef type..
you should check type of TDISPParams(Params).rgvarg^[0] by using vt member.
in long * case it is plVal (VT_BYREF or VT_I4 = $4003)
i.e.
TDISPParams(Params).rgvarg^[0]).plVal^ := 5;
assignment will work as it must work (changes value) in TComEvents.Invoke
method.
and you can't simply pass to event handler casted args as it invokes type
conversion from byref to simple type..
so here will be modified Invoke method of TComEvents:

function TComEvents.Invoke(DispID: Integer; const IID: TGUID; LocaleID:
Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
HResult;
var
  szEvent: String;
  index, count, i: Integer;
  evVar: Tvariantarray;
begin
 Result:=S_OK;
 // Make sure the OnEvent is assigned
 if not(Assigned(FEvent)) then exit;
 // Get the event name using the dispacth id. Exit if unable to find DispID
 index := FEventIDs.IndexOf(Pointer(DispID));
 if (index < 0) then exit
   else szEvent := FEvents[index];
 // Get parameter count
 count := TDispParams(Params).cArgs;
 // we must copy args to prevent from type change
 setLength(evVar, count);
 for i := 0 to count -1 do
   evVar[i] := OleVariant(TDispParams(Params).rgvarg^[i]);
 // calling event
 if Assigned(FEvent) then
    FEvent(FObj, szEvent, DispID, evVar);
 // copying back all values passed ByRef
 for i := 0 to count -1 do
  with TDISPParams(Params) do
   if rgvarg^[i].vt and VT_BYREF = VT_BYREF then begin
     with rgvarg^[i] do
     case vt of
      VT_BYREF or VT_UI1:      pbVal^ := evVar[i];
      VT_BYREF or VT_I2:       piVal^ := evVar[i];
      VT_BYREF or VT_I4:       plVal^ := evVar[i];
      VT_BYREF or VT_R4:       pfltVal^ := evVar[i];
      VT_BYREF or VT_R8:       pdblVal^ := evVar[i];
      VT_BYREF or VT_BOOL:     pbool^ := evVar[i];
      VT_BYREF or VT_DATE:     pdate^ := evVar[i];
      VT_BYREF or VT_BSTR:     pbstrVal^ := evVar[i];
      VT_BYREF or VT_UNKNOWN:  punkVal^ := evVar[i];
      VT_BYREF or VT_DISPATCH: pdispVal^ := evVar[i];
      VT_BYREF or VT_VARIANT:  pvarVal^ := evVar[i];
      VT_BYREF or VT_UI4:      pulVal^ := evVar[i];
      VT_BYREF or VT_INT:      pintVal^ := evVar[i];
      VT_BYREF or VT_UINT:     puintVal^ := evVar[i];
     end;
   end;
end;

good luck!
0
 
jpcsAuthor Commented:
Thanks a lot!
0
All Courses

From novice to tech pro — start learning today.