Trying to workaround it (the hard way) seems impossible. Have been playing around with intercepting the binary respresentation of the starttime floating point value, before AHK does its "no good" conversion, and trying to convert the variant time back to system time using lexikos SystemTime class and VariantTimeToSystemTime dll calls. But utilizing it on these kind of COM IDispatch calls seems merely impossible. The variant data types cannot be determined...and the dll call does consequently not work.
Doing it when using COM safearrays proved to be possible for some reason. See sample below the one below....
Code: Select all
#NoEnv
;DllCall("oleaut32\SystemTimeToVariantTime", "Ptr", (_ := SystemTime.Now()).p, "Double*", oleSt)
DllCall("oleaut32\SystemTimeToVariantTime", "Ptr", (_ := SystemTime.FromString(20170512000000)).p, "Double*", oleSt)
;SystemTime to convert = 20170512000000
;Results in floating point (double) OleSt = 42867.000000
iDVBViewer := ComObjActive("DVBViewerServer.DVBViewer")
channelnumber := 2 ; number of your wanted channel
epgcid := iDVBViewer.channelmanager(channelnumber).EPGChannelID
SuD := iDVBViewer.channelmanager.GetByEPGChannelID(epgcid).tuner.SID
TuD := iDVBViewer.channelmanager.GetByEPGChannelID(epgcid).tuner.TransportStreamID
o_epgGet := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,0)
epgnow := o_epgGet.item(0).Title
epgnext := o_epgGet.item(1).Title
starttime := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,oleSt).item(0).Time ; AHK converts oleSt floating point value to systemtime and fails to bring back the HH:mm:ss part.
endtime := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,0).item(0).Endtime
msgbox % starttime . " " . epgnow . "`n" . endtime " " epgnext " "
; 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
}
Code: Select all
#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
}
}