⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctlutil.cpp

📁 basic class basic classbasic class
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                           DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
        IID_IBasicAudio,
        rgszNames,
        cNames,
        lcid,
        rgdispid);
}


STDMETHODIMP
CBasicAudio::Invoke(
                    DISPID dispidMember,
                    REFIID riid,
                    LCID lcid,
                    WORD wFlags,
                    DISPPARAMS * pdispparams,
                    VARIANT * pvarResult,
                    EXCEPINFO * pexcepinfo,
                    UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
        return DISP_E_UNKNOWNINTERFACE;
    }
    
    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);
    
    if (FAILED(hr)) {
        return hr;
    }
    
    hr = pti->Invoke(
        (IBasicAudio *)this,
        dispidMember,
        wFlags,
        pdispparams,
        pvarResult,
        pexcepinfo,
        puArgErr);
    
    pti->Release();
    return hr;
}


// --- IVideoWindow implementation ----------

CBaseVideoWindow::CBaseVideoWindow(const TCHAR * pName,LPUNKNOWN punk) :
CUnknown(pName, punk)
{
}


// overriden to publicise our interfaces

STDMETHODIMP
CBaseVideoWindow::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IVideoWindow) {
        return GetInterface( (IVideoWindow *) this, ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


STDMETHODIMP
CBaseVideoWindow::GetTypeInfoCount(UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


STDMETHODIMP
CBaseVideoWindow::GetTypeInfo(
                              UINT itinfo,
                              LCID lcid,
                              ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
        IID_IVideoWindow,
        itinfo,
        lcid,
        pptinfo);
}


STDMETHODIMP
CBaseVideoWindow::GetIDsOfNames(
                                REFIID riid,
                                OLECHAR  ** rgszNames,
                                UINT cNames,
                                LCID lcid,
                                DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
        IID_IVideoWindow,
        rgszNames,
        cNames,
        lcid,
        rgdispid);
}


STDMETHODIMP
CBaseVideoWindow::Invoke(
                         DISPID dispidMember,
                         REFIID riid,
                         LCID lcid,
                         WORD wFlags,
                         DISPPARAMS * pdispparams,
                         VARIANT * pvarResult,
                         EXCEPINFO * pexcepinfo,
                         UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
        return DISP_E_UNKNOWNINTERFACE;
    }
    
    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);
    
    if (FAILED(hr)) {
        return hr;
    }
    
    hr = pti->Invoke(
        (IVideoWindow *)this,
        dispidMember,
        wFlags,
        pdispparams,
        pvarResult,
        pexcepinfo,
        puArgErr);
    
    pti->Release();
    return hr;
}


// --- IBasicVideo implementation ----------


CBaseBasicVideo::CBaseBasicVideo(const TCHAR * pName,LPUNKNOWN punk) :
CUnknown(pName, punk)
{
}


// overriden to publicise our interfaces

STDMETHODIMP
CBaseBasicVideo::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IBasicVideo || riid == IID_IBasicVideo2) {
        return GetInterface( static_cast<IBasicVideo2 *>(this), ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}

STDMETHODIMP
CBaseBasicVideo::GetTypeInfoCount(UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


STDMETHODIMP
CBaseBasicVideo::GetTypeInfo(
                             UINT itinfo,
                             LCID lcid,
                             ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
        IID_IBasicVideo,
        itinfo,
        lcid,
        pptinfo);
}


STDMETHODIMP
CBaseBasicVideo::GetIDsOfNames(
                               REFIID riid,
                               OLECHAR  ** rgszNames,
                               UINT cNames,
                               LCID lcid,
                               DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
        IID_IBasicVideo,
        rgszNames,
        cNames,
        lcid,
        rgdispid);
}


