majstang Posted May 9, 2017 Share Posted May 9, 2017 (edited) Hello, What is the VARIANT Type for the EPGItem? .item() Edited May 9, 2017 by majstang Quote Link to comment
nuts Posted May 9, 2017 Share Posted May 9, 2017 Not sure I understand your question, but DVBViewer COM-Server wants the data type "Integer" for IEPGCollection.Item(). Quote Link to comment
majstang Posted May 9, 2017 Author Share Posted May 9, 2017 Ah, I was looking in the wrong place (COM doku), thanks nuts Just doing some experimenting, will probably not pan out as intended. Quote Link to comment
majstang Posted May 10, 2017 Author Share Posted May 10, 2017 (edited) As it seems Im having big difficulties to catch the rawTime value (floating point (double) value) before AHK does its implicite conversion to it, when the COM call is mixing Integers with floating point values. starttime := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,oleSt).item(0).Time Edited May 10, 2017 by majstang Quote Link to comment
nuts Posted May 10, 2017 Share Posted May 10, 2017 Don't think the COM Call is mixing integers with floating point values. Everything in AHK is stored as variant (?). => iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,oleSt).item(0).Time returns a floating point (double) value => AHK "translate" this for you to variant data type (starttime) When you are working with this variant data type variables you need to be very careful. i.e. you have to convert them again for the next COM call. Quote Link to comment
majstang Posted May 10, 2017 Author Share Posted May 10, 2017 (edited) 3 hours ago, nuts said: Don't think the COM Call is mixing integers with floating point values. Hi nuts! Im trying to use the same method as the GetAsArray sample to catch the floating point value (TDateTime) or actually a Half-Ptr , before AHK does its conversion which works nicely there. http://www.DVBViewer.tv/forum/topic/59821-get-com-arrays/?do=findComment&comment=462500 . Im trying to fix the failed AHK TTime midnight conversion (missing 00:00:00) for EPGManager.Get as well, but its like banging the head against a door...you only get a headache For some reason NumGet does not return the pointer to the variant data type for starttime which in the GetAsArray example (for Time var) is the varType VT_UI4 which, apparently, is how a double referring to the date and time is stored as. Without this info I cant convert the TDateTime back into a SYSTEMTIME using the SystemTime class and VariantTimeToSystemTime dll call, which does a much better job than AHK itself. So my problem is I can't work out how to get to the raw Time variant as long as the EPGItem is in the picture. Cannot interpret the non-result it in any other way. This is really advanced stuff and Im hardly understanding it all. 3 hours ago, nuts said: When you are working with this variant data type variables you need to be very careful. i.e. you have to convert them again for the next COM call. No, that Im very aware of, no AHK (badly) converted TDateTime floating pointers can be used in next coming COM calls. But if converted by SystemTime class and VariantTimeToSystemTime they should be accepted, but I havent tried that (yet) 3 hours ago, nuts said: Everything in AHK is stored as variant (?). Dont know, but it is important getting those right when doing VariantTimeToSystemTime dll call, in order to accurately convert back the floating point to systemtime. Perhaps you wanna have a go at it yourself? Im working with this code: #NoEnv iDVBViewer := ComObjActive("DVBViewerServer.DVBViewer") DllCall("oleaut32\SystemTimeToVariantTime", "Ptr", (_ := SystemTime.Now()).p, "Double*", oleSt) ;DllCall("oleaut32\SystemTimeToVariantTime", "Ptr", (_ := SystemTime.FromString(20170511000000)).p, "Double*", oleSt) channelnumber := 3 ; 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 endtime := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,0).item(0).Endtime duration := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,oleSt).item(0).Duration showinfo := iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,oleSt).item(0).Description msgbox % starttime . " " . epgnow . "`n" . endtime " " epgnext " " if (starttime) { ; check if getting the target field succeeded normally if (NumGet(starttime+0,, "UShort") & 19) ; should get back a pointer to a variant - for GetAsArray its the varType VT_UI4 which, apparently, is how a double referring to the date and time is stored as if (DllCall("oleaut32\VariantTimeToSystemTime", "Double", NumGet(starttime+0, 8, "Double"), "Ptr", st.p)) ; if so, convert the TDateTime back into a SYSTEMTIME FormatTime, rawStartTime, % st.ToString(), yyyy-MM-dd HH:mm:ss } msgbox % rawStartTime . " " . 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 } Edited May 10, 2017 by majstang Quote Link to comment
nuts Posted May 10, 2017 Share Posted May 10, 2017 Mhm I don't really understand the problem. You want to translate TDateTime by: iDVBViewer.epgmanager.Get(SuD,TuD,oleSt,oleSt).item(0).Time to "system time" (variant/string YYYY/MM/DD HH:MM:SS)? Quote Link to comment
majstang Posted May 10, 2017 Author Share Posted May 10, 2017 (edited) Yep, cuz when AHK translates/converts it the 00:00:00 (TTime part of TDateTime vanishes when converted to systemtime HH:mm:ss) is missing for all shows starting at midnight. Im trying to convert the TDateTime to systemtime yyyy-MM-dd HH:mm:ss using the SystemTime class and the "VariantTimeToSystemTime", the opposite to the "SystemTimeToVariantTime" Maybe you know an easier method? Edited May 10, 2017 by majstang Quote Link to comment
Delphi Posted May 17, 2017 Share Posted May 17, 2017 From the DVBViewerServer_TLB.pas unit (created by the Delphi XE2 IDE): Spoiler // *********************************************************************// // Interface: IEPGItem // Flags: (4416) Dual OleAutomation Dispatchable // GUID: {340BE5BA-0B5B-490A-B0C3-FB30B88FCEF5} // *********************************************************************// IEPGItem = interface(IDispatch) ['{340BE5BA-0B5B-490A-B0C3-FB30B88FCEF5}'] function Get_ServiceID: Integer; safecall; function Get_TransportID: Integer; safecall; function Get_Charset: Integer; safecall; procedure Set_Charset(Value: Integer); safecall; function Get_Content: Integer; safecall; procedure Set_Content(Value: Integer); safecall; function Get_Description: WideString; safecall; procedure Set_Description(const Value: WideString); safecall; function Get_Duration: TDateTime; safecall; procedure Set_Duration(Value: TDateTime); safecall; function Get_Event: WideString; safecall; procedure Set_Event(const Value: WideString); safecall; function Get_EventID: Integer; safecall; procedure Set_EventID(Value: Integer); safecall; function Get_Time: TDateTime; safecall; procedure Set_Time(Value: TDateTime); safecall; function Get_Title: WideString; safecall; procedure Set_Title(const Value: WideString); safecall; procedure SetEPGEventID(ServiceID: Integer; TransportID: Integer); safecall; function Get_EndTime: TDateTime; safecall; function Get_EPGEventID: Integer; safecall; procedure Set_EPGEventID(Value: Integer); safecall; property ServiceID: Integer read Get_ServiceID; property TransportID: Integer read Get_TransportID; property Charset: Integer read Get_Charset write Set_Charset; property Content: Integer read Get_Content write Set_Content; property Description: WideString read Get_Description write Set_Description; property Duration: TDateTime read Get_Duration write Set_Duration; property Event: WideString read Get_Event write Set_Event; property EventID: Integer read Get_EventID write Set_EventID; property Time: TDateTime read Get_Time write Set_Time; property Title: WideString read Get_Title write Set_Title; property EndTime: TDateTime read Get_EndTime; property EPGEventID: Integer read Get_EPGEventID write Set_EPGEventID; end; To conclude: The IEPGItem.Time and IEPGItem.EndTime are of type TDateTime = Doubble = 8 byte floating point number. In Delphi there is a unit (Library) which handles all types of conversions for TDateTime. Maybe you can find a library for AHK for that. A few examples from DateUtils.pas: function YearOf(const AValue: TDateTime): Word; function MonthOf(const AValue: TDateTime): Word; function WeekOf(const AValue: TDateTime): Word; {ISO 8601} function DayOf(const AValue: TDateTime): Word; function HourOf(const AValue: TDateTime): Word; function MinuteOf(const AValue: TDateTime): Word; function SecondOf(const AValue: TDateTime): Word; function MilliSecondOf(const AValue: TDateTime): Word; Quote Link to comment
majstang Posted May 17, 2017 Author Share Posted May 17, 2017 (edited) Thanks Delphi 5 hours ago, Delphi said: To conclude: The IEPGItem.Time and IEPGItem.EndTime are of type TDateTime = Doubble = 8 byte floating point number. Yes, I know this, but AHK doesnt. NumGet() cant return the binary number stored at the specified address+offset for EPGItems, due to reasons unknown to me (as if the variant type has changed). That was possible in the GetAsArray sample (which creates total confusion for me), although those were no EPGItems. 5 hours ago, Delphi said: In Delphi there is a unit (Library) which handles all types of conversions for TDateTime. Maybe you can find a library for AHK for that. There are none for AHK, but with increasing COM usage it might be needed. But not likely, cuz "VariantTimeToSystemTime" function is probably the best there is handling TDateTime to system time conversions. Edited May 17, 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.