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;