STDMETHODIMP
CBaseBasicVideo::Invoke(
                        DISPID dispidMember,
                        REFIID riid,
                        LCID lcid,
                        WORD wFlags,
                        DISPPARAMS * pdispparams,
                        VARIANT * pvarResult,
                        EXCEPINFO * pexcepinfo,
                        UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
        return DISP_E_UNKNOWNINTERFACE;
    }
    
    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);
    
    if (FAILED(hr)) {
        return hr;
    }
    
    hr = pti->Invoke(
        (IBasicVideo *)this,
        dispidMember,
        wFlags,
        pdispparams,
        pvarResult,
        pexcepinfo,
        puArgErr);
    
    pti->Release();
    return hr;
}


// --- Implementation of Deferred Commands ----------


CDispParams::CDispParams(UINT nArgs, VARIANT* pArgs)
{
    cNamedArgs = 0;
    rgdispidNamedArgs = NULL;
    cArgs = nArgs;
    
    if (cArgs) {
        rgvarg = new VARIANT[cArgs];
        
        for (UINT i = 0; i < cArgs; i++) {
            
            VARIANT * pDest = &rgvarg[i];
            VARIANT * pSrc = &pArgs[i];
            
            pDest->vt = pSrc->vt;
            switch(pDest->vt) {
                
            case VT_I4:
                pDest->lVal = pSrc->lVal;
                break;
                
            case VT_UI1:
                pDest->bVal = pSrc->bVal;
                break;
                
            case VT_I2:
                pDest->iVal = pSrc->iVal;
                break;
                
            case VT_R4:
                pDest->fltVal = pSrc->fltVal;
                break;
                
            case VT_R8:
                pDest->dblVal = pSrc->dblVal;
                break;
                
            case VT_BOOL:
                pDest->boolVal = pSrc->boolVal;
                break;
                
            case VT_ERROR:
                pDest->scode = pSrc->scode;
                break;
                
            case VT_CY:
                pDest->cyVal = pSrc->cyVal;
                break;
                
            case VT_DATE:
                pDest->date = pSrc->date;
                break;
                
            case VT_BSTR:
                if (pSrc->bstrVal == NULL) {
                    pDest->bstrVal = NULL;
                } else {
                    
                    // a BSTR is a WORD followed by a UNICODE string.
                    // the pointer points just after the WORD
                    
                    WORD len = * (WORD*) (pSrc->bstrVal - (sizeof(WORD) / sizeof(OLECHAR)));
                    OLECHAR* pch = new OLECHAR[len + (sizeof(WORD)/sizeof(OLECHAR))];
                    WORD *pui = (WORD*)pch;
                    *pui = len;
                    pDest->bstrVal = pch + (sizeof(WORD)/sizeof(OLECHAR));
                    CopyMemory(pDest->bstrVal, pSrc->bstrVal, len*sizeof(OLECHAR));
                }
                pDest->bstrVal = pSrc->bstrVal;
                break;
                
            case VT_UNKNOWN:
                pDest->punkVal = pSrc->punkVal;
                pDest->punkVal->AddRef();
                break;
                
            case VT_DISPATCH:
                pDest->pdispVal = pSrc->pdispVal;
                pDest->pdispVal->AddRef();
                break;
                
            default:
                // a type we haven't got round to adding yet!
                ASSERT(0);
                break;
            }
        }
        
    } else {
        rgvarg = NULL;
    }
    
}


CDispParams::~CDispParams()
{
    for (UINT i = 0; i < cArgs; i++) {
        switch(rgvarg[i].vt) {
        case VT_BSTR:
            if (rgvarg[i].bstrVal != NULL) {
                OLECHAR * pch = rgvarg[i].bstrVal - (sizeof(WORD)/sizeof(OLECHAR));
                delete pch;
            }
            break;
            
        case VT_UNKNOWN:
            rgvarg[i].punkVal->Release();
            break;
            
        case VT_DISPATCH:
            rgvarg[i].pdispVal->Release();
            break;
        }
    }
    delete[] rgvarg;
}


// lifetime is controlled by refcounts (see defer.h)

