COM Interface delphi to AHK array troubles

Get help with using AutoHotkey and its commands and hotkeys
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

COM Interface delphi to AHK array troubles

29 Apr 2017, 12:00

Hi,

Im working on the DVBViewer COM interface trying to get an associative array containing all Favourite Channels, so that I can enumerate them and assign all channel menu items (14 channels). It seems language differences between c++ and AHK in how to assign arrays makes this quite hard to solve, cuz it is impossible to get the array and enumerate it. When it works Im abled to change channels from the DVBViewer thumbnail Im using. This is the line im passing and there is some COM interface syntax commented in codebox.
hhh := iDVBViewer.FavoritesManager.GetFavorites.Item[Index: Integer] Although you are not abled to test the COM code, but I have to ask if anyone might know something that could work?

Code: Select all

DVBVGuiContextMenu:
If (A_Gui = "DVBV") && (A_GuiEvent = "RightClick") { 
;msgbox % iDVBViewer.Channelmanager.GetbyChannelname("SVT1 HD")
;msgbox % iDVBViewer.CurrentChannel.Name
;msgbox % iDVBViewer.Channelmanager.GetChannelList(List)
;msgbox % iDVBViewer.FavoritesManager.GetFavorites.Count              ; Public property Count: Integer;
hhh := iDVBViewer.FavoritesManager.GetFavorites.Item[Index: Integer]  ; property Item[Index: Integer]: IFavoritesItem;
                                                                      /*The IFavoritesItem list can by accessed like
 																	    an array with an Index from 0 to count-1.
                                                                        Read only Property. Default property.*/
For k, v in hhh
  msgbox %k%=%v%
  
  Menu, DVBVContextMenu, Add
  Menu, DVBVContextMenu, DeleteAll
  Menu, DVBVContextMenu, Add, channel1, channel1
  Menu, DVBVContextMenu, Add, channel2, channel2
  Menu, DVBVContextMenu, Show, %A_GuiX%, %A_GuiY%

}
return
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: COM Interface delphi to AHK array troubles

02 May 2017, 12:47

Please help me read this Delphi array into AHK. It should be possible to do it with help of ComObjArray() since AHK supports arrays containing up to 8 dimensions. Cannot work out how it is supposed to be done.

This creates the array, but I cant enumerate it:

Code: Select all

iDVBViewer := ComObject("DVBViewerServer.DVBViewer")
Arr := iDVBViewer.FavoritesManager.GetFavoritesList(List)
for i, v in Arr
 msgbox %i%=%v% 
msgbox % Arr[Key, 1]
Here is info from the COM interface documentation:
Public function GetFavoritesList(out List: OleVariant): Integer;
Return a list of all favorites as a two-dimensional variant safearray.

List[x,0] := Groupname;
List[x,1] := Name;
List[x,2] := ChannelID
List[x,3] := ID Number

Parameters
List
A variant to be filled with the array.
Returns
The count of the arrayitems in the first dimension.
Here is the Delphi code DVBViewer uses when calling the GetFavoritesList() and enumerates the array:

Code: Select all

  List := VarArrayCreate([0, Get_Count - 1, 0, 3], varVariant);
  for i := 0 to Favourites.Count - 1 do
  begin
    afav := Favourites[i];
    if (afav.Name <> '') and (afav.IDStr <> '') then
    begin
      List[i, 0] := afav.Group;
      List[i, 1] := afav.Name;
      List[i, 2] := afav.IDStr;
      List[i, 3] := i;
    end;
    Sleep(0);
  end;
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: COM Interface delphi to AHK array troubles

02 May 2017, 13:46

At least im getting some numbers from the array using this, so i must be on the right track. Although I have no idea what im doing :oops:

msgbox 1:
Variant type: 9
Type name: IDVBViewer3
Interface ID: {CA8A3ACB-6635-4399-8967-C9BA40F719EA}
msgbox 2:
8201

{CA8A3ACB-6635-4399-8967-C9BA40F719EA}
msgbox 3:
0 .. -1
0 .. -1
0 .. -1
0 .. -1
msgbox 4: Empty

Code: Select all

