AutoHotkey Community

It is currently May 27th, 2012, 6:31 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: March 11th, 2011, 10:13 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
subj :roll:


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Byref
PostPosted: March 11th, 2011, 12:50 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
subj

_________________
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 11th, 2011, 5:35 pm 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
shajul wrote:
Byref

I need to call a method of a COM object..


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 11th, 2011, 6:05 pm 
A COM object method is not defined by AHK. The COM object method would have to be designed to accept the param ByRef.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 12th, 2011, 7:34 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
It depends on the method, but perhaps ComVar would do the job.

Please put more detail into your posts in future, such as code and what it is you're trying to do. Showing that you made some effort to solve the problem makes it more likely that others will go to the effort of helping you.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 15th, 2011, 9:14 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
Lexikos
Thanks for your reply.

I'm trying to work with the RemoteService 1.0 Type Library (AVerMedia), but my knowledge is not enough.

There are two files generated with TLIBIMP:
REMOTESERVICELib_TLB.cpp
REMOTESERVICELib_TLB.h

I'm creating an object:
Code:
IRemoteCtrl := ComObjCreate("RemoteService.Remote") ; {D56DCE4D-C4AF-438E-A86D-C355F2664B24}
MsgBox, % ""
   . "Variant type:`t" . ComObjType(IRemoteCtrl) . "`n"
   . "Type name:`t" . ComObjType(IRemoteCtrl, "Name") . "`n"
   . "Interface ID:`t" . ComObjType(IRemoteCtrl, "IID")

Message box shows:
Code:
Variant type:   9
Type name:   IRemoteCtrl2
Interface ID:   {CF52E9A5-F2E0-4AB9-AF6D-52AF7AAE1AE5}

Then following two lines are necessary to initialize hardware:
Code:
IRemoteCtrl.Initialize
IRemoteCtrl.DetectHW

Now I need to call GetDeviceNum with reference to nDeviceNum [VT_UINT] and then (for each device) EnumDeviceInfo with reference to hwInfo struct [VARIANT].
Finally, I need to register an event sink for OnRemoteData.
I don't know how to do these steps.
Thanks for any help.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 15th, 2011, 9:54 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Big Digger wrote:
Now I need to call GetDeviceNum with reference to nDeviceNum [VT_UINT]
Firstly, try ComVar as linked in my previous post. If that doesn't work, try changing it as follows and passing 0x17 (i.e. VT_UINT) as a parameter:
Code:
ComVar(vt=0xC)
{
    ...
    arr := ComObjArray(vt, 1)
    ...
    return ... ComObjParameter(0x4000|vt, arr_data) ...
}

Quote:
and then (for each device) EnumDeviceInfo with reference to hwInfo struct [VARIANT].
I have no idea how to handle structs. Once you have the value for nIndex, try using ComVar() as follows and let us know the result:
Code:
var := ComVar()
IRemoteCtrl.EnumDeviceInfo(nIndex, var.ref)
MsgBox % A_LastError " -- " NumGet(ComObjValue(var.ref),0,"ushort")  ; HRESULT -- VarType

Quote:
Finally, I need to register an event sink for OnRemoteData.
You should be able to use ComObjConnect. See the help file for an example.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 15th, 2011, 11:01 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
Lexikos wrote:
Firstly, try ComVar as linked in my previous post. If that doesn't work, try changing it as follows and passing 0x17 (i.e. VT_UINT) as a parameter

Code:
#NoEnv
#SingleInstance Force
OnExit, ExitSub

IRemoteCtrl := ComObjCreate("RemoteService.Remote") ; {D56DCE4D-C4AF-438E-A86D-C355F2664B24}
IRemoteCtrl.Initialize
IRemoteCtrl.DetectHW
nDeviceNum := ComVar()
IRemoteCtrl.GetDeviceNum(nDeviceNum.ref)
Return


ExitSub:
IRemoteCtrl.Uninitialize
ExitApp

; ComVar: Creates an object which can be used to pass a value ByRef.
;   ComVar[] retrieves the value.
;   ComVar[] := Val sets the value.
;   ComVar.ref retrieves a ByRef object for passing to a COM function.
ComVar(vt=0xC)
{
    static base := Object("__Get","ComVarGet","__Set","ComVarSet","__Delete","ComVarDel")
    ; Create an array of 1 VARIANT.  This method allows built-in code to take
    ; care of all conversions between VARIANT and AutoHotkey internal types.
    arr := ComObjArray(vt, 1)
    ; Lock the array and retrieve a pointer to the VARIANT.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; Store the array and an object which can be used to pass the VARIANT ByRef.
    return Object("ref", ComObjParameter(0x4000|vt, arr_data), "_", arr, "base", base)
}
ComVarGet(cv, p*) { ; Called when script accesses an unknown field.
    if p.MaxIndex() = "" ; No name/parameters, i.e. cv[]
        return cv._[0]
}
ComVarSet(cv, v, p*) { ; Called when script sets an unknown field.
    if p.MaxIndex() = "" ; No name/parameters, i.e. cv[]:=v
        return cv._[0] := v
}
ComVarDel(cv) { ; Called when the object is being freed.
    ; This must be done to allow the internal array to be freed.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}

