📄 ctlutil.cpp
字号:
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 + -