Jump to content
majstang

COM EPGItem VARIANT type?

Recommended Posts

majstang

Hello, 

What is the VARIANT Type for the EPGItem? .item()

Edited by majstang

Share this post


Link to post
nuts

Not sure I understand your question, but DVBViewer COM-Server wants the data type "Integer" for IEPGCollection.Item().

Share this post


Link to post
majstang

Ah, I was looking in the wrong place (COM doku), thanks nuts:) Just doing some experimenting, will probably not pan out as intended.

Share this post


Link to post
majstang

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

Share this post


Link to post
nuts

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.

Share this post


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

Share this post


Link to post
nuts

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

Share this post


Link to post
majstang

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

Share this post


Link to post
Delphi

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;


 

Share this post


Link to post
majstang

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 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...