majstang Posted April 29, 2017 Share Posted April 29, 2017 Hello, Im trying to get the Favorites array, but im failing each time. Syntax Im using looks like the below. The IFavoritesItem list can by accessed like an array with an Index from 0 to count-1. How would the code look like to get the array and enumerate it? Set iDVBViewer = GetObject(, "DVBViewerServer.DVBViewer") 'MyVolume = iDVBViewer.Datamanager.Value("#Volume") 'MsgBox(Count) 'iDVBViewer.Volume = 0.25 'Count = iDVBViewer.FavoritesManager.GetFavorites.Count 'MsgBox(Count) Arr = iDVBViewer.FavoritesManager.GetFavorites.Item[Index: Integer] 'For Each element In Arr Quote Link to comment
nuts Posted April 29, 2017 Share Posted April 29, 2017 Are you sure your Script Language Support Arrays via COM? AFAIK autoit doesnt support it, not sure about autohotkey. Quote Link to comment
majstang Posted April 30, 2017 Author Share Posted April 30, 2017 Hello nuts, The scripting language in the codebox is VBScript, but it is correct AutoHotkey is the preferred scripting language of mine and this fails with that too. Regarding AutoHotkey, which is the scripting language Im using to do some favourites channel switching features for a DVBViewer thumbnailed app, does actually support COM objects arrays https://autohotkey.com/docs/commands/ComObjArray.htm Quote Link to comment
Marc32 Posted April 30, 2017 Share Posted April 30, 2017 (edited) hallo, ich bekomme auch kein array, nur counts. wahrscheinlich mache ich irgendeinen syntax fehler. Arr = DVBViewer.FavoritesManager.GetFavoritesList (x1)MsgBox arr arr(0) erzeugt einen error, ist ja auch kein array. erzeugt bei mir wie gesagt nur einen count der favoriten. was müsste denn zwischen den () stehen, falls ich da einen fehler mache? grüße, marc Edited April 30, 2017 by Marc32 Quote Link to comment
Griga Posted April 30, 2017 Share Posted April 30, 2017 (edited) As already mentioned, I didn't make the COM interface, I never used it, so I have no idea how it works in practice. But from looking at the interface declaration function GetFavoritesList(out List: OleVariant): Integer; safecall; I guess it returns the list count as function result and a pointer to a variant as out parameter containing the list. (corrected - see below) No idea if and how this can be handled in VBScript. The following function GetFavorites: IFavoritesCollection; safecall; looks more promising to me, because it simply returns an IFavoriteCollection interface. I guess (again) that it also allows to access the whole favourites list by index (via IFavoritesCollection.Get_Count and IFavoritesCollection.Get_Item). Edited April 30, 2017 by Griga Quote Link to comment
Griga Posted April 30, 2017 Share Posted April 30, 2017 13 minutes ago, Griga said: I guess it returns the list count as function result and a pointer to a variant as out parameter containing the list. Wrong. Should be "It returns the list count as function result and receives a pointer to a variant variable to which the list is written." Quote Link to comment
Delphi Posted May 1, 2017 Share Posted May 1, 2017 var N: integer; List: OleVariant; s: string; FavoritesManager: IFavoritesManager; begin FavoritesManager := FDVBViewer.FavoritesManager; N := pFavoritesManager.GetFavoritesList(List); for i := 0 to N - 1 do s := List[i]; end; If I do this I get an "index out of bounds" error for i=0; I don't use that in Xepg and I don't know whether it's supposed to be a one dimensional array. Quote Link to comment
Griga Posted May 2, 2017 Share Posted May 2, 2017 In DVBViewer it's 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; That's all I can say about it. Quote Link to comment
majstang Posted May 2, 2017 Author Share Posted May 2, 2017 Cool, with this info it might be time to take an another crack at this. Havent seen it as priority since Im fetching the Favourites List from the DMS API instead. It would be a shame to take the easy road and leave things unsolved Quote Link to comment
majstang Posted May 2, 2017 Author Share Posted May 2, 2017 16 hours ago, Delphi said: If I do this I get an "index out of bounds" error for i=0; I don't use that in Xepg and I don't know whether it's supposed to be a one dimensional array. According to COM documentations it should Return a list of all favorites as a two-dimensional variant safearray. At least the GetFavoritesList does. Hmm..copy and paste into this textbox screws up the format... Quote Link to comment
erwin Posted May 4, 2017 Share Posted May 4, 2017 (edited) Am 30.04.2017 um 18:50 schrieb Griga: As already mentioned, I didn't make the COM interface, I never used it, so I have no idea how it works in practice. But from looking at the interface declaration function GetFavoritesList(out List: OleVariant): Integer; safecall; The lasting issue with safecall i guess. See this old discussion for explanation. http://www.DVBViewer.tv/forum/topic/40060-c-sample-plugin/?page=3#comment-329927 @ majstang: This is für C/C++ as Interface language. VBScript is not in my experience, but i think it's the same issue.. If VBScript isn't safecall -aware try this: Call GetFavoritesList like this: HRESULT GetFavoritesList( int * count, list ). function GetFavoritesList(out Count:Integer, out List: OleVariant): Integer; stdcall; As you can see the return (the Count) from Griga's declaration ist the first Parameter as an reference, the list is the second parameter. And the return of this function is not the Count, but a HRESULT. The crux is that the SDK - Interface-description is only for Delphi like languages correct. Edited May 4, 2017 by erwin Quote Link to comment
majstang Posted May 4, 2017 Author Share Posted May 4, 2017 (edited) On 2017-05-04 at 6:39 AM, erwin said: @ majstang: This is für C/C++ as Interface language. VBScript is not in my experience, but i think it's the same issue.. If VBScript isn't safecall -aware try this: Call GetFavoritesList like this: HRESULT GetFavoritesList( int * count, list ). function GetFavoritesList(out Count:Integer, out List: OleVariant): Integer; stdcall; As you can see the return (the Count) from Griga's declaration ist the first Parameter as an reference, the list is the second parameter. And the return of this function is not the Count, but a HRESULT. The crux is that the SDK - Interface-description is only for Delphi like languages correct. Hello Erwin, A really smart dude (qwerty12) at the AHK forum figured out how to do it with AHK at least. Whether its possible to retrieve the safearray with VBScript I will leave be. True VBScripters might find it fun to try to work it out . GetFavoritesList safearray with AHK: #NoEnv 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, 2] } else { DllCall("ole32\VariantClear", "Ptr", &var) } Edited May 5, 2017 by majstang Quote Link to comment
erwin Posted May 4, 2017 Share Posted May 4, 2017 Hi majstang! This really works? Surprisingly good result! Quote Link to comment
Delphi Posted May 16, 2017 Share Posted May 16, 2017 Seems that you have figured things out. Just for the sake of completeness, the following works in Delphi: N := FDVBViewer.FavoritesManager.GetFavoritesList(List); for i := 0 to N - 1 do begin s := List[i,0]; //'DK' : category s := List[i,1]; //'TV 2 News' : channel name s := List[i,2]; //'3431748929602525161|TV 2 News' :the correct 64 bit channel ID|channel name s := List[i,3]; // '0': favorite number, same as i, can be read as an integer type end; List is of type OleVariant. Quote Link to comment
majstang Posted May 16, 2017 Author Share Posted May 16, 2017 (edited) @Delphi, thanks for that Yeah, im on top retrieving all the safearrays. Surprisingly it was, what I supposed being the easy stuff, that in reality proved to be the completely unsolvable nut to crack, at least with AutoHotkey. I could not figure out how to get to the raw Time VARIANT data type of the EPGItem. http://www.DVBViewer.tv/forum/topic/59840-com-epgitem-variant-type/ Perhaps, if you are up to it, you might wanna have a go at it with Delphi to see if you get the same result as I get with both AHK and VBScript? FYI in that thread I was mistakenly under the assumption AHK did some faulty conversion, but I later discovered AutoHotkey doesn't understand or interpret date-time values. For any types it doesn't understand, it just requests a standard COM conversion to string. The COM IDispatch interface has several helper functions doing conversions and upon conversion request from client (AHK) IDispatch probably calls one of those and I get back a crappy converted string for all shows starting at midnight (00:00:00). So I suspect you get the same result if trying with Delphi. The problem is how to call the VariantTimeToSystemTime function (which provenly returns better result) correctly when there is no way to get the variant data type for the EPGItem. Edited May 16, 2017 by majstang Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.