Modify

Opened 3 years ago

Last modified 2 years ago

#3832 new Bug

IDispatch and the "_" character

Reported by: kAnon Owned by:
Milestone: Component: AutoIt
Version: 3.3.14.5 Severity: None
Keywords: Cc:

Description

It is not possible to call the IDispatch method of an interface if its name contains the "_" character.

#include <GUIConstantsEx.au3>
#include <WinAPIConstants.au3>
#include <FileConstants.au3>

#Region
Global Const $CLSID_FilterGraph = '{e436ebb3-524f-11ce-9f53-0020af0ba770}'
Global Const $IID_IFilterGraph2 = '{36b73882-c2c8-11cf-8b46-00805f6cef60}'
Global Const $tagIFilterGraph2 = _
        'AddFilter hresult(ptr;wstr);' & _
        'RemoveFilter hresult(ptr);' & _
        'EnumFilters hresult(ptr*);' & _
        'FindFilterByName hresult(wstr;ptr*);' & _
        'ConnectDirect hresult(ptr;ptr;struct*);' & _
        'Reconnect hresult(ptr);' & _
        'Disconnect hresult(ptr);' & _
        'SetDefaultSyncSource hresult();' & _
        'Connect hresult(ptr;ptr);' & _
        'Render hresult(ptr);' & _
        'RenderFile hresult(wstr;ptr);' & _
        'AddSourceFilter hresult(wstr;wstr;ptr*);' & _
        'SetLogFile hresult(dword_ptr);' & _
        'Abort hresult();' & _
        'ShouldOperationContinue hresult();' & _
        'AddSourceFilterForMoniker hresult(ptr;ptr;wstr;ptr*);' & _
        'ReconnectEx hresult(ptr;struct*);' & _
        'RenderEx hresult(ptr;dword;ptr);'
Global Const $IID_IMediaControl = '{56a868b1-0ad4-11ce-b03a-0020af0ba770}'
Global Const $CLSID_DSoundRender = '{79376820-07D0-11cf-A24D-0020AFD79767}'
Global Const $IID_IBaseFilter = '{56a86895-0ad4-11ce-b03a-0020af0ba770}'
Global Const $tagIBaseFilter = _
        'GetClassID hresult(clsid*);' & _
        'Stop hresult();' & _
        'Pause hresult();' & _
        'Run hresult(int64);' & _
        'GetState hresult(dword;int*);' & _
        'SetSyncSource hresult(ptr);' & _
        'GetSyncSource hresult(ptr*);' & _
        'EnumPins hresult(ptr*);' & _
        'FindPin hresult(wstr;ptr*);' & _
        'QueryFilterInfo hresult(struct*);' & _
        'JoinFilterGraph hresult(ptr;wstr);' & _
        'QueryVendorInfo hresult(wstr*);'
Global Const $IID_IEnumPins = '{56a86892-0ad4-11ce-b03a-0020af0ba770}'
Global Const $tagIEnumPins = _
        'Next hresult(ulong;ptr*;ulong*);' & _
        'Skip hresult(ulong);' & _
        'Reset hresult();' & _
        'Clone hresult(ptr*);'
Global Const $IID_IPin = '{56a86891-0ad4-11ce-b03a-0020af0ba770}'
Global Const $tagIPin = _
        'Connect hresult(ptr;struct*);' & _
        'ReceiveConnection hresult(ptr;struct*);' & _
        'Disconnect hresult();' & _
        'ConnectedTo hresult(ptr*);' & _
        'ConnectionMediaType hresult(struct*);' & _
        'QueryPinInfo hresult(struct*);' & _
        'QueryDirection hresult(int*);' & _
        'QueryId hresult(wstr*);' & _
        'QueryAccept hresult(struct*);' & _
        'EnumMediaTypes hresult(ptr*);' & _
        'QueryInternalConnections hresult(ptr*;ulong*);' & _
        'EndOfStream hresult();' & _
        'BeginFlush hresult();' & _
        'EndFlush hresult();' & _
        'NewSegment hresult(int64;int64;double);'
Global Const $AM_RENDEREX_RENDERTOEXISTINGRENDERERS = 0x1
#EndRegion

test()

Func test()
    Local $sFile = FileOpenDialog('', @ScriptDir, 'MP3 (*.mp3)', $FD_FILEMUSTEXIST)
    If @error Then Return

    GUICreate('', 400, 100)
    GUICtrlCreateLabel($sFile, 10, 10, 380, 80)
    GUISetState()

    Local $_ = ObjEvent('AutoIt.Error', onError)
    #forceref $_

    Local $oIFilterGraph2, $oIMediaControl, $ppUnk
    If Not renderFile($sFile, $oIFilterGraph2, $oIMediaControl) Then Return
    $oIMediaControl.get_FilterCollection($ppUnk) ; err.windescription:    Unknown name.
    $oIMediaControl.Run() ; work

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>test

