majstang Posted May 5, 2017 Share Posted May 5, 2017 Hello! Here is a few samples of getting DVBViewer COM safearrays with AutoHotkey: - ChannelCollection.GetChannelList(List) - FavoritesManager.GetFavoritesList(List) - EPGManager.GetAsArray(0,0,0,List) /* ;---------------------------------------------------------------------------- ;---ChannelCollection.GetChannelList(vref)----------------------------------- ;---------------------------------------------------------------------------- #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.ChannelCollection.GetChannelList(vref)) && NumGet(var,,"UShort") & expected_type) { List := ComObject(expected_type, NumGet(var, 8, "Ptr"), 1) Loop %count% { Root := List[A_Index - 1, 0] Name := List[A_Index - 1, 1] Category := List[A_Index - 1, 2] Encrypted := List[A_Index - 1, 3] TunerType := List[A_Index - 1, 4] Frequency := List[A_Index - 1, 5] SymbolRate := List[A_Index - 1, 6] LNB := List[A_Index - 1, 7] PMT := List[A_Index - 1, 8] ECM_0 := List[A_Index - 1, 9] SatModulation := List[A_Index - 1, 10] AVFormat := List[A_Index - 1, 11] FEC := List[A_Index - 1, 12] CAID_0 := List[A_Index - 1, 13] Polarity := List[A_Index - 1, 14] ECM_1 := List[A_Index - 1, 15] LNBSelection := List[A_Index - 1, 16] CAID_1 := List[A_Index - 1, 17] Diseqc := List[A_Index - 1, 18] ECM_2 := List[A_Index - 1, 19] AudioPID := List[A_Index - 1, 20] CAID_2 := List[A_Index - 1, 21] VideoPID := List[A_Index - 1, 22] TransportStreamID := List[A_Index - 1, 23] telePID := List[A_Index - 1, 24] NetworkID := List[A_Index - 1, 25] SID := List[A_Index - 1, 26] PCRPID := List[A_Index - 1, 27] ChannelGroup := List[A_Index - 1, 28] MsgBox % Root . "`r`nName: " . Name . "`r`nCategory: " . Category . "`r`nEncrypted: " . Encrypted . "`r`nTunerType: " . TunerType . "`r`nFrequency: " . Frequency . "`r`nSymbolRate: " . SymbolRate . "`r`nLNB: " . LNB . "`r`nPMT: " . PMT . "`r`nECM_0: " . ECM_0 . "`r`nSatModulation: " . SatModulation . "`r`nAVFormat: " . AVFormat . "`r`nFEC: " . FEC . "`r`nCAID_0: " . CAID_0 . "`r`nPolarity: " . Polarity . "`r`nECM_1: " . ECM_1 . "`r`nLNBSelection: " . LNBSelection . "`r`nCAID_1: " . CAID_1 . "`r`nDiseqc: " . Diseqc . "`r`nECM_2: " . ECM_2 . "`r`nAudioPID: " . AudioPID . "`r`nCAID_2: " . CAID_2 . "`r`nVideoPID: " . VideoPID . "`r`nTransportStreamID: " . TransportStreamID . "`r`ntelePID: " . telePID . "`r`nNetworkID: " . NetworkID . "`r`nSID: " . SID . "`r`nPCRPID: " . PCRPID . "`r`nChannelGroup: " . ChannelGroup } ; to access the name of, say, the second channel directly MsgBox % List[1, 1] } else { DllCall("ole32\VariantClear", "Ptr", &var) } */ ;---------------------------------------------------------------------------- /* ;---------------------------------------------------------------------------- ;---FavoritesManager.GetFavoritesList(vref)---------------------------------- ;---------------------------------------------------------------------------- #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, 1] } else { DllCall("ole32\VariantClear", "Ptr", &var) } ;---------------------------------------------------------------------------- */ /* ;---------------------------------------------------------------------------- ;---EPGManager.GetAsArray(0,0,0,vref)---------------------------------------- ;---------------------------------------------------------------------------- #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.EPGManager.GetAsArray(0,0,0,vref)) && NumGet(var,,"UShort") & expected_type) { List := ComObject(expected_type, NumGet(var, 8, "Ptr"), 1) Loop %count% { EPGChannelID := List[A_Index - 1, 0] ; // Longword (unsigned int) EventID := List[A_Index - 1, 1] ; // Longword (unsigned int) Time := List[A_Index - 1, 2] ; // Datetime (Double) Duration := List[A_Index - 1, 3] ; // Datetime (Double) Event := List[A_Index - 1, 4] ; // String Title := List[A_Index - 1, 5] ; // String Description := List[A_Index - 1, 6] ; // String CharSet := List[A_Index - 1, 7] ; // Byte Content := List[A_Index - 1, 8] ; // Byte MsgBox % EPGChannelID . "`r`nEventID: " . EventID . "`r`nTime: " . Time . "`r`nDuration: " . Duration . "`r`nEvent: " . Event . "`r`nTitle: " . Title . "`r`nDescription: " . Description . "`r`nCharSetList: " . CharSetList . "`r`nContent: " . Content } ; to access the EventID of, say, the second EPG_entry directly MsgBox % List[1, 1] } else { DllCall("ole32\VariantClear", "Ptr", &var) } ;---------------------------------------------------------------------------- */ Quote Link to comment
majstang Posted May 9, 2017 Author Share Posted May 9, 2017 (edited) A more specific Autohotkey sample of utilizing the COM EPGManager.GetAsArray(List) to get all EPG info for shows that are currently aired on your channels. The DMS webinterface uses something similar yellow marking all NOW shows. DVBViewer uses a red vertical line in its EPG marking the now shows instead. This code also fixes the issue with missing time when show starts at midnight (00:00:00) (AHK and VBScript issues). More about that problem here: http://www.DVBViewer.tv/forum/topic/59829-com-epgmanagerget-ttime-000000-missing/?do=findComment&comment=462393 Thanks Griga for explaining it so well. The fix is applied for Time (TDateTime) only although duration is also returned as a floating point (double) (the problem cannot be spotted for duration). #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 DllCall("oleaut32\SystemTimeToVariantTime", "Ptr", (_ := SystemTime.Now()).p, "Double*", oleSt) if ((count := iDVBViewer.EPGManager.GetAsArray(0, oleSt, oleSt, vref)) && NumGet(ComObjValue(vref),, "UShort") & expected_type) { VarSetCapacity(rgIndices, 4*2), st := IsObject(_) ? _ : new SystemTime ; allocate space to store array indices for SafeArrayPtrOfIndex and reuse SystemTime class object if it exists List := ComObject(expected_type, NumGet(ComObjValue(vref), 8, "Ptr"), 1) Loop %count% { EPGChannelID := List[A_Index - 1, 0] ; // Longword (unsigned int) EventID := List[A_Index - 1, 1] ; // Longword (unsigned int) Time := List[A_Index - 1, 2] ; // Datetime (Double) Duration := List[A_Index - 1, 3] ; // Datetime (Double) Event := List[A_Index - 1, 4] ; // String Title := List[A_Index - 1, 5] ; // String Description := List[A_Index - 1, 6] ; // String CharSet := List[A_Index - 1, 7] ; // Byte Content := List[A_Index - 1, 8] ; // Byte if (Time) { NumPut(2, NumPut(A_Index - 1, rgIndices, "Int"), "Int") if (DllCall("oleaut32\SafeArrayPtrOfIndex", "Ptr", ComObjValue(List), "Ptr", &rgIndices, "Ptr*", varTime) == 0 && varTime) if (NumGet(varTime+0,, "UShort") & 19) if (DllCall("oleaut32\VariantTimeToSystemTime", "Double", NumGet(varTime+0, 8, "Double"), "Ptr", st.p)) FormatTime, rawTime, % st.ToString(), yyyy-MM-dd HH:mm:ss } MsgBox % "EPGChannelID= " EPGChannelID . "`r`nEventID: " . EventID . "`r`nTime: " . (rawTime ? rawTime : "") . "`r`nDuration: " . Duration . "`r`nEvent: " . Event . "`r`nTitle: " . Title . "`r`nDescription: " . Description . "`r`nCharSetList: " . CharSetList . "`r`nContent: " . Content rawTime := "" ; clear the rawTime variable so that the next call doesn't get the old date if conversion fails } } else { DllCall("ole32\VariantClear", "Ptr", &var) } ; Written by Lexikos for EnableUIAccess /* SystemTime - Wrapper for Win32 SYSTEMTIME Structure http://msdn.microsoft.com/en-us/library/ms724950 Usage Examples: ; Create structure from string. st := SystemTime.FromString(A_Now) ; Shortcut: st := SystemTime.Now() ; Update values. st.FromString(A_Now) ; Retrieve components. year := st.Year month := st.Month weekday := st.DayOfWeek day := st.Day hour := st.Hour minute := st.Minute second := st.Second ms := st.Milliseconds ; Set or perform math on component. st.Year += 10 ; Create structure to receive output from DllCall. st := new SystemTime DllCall("GetSystemTime", "ptr", st.p) MsgBox % st.ToString() ; Fill external structure. st := SystemTime.FromPointer(externalPointer) st.FromString(A_Now) ; Convert external structure to string. MsgBox % SystemTime.ToString(externalPointer) */ class SystemTime { FromString(str) { if this.p st := this else st := new this if !(p := st.p) return 0 FormatTime wday, %str%, WDay wday -= 1 FormatTime str, %str%, yyyy M '%wday%' d H m s '0' Loop Parse, str, %A_Space% NumPut(A_LoopField, p+(A_Index-1)*2, "ushort") return st } FromPointer(pointer) { return { p: pointer, base: this } ; Does not call __New. } ToString(st = 0) { if !(p := (st ? (IsObject(st) ? st.p : st) : this.p)) return "" VarSetCapacity(s, 28), s := SubStr("000" NumGet(p+0, "ushort"), -3) Loop 6 if A_Index != 2 s .= SubStr("0" NumGet(p+A_Index*2, "ushort"), -1) return s } Now() { return this.FromString(A_Now) } __New() { if !(this.SetCapacity("struct", 16)) || !(this.p := this.GetAddress("struct")) return 0 NumPut(0, NumPut(0, this.p, "int64"), "int64") } __GetSet(name, value="") { static fields := {Year:0, Month:2, DayOfWeek:4, Day:6, Hour:8 , Minute:10, Second:12, Milliseconds:14} if fields.HasKey(name) return value="" ? NumGet( this.p + fields[name], "ushort") : NumPut(value, this.p + fields[name], "ushort") } static __Get := SystemTime.__GetSet static __Set := SystemTime.__GetSet } Edited May 9, 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.