iDVBViewer := ComObject("DVBViewerServer.DVBViewer")
VarType := ComObjType(iDVBViewer)          ; Always 9 for script-callable objects.
Name    := ComObjType(iDVBViewer, "Name")  ; Only valid for script-callable objects.
IID     := ComObjType(iDVBViewer, "IID")   ; As above.
MsgBox Variant type:`t%VarType%`nType name:`t%Name%`nInterface ID:`t%IID%
arr := {}
arr := ComObjArray(9,Group,Name,IDStr,i)
dd := iDVBViewer.FavoritesManager.GetFavoritesList(List)
dd  := arr 
VarType := ComObjType(dd)
Group   := ComObjType(dd, "Group")
Name    := ComObjType(dd, "Name")
IDStr   := ComObjType(dd, "IDStr")
i       := ComObjType(dd, "i")
msgbox % VarType "`n" Name "`n" IID
; Get the number of dimensions:
dim := DllCall("oleaut32\SafeArrayGetDim", "ptr", ComObjValue(dd))

; Get the bounds of each dimension:
Loop %dim%
    dims .= dd.MinIndex(A_Index) " .. " dd.MaxIndex(A_Index) "`n"
MsgBox %dims%

; Simple usage:
Loop 3 {
    x := A_Index-1
    Loop 4 {
        y := A_Index-1
        dd[x, y] := x * y
    }
}
MsgBox % dd[2, 3]
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: COM Interface delphi to AHK array troubles

03 May 2017, 15:35

zcooler wrote:This is the line im passing and there is some COM interface syntax commented in codebox. hhh := iDVBViewer.FavoritesManager.GetFavorites.Item[Index: Integer]
Hi zcooler,

Not technically what you were asking for (sorry, but I don't know anything about COM arrays), but I'm posting because I think you can still achieve what you want with this:

Code: Select all

iDVBViewer := ComObjActive("DVBViewerServer.DVBViewer")
count := iDVBViewer.FavoritesManager.GetFavorites.Count

Loop %count% {
	afav := iDVBViewer.FavoritesManager.GetFavorites.Item[A_Index - 1]
	MsgBox % afav.Nr . "`r`nGroup: " . afav.Group . "`r`nName: " . afav.Name . "`r`nChannel ID: " . afav.ChannelID
}
Of course, someone might come in with the proper way.

Good luck!
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: COM Interface delphi to AHK array troubles

03 May 2017, 16:33

Wow it works!! Man you are nifty and really smart :D Had almost given up this approach and was working with an another one.
Hmm...lets see if I can retrieve the EPGID with the same method but with other COM functions...
Due to the test limitations I suspect the "proper way" will never see daylight, but you will never know. Someone can surprise. Although the posts about ComObjArrays is very few and I think the only one showing a good (Excel) example, where a few tricks are revealed (set it up in practise), is kon.

Big thanks qwerty12, you ROCK :mrgreen:
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: COM Interface delphi to AHK array troubles

03 May 2017, 18:12

zcooler wrote:Due to the test limitations I suspect the "proper way" will never see daylight, but you will never know. Someone can surprise.
Hey zcooler,

No problem. I actually worked out how to do it using GetFavoritesList:

Code: Select all

iDVBViewer := ComObjActive("DVBViewerServer.DVBViewer")
; https://lexikos.github.io/v2/docs/commands/ComObject.htm#ByRef
VarSetCapacity(var, 24, 0)
vref := ComObject(0x400C, &var)
expected_type := 0x2000 | 0xC

if ((count := iDVBViewer.FavoritesManager.GetFavoritesList(vref)) && NumGet(var,,"UShort") & expected_type) {
	List := ComObject(expected_type, NumGet(var, 8, "Ptr"), 1)

	Loop %count% {
		Groupname := List[A_Index - 1, 0]
		Name := List[A_Index - 1, 1]
		ChannelID := List[A_Index - 1, 2]
		ID_Number := List[A_Index - 1, 3]
		MsgBox % ID_Number . "`r`nGroup: " . Groupname . "`r`nName: " . Name . "`r`nChannel ID: " . ChannelID
	}

	; to access the name of, say, the second favourite directly
	MsgBox % List[1, 1]
} else {
	DllCall("ole32\VariantClear", "Ptr", &var)
}
The allocation of the array is done by DVBViewer - I can't believe I missed that :oops:

If you don't work out how to get the EPGID, feel free to shoot me a PM :-)
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: COM Interface delphi to AHK array troubles

04 May 2017, 00:53

Far out :shock:
Impressing as hell :D That was unexpected...do you by any chance have the DVBViewer?
Many thanks, qwerty12 :wave:
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: COM Interface delphi to AHK array troubles

04 May 2017, 05:59

@qwerty12
I will take the opportunity to ask while this is fresh...this COM stuff involves IDispatch (the COM feature that lets you call supporting COM methods easily by name in AutoHotkey). Do you think there might be an easier way to get to the array instead of doing what you did with NumGet? All who knows how to and sees this post please weigh in.

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], mikeyww, pyn, teadrinker and 40 guests