CDeferredCommand::CDeferredCommand(
                                   CCmdQueue * pQ,
                                   LPUNKNOWN    pUnk,
                                   HRESULT *    phr,
                                   LPUNKNOWN    pUnkExecutor,
                                   REFTIME  time,
                                   GUID*    iid,
                                   long dispidMethod,
                                   short    wFlags,
                                   long nArgs,
                                   VARIANT* pDispParams,
                                   VARIANT* pvarResult,
                                   short*   puArgErr,
                                   BOOL bStream
                                   ) :
CUnknown(NAME("DeferredCommand"), pUnk),
m_pQueue(pQ),
m_pUnk(pUnkExecutor),
m_iid(iid),
m_dispidMethod(dispidMethod),
m_wFlags(wFlags),
m_DispParams(nArgs, pDispParams),
m_pvarResult(pvarResult),
m_bStream(bStream),
m_hrResult(E_ABORT)

{
    // convert REFTIME to REFERENCE_TIME
    COARefTime convertor(time);
    m_time = convertor;
    
    // no check of time validity - it's ok to queue a command that's
    // already late
    
    // check iid is supportable on pUnk by QueryInterface for it
    IUnknown * pInterface;
    HRESULT hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface);
    if (FAILED(hr)) {
        *phr = hr;
        return;
    }
    pInterface->Release();
    
    
    // !!! check dispidMethod and param/return types using typelib
    ITypeInfo *pti;
    hr = m_Dispatch.GetTypeInfo(*iid, 0, 0, &pti);
    if (FAILED(hr)) {
        *phr = hr;
        return;
    }
    // !!! some sort of ITypeInfo validity check here
    pti->Release();
    
    
    // Fix up the dispid for put and get
    if (wFlags == DISPATCH_PROPERTYPUT) {
        m_DispParams.cNamedArgs = 1;
        m_DispId = DISPID_PROPERTYPUT;
        m_DispParams.rgdispidNamedArgs = &m_DispId;
    }
    
    // all checks ok - add to queue
    hr = pQ->Insert(this);
    if (FAILED(hr)) {
        *phr = hr;
    }
}


// refcounts are held by caller of InvokeAt... and by list. So if
// we get here, we can't be on the list

#if 0
CDeferredCommand::~CDeferredCommand()
{
    // this assert is invalid since if the queue is deleted while we are
    // still on the queue, we will have been removed by the queue and this
    // m_pQueue will not have been modified.
    // ASSERT(m_pQueue == NULL);
    
    // we don't hold a ref count on pUnk, which is the object that should
    // execute the command.
    // This is because there would otherwise be a circular refcount problem
    // since pUnk probably owns the CmdQueue object that has a refcount
    // on us.
    // The lifetime of pUnk is guaranteed by it being part of, or lifetime
    // controlled by, our parent object. As long as we are on the list, pUnk
    // must be valid. Once we are off the list, we do not use pUnk.
    
}
#endif


// overriden to publicise our interfaces

STDMETHODIMP
CDeferredCommand::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IDeferredCommand) {
        return GetInterface( (IDeferredCommand *) this, ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


// remove from q. this will reduce the refcount by one (since the q
// holds a count) but can't make us go away since he must have a
// refcount in order to call this method.

STDMETHODIMP
CDeferredCommand::Cancel()
{
    if (m_pQueue == NULL) {
        return VFW_E_ALREADY_CANCELLED;
    }
    
    HRESULT hr = m_pQueue->Remove(this);
    if (FAILED(hr)) {
        return hr;
    }
    
    m_pQueue = NULL;
    return S_OK;
}


STDMETHODIMP
CDeferredCommand::Confidence(LONG* pConfidence)
{
    return E_NOTIMPL;
}


STDMETHODIMP
CDeferredCommand::GetHResult(HRESULT * phrResult)
{
    CheckPointer(phrResult,E_POINTER);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -