Jump to content
majstang

COM GetFavorites items array?

Recommended Posts

majstang

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

 

Share this post


Link to post
nuts

Are you sure your Script Language Support Arrays via COM? 

AFAIK autoit doesnt support it, not sure about autohotkey. 

Share this post


Link to post
majstang

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

 

 

 

 

Share this post


Link to post
Griga

@majstang: PM

Share this post


Link to post
Marc32

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 by Marc32

Share this post


Link to post
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;

 

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 by Griga

Share this post


Link to post
Griga
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."

Share this post


Link to post
Delphi
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.

Share this post


Link to post
Griga

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.

Share this post


Link to post
majstang

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;)

 

Share this post


Link to post
majstang
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...

 

Share this post


Link to post
erwin
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 by erwin

Share this post


Link to post
majstang
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 by majstang

Share this post


Link to post
erwin

Hi  majstang!

 

 

This really works? Surprisingly good result!

 

 

Share this post


Link to post
Delphi

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.

Share this post


Link to post
majstang

@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 by majstang

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...