I've tried ComVar() and ComVar(0x17).
Both produce the same error:
Code:
Error:  0x80020005 - Type mismatch.


Specifically: GetDeviceNum

   Line#
   023: base := Object("__Get","ComVarGet","__Set","ComVarSet","__Delete","ComVarDel")
   003: OnExit,ExitSub
   005: IRemoteCtrl := ComObjCreate("RemoteService.Remote")
   006: IRemoteCtrl.Initialize 
   007: IRemoteCtrl.DetectHW 
   008: nDeviceNum := ComVar()
--->   009: IRemoteCtrl.GetDeviceNum(nDeviceNum.ref) 
   010: Return
   014: IRemoteCtrl.Uninitialize 
   015: ExitApp
   022: {
   026: arr := ComObjArray(vt, 1)
   028: DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data) 
   030: Return,Object("ref", ComObjParameter(0x4000|vt, arr_data), "_", arr, "base", base)

Continue running the script?

Code:
Error:  0x80020005 - Type mismatch.


Specifically: GetDeviceNum

   Line#
   023: base := Object("__Get","ComVarGet","__Set","ComVarSet","__Delete","ComVarDel")
   003: OnExit,ExitSub
   005: IRemoteCtrl := ComObjCreate("RemoteService.Remote")
   006: IRemoteCtrl.Initialize 
   007: IRemoteCtrl.DetectHW 
   008: nDeviceNum := ComVar(0x17)
--->   009: IRemoteCtrl.GetDeviceNum(nDeviceNum.ref) 
   010: Return
   014: IRemoteCtrl.Uninitialize 
   015: ExitApp
   022: {
   026: arr := ComObjArray(vt, 1)
   028: DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data) 
   030: Return,Object("ref", ComObjParameter(0x4000|vt, arr_data), "_", arr, "base", base)

Continue running the script?

I've found example implementations for Delphi (maybe it can help):
Code:
.........
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, REMOTESERVICELib_TLB, StdCtrls, ComObj, ActiveX, EvSink;
..............

  TfmIREventHandler = class(TForm)
.................
    procedure OnRemoteData(nKeyFun: SYSUINT; nKey: SYSUINT; dwKeyCode: LongWord);
//обработчик обязательно должен находится в секции published описания формы
.........
  private
    DevNum : Cardinal;
    RemoteCtrl : Remote;
    EventSink: IEventSink;
............
  end;

var
  fmIREventHandler: TfmIREventHandler;

implementation
..............
procedure TfmIREventHandler.FormCreate(Sender: TObject);
begin
............
 RemoteCtrl := CoRemote.Create;
//создаем COM Automation-объект
end;
............
procedure TfmIREventHandler.FormShow(Sender: TObject);
var hwInfo: tagHWINFO;
    i : integer;
begin
//без этих двух строчек эвент работать не будет
  RemoteCtrl.Initialize;
  RemoteCtrl.DetectHW;
//получаем к-во пультов
  RemoteCtrl.GetDeviceNum(DevNum);
  for I := 0 to DevNum - 1 do
  begin
//получаем информацию по каждому пульту
    RemoteCtrl.EnumDeviceInfo(I, hwInfo);
    with hwInfo do
    begin
      ShowMessage(
        Format( 'Device name : %s' + #13#10 +
                'Device PnPID : %s' + #13#10 +
                'EnumRemoteID : %d' + #13#10 +
                'EnumMCERemoteID : %d'  + #13#10 +
                'CurRemoteID : %d' + #13#10 +
                'SelectedAP : %d' + #13#10 +
                'IsRemoteSupport : %d' + #13#10 +
                'IsEnable : %d' + #13#10 +
                'IRemoteControlEnumEx : %d' + #13#10 +
                'HWRemoteNotify : %d' + #13#10 +
                'IRemoteControlEnum : %d',
                [szDeviceName, szDevicePNPID, lEnumRemoteID,
                 lEnumMCERemoteID, lCurRemoteID, lSelectedAP,
                 wIsRemoteSupport, bIsEnable, bIRemoteControlEnumEx,
                 bHWRemoteNotify, bIRemoteControlEnum] )
       );
    end;
  end;

  // Создаем обработчик (event sink) и говорим ему, что он должен обрабатывать интерфейс DIID__IRemoteEvents
  EventSink := TEventSink.Create(DIID__IRemoteEvents);
  // теперь связываем sink с обработчиком формы OnRemoteData
  // 1 это DispID метода OnRemoteData в интерфейсе _IRemoteEvents
  EventSink.AddEventHandler(1, fmIREventHandler, 'OnRemoteData');
  // Привязываем эвент к COM-источнику
  EventSink.Connect(RemoteCtrl);     
end;

procedure TfmIREventHandler.OnRemoteData(nKeyFun, nKey: SYSUINT; dwKeyCode: LongWord);
begin
  ShowMessage(IntToStr(nKeyFun));
  //Здесь делаем то, что нам нужно. nKeyFun - код нажатой клавиши (1-54)
end;


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 15th, 2011, 12:52 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
I don't have any other ideas. It looks like Delphi handles it transparently.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 16th, 2011, 9:03 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
Quiet sad to know. Thanks anyway.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], hd0202 and 61 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group