Func renderFile($sFile, ByRef $oIFilterGraph2, ByRef $oIMediaControl)
    $oIFilterGraph2 = ObjCreateInterface($CLSID_FilterGraph, $IID_IFilterGraph2, $tagIFilterGraph2)
    If @error Then Return

    Local $iHr = $oIFilterGraph2.QueryInterface($IID_IMediaControl, $oIMediaControl)
    If hrFailed($iHr) Then Return
    $oIMediaControl = ObjCreateInterface($oIMediaControl, $IID_IMediaControl)
    If @error Then Return

    Local $oIBaseFilterAudio = ObjCreateInterface($CLSID_DSoundRender, $IID_IBaseFilter, $tagIBaseFilter)
    If @error Then Return
    $iHr = $oIFilterGraph2.AddFilter($oIBaseFilterAudio, 'Audio')
    If hrFailed($iHr) Then Return

    Local $oIBaseFilterSource
    $iHr = $oIFilterGraph2.AddSourceFilter($sFile, Null, $oIBaseFilterSource)
    If hrFailed($iHr) Then Return
    $oIBaseFilterSource = ObjCreateInterface($oIBaseFilterSource, $IID_IBaseFilter, $tagIBaseFilter)
    If @error Then Return

    Local $oIEnumPins
    $iHr = $oIBaseFilterSource.EnumPins($oIEnumPins)
    If hrFailed($iHr) Then Return
    $oIEnumPins = ObjCreateInterface($oIEnumPins, $IID_IEnumPins, $tagIEnumPins)
    If @error Then Return

    Local $oIPin, $iHrTmp
    Local $bRenderedAnyPin = False
    While $S_OK = $oIEnumPins.Next(1, $oIPin, Null)
        $iHrTmp = $oIFilterGraph2.RenderEx($oIPin, $AM_RENDEREX_RENDERTOEXISTINGRENDERERS, Null)
        $oIPin = ObjCreateInterface($oIPin, $IID_IPin, $tagIPin)
        If hrSucceeded($iHrTmp) Then $bRenderedAnyPin = True
    WEnd
    If Not $bRenderedAnyPin Then Return

    Return 1
EndFunc   ;==>renderFile

Func hrSucceeded($iHr)
    Return $iHr >= 0
EndFunc   ;==>hrSucceeded

Func hrFailed($iHr)
    Return $iHr < 0
EndFunc   ;==>hrFailed

Func onError($oError)
    ConsoleWrite(@ScriptName & ' (' & $oError.scriptline & ') : ==> COM Error intercepted !' & @CRLF & _
            @TAB & 'err.number is: ' & @TAB & @TAB & '0x' & Hex($oError.number) & @CRLF & _
            @TAB & 'err.windescription:' & @TAB & $oError.windescription & @CRLF & _
            @TAB & 'err.description is: ' & @TAB & $oError.description & @CRLF & _
            @TAB & 'err.source is: ' & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & 'err.helpfile is: ' & @TAB & $oError.helpfile & @CRLF & _
            @TAB & 'err.helpcontext is: ' & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & 'err.lastdllerror is: ' & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & 'err.scriptline is: ' & @TAB & $oError.scriptline & @CRLF & _
            @TAB & 'err.retcode is: ' & @TAB & '0x' & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>onError

Declaring this interface in <control.h>

IMediaControl : public IDispatch
{
public:
    virtual HRESULT STDMETHODCALLTYPE Run( void) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE Pause( void) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE Stop( void) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE GetState( 
        /* [in] */ LONG msTimeout,
        /* [out] */ __RPC__out OAFilterState *pfs) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE RenderFile( 
        /* [in] */ __RPC__in BSTR strFilename) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE AddSourceFilter( 
        /* [in] */ __RPC__in BSTR strFilename,
        /* [out] */ __RPC__deref_out_opt IDispatch **ppUnk) = 0;
    
    virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_FilterCollection( 
        /* [retval][out] */ __RPC__deref_out_opt IDispatch **ppUnk) = 0;
    
    virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_RegFilterCollection( 
        /* [retval][out] */ __RPC__deref_out_opt IDispatch **ppUnk) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE StopWhenReady( void) = 0;
};

Windows 10 Pro 21H1 x64
AutoIt Version: 3.3.14.5 / 3.3.15.4


IMediaControl interface (control.h)

Attachments (0)

Change History (1)

comment:1 Changed 2 years ago by Jpm

Hi,
as I understand Global Const $tagIBaseFilter
refer to run but not to get_FilterCollection
so that certainly why it is not working

BTW I a not an expert iDispath usage so I can be wrong
please confirm

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as new The ticket will remain with no owner.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.