Modify

Opened 5 years ago

Last modified 4 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 by J-Paul Mesnage, 4 years ago

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

Modify Ticket

Action
as new The ticket will remain with no owner.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.