|
|
/*******************************************************************************
* DTBase.cpp * *------------* * Description: * This module contains the CDXBaseNTo1 transform *------------------------------------------------------------------------------- * Created By: Edward W. Connell Date: 07/28/97 * Copyright (C) 1997 Microsoft Corporation * All Rights Reserved * *------------------------------------------------------------------------------- * Revisions: * *******************************************************************************/ //--- Additional includes
#include <DXTrans.h>
#include "DTBase.h"
#include "new.h"
//--- Initialize static member of debug scope class
#ifdef _DEBUG
CDXTDbgFlags CDXTDbgScope::m_DebugFlags; #endif
//--- This should only be used locally in this file. We duplicated this GUID
// value to avoid having to include DDraw.
static const IID IID_IDXDupDirectDraw = { 0x6C14DB80,0xA733,0x11CE, { 0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 } };
static const IID IID_IDXDupDDrawSurface = { 0x6C14DB81,0xA733,0x11CE, { 0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 } };
static const IID IID_IDXDupDirect3DRM = {0x2bc49361, 0x8327, 0x11cf, {0xac, 0x4a, 0x0, 0x0, 0xc0, 0x38, 0x25, 0xa1 } };
static const IID IID_IDXDupDirect3DRM3 = {0x4516ec83, 0x8f20, 0x11d0, {0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3 } };
static const IID IID_IDXDupDirect3DRMMeshBuilder3 = { 0x4516ec82, 0x8f20, 0x11d0, { 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3} };
HRESULT CDXDataPtr::Assign(BOOL bMesh, IUnknown * pObject, IDXSurfaceFactory *pSurfaceFactory) { HRESULT hr = S_OK; if (pObject) { IUnknown *pNative = NULL; if (!bMesh) { //--- Try to get a DX surface
hr = pObject->QueryInterface( IID_IDXSurface, (void **)&pNative ); if( FAILED( hr ) ) { IDirectDrawSurface *pSurf; //--- Try to get a DDraw surface
hr = pObject->QueryInterface( IID_IDXDupDDrawSurface, (void **)&pSurf ); if( SUCCEEDED( hr ) ) { //--- Create a DXSurface from the DDraw surface
hr = pSurfaceFactory->CreateFromDDSurface( pSurf, NULL, 0, NULL, IID_IDXSurface, (void **)&pNative ); pSurf->Release(); } } } else // Must be a mesh builder
{ hr = pObject->QueryInterface(IID_IDXDupDirect3DRMMeshBuilder3, (void **)&pNative); } if (SUCCEEDED(hr)) { Release(); m_pNativeInterface = pNative; pObject->AddRef(); m_pUnkOriginalObject = pObject; if (SUCCEEDED(pNative->QueryInterface(IID_IDXBaseObject, (void **)&m_pBaseObj))) { m_pBaseObj->GetGenerationId(&m_dwLastDirtyGenId); m_dwLastDirtyGenId--; } if (!bMesh) { ((IDXSurface *)pNative)->GetPixelFormat(NULL, &m_SampleFormat); } } else { if (hr == E_NOINTERFACE) { hr = E_INVALIDARG; } } } else { Release(); } return hr; } /* CDXDataPtr::Assign */
bool CDXDataPtr::IsDirty(void) { if (m_pBaseObj) { DWORD dwOldId = m_dwLastDirtyGenId; m_pBaseObj->GetGenerationId(&m_dwLastDirtyGenId); return dwOldId != m_dwLastDirtyGenId; } else { return false; }
}
DWORD CDXDataPtr::GenerationId(void) { if (m_pBaseObj) { DWORD dwGenId; m_pBaseObj->GetGenerationId(&dwGenId); return dwGenId; } else { return 0; } }
bool CDXDataPtr::UpdateGenerationId(void) { if (m_pBaseObj) { DWORD dwOldId = m_dwLastUpdGenId; m_pBaseObj->GetGenerationId(&m_dwLastUpdGenId); return dwOldId != m_dwLastUpdGenId; } else { return false; } } /* CDXDataPtr::UpdateGenerationId */
ULONG CDXDataPtr::ObjectSize(void) { ULONG ulSize = 0; if (m_pBaseObj) { m_pBaseObj->GetObjectSize(&ulSize); } return ulSize; }
/*****************************************************************************
* CDXBaseNTo1::CDXBaseNTo1 * *--------------------------* * Description: * Constructor *----------------------------------------------------------------------------- * Created By: Ed Connell Date: 07/28/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ CDXBaseNTo1::CDXBaseNTo1() : m_aInputs(NULL), m_ulNumInputs(0), m_ulNumProcessors(1), // Default to one until task manager is set
m_dwGenerationId(1), m_dwCleanGenId(0), m_Duration(1.0f), m_StepResolution(0.0f), m_Progress(0.0f), m_dwBltFlags(0), m_bPickDoneByBase(false), m_bInMultiThreadWorkProc(FALSE), m_fQuality(0.5f), // Default to normal quality.
// Wait forever before timing out on a lock by default
m_ulLockTimeOut(INFINITE), //
// Override these flags if your object does not support one or more of these options.
// Typically, 3-D effects should set this member to 0.
//
m_dwMiscFlags(DXTMF_BLEND_WITH_OUTPUT | DXTMF_DITHER_OUTPUT | DXTMF_BLEND_SUPPORTED | DXTMF_DITHER_SUPPORTED | DXTMF_BOUNDS_SUPPORTED | DXTMF_PLACEMENT_SUPPORTED), //
// If your object has a different number of objects or a different number of
// required objects than 1, simply set these members in the body of your
// constructor or in FinalConstruct(). For every input that is > the number
// required, that input will be reported as optional.
//
// If your transform takes 2 required inputs, set both to 2.
// If your transform takes 2 optional inputs, set MaxInputs = 2, NumInRequired = 0
// If your transform takes 1 required and 2 optional inputs,
// set MaxInputs = 2, NumInRequired = 1
//
// For more complex combinations of optinal/required, you will need to override
// the OnSetup method of this base class, and override the methods
// GetInOutInfo
//
m_ulMaxInputs(1), m_ulNumInRequired(1), //
// If the intputs or output types are not surfaces then set appropriate object type
//
m_dwOptionFlags(0), // Inputs and output are surfaces, don't have to be the same size
m_ulMaxImageBands(DXB_MAX_IMAGE_BANDS), m_fIsSetup(false) { DXTDBG_FUNC( "CDXBaseNTo1::CDXBaseNTo1" ); //
// Set event handles to NULL.
//
memset(m_aEvent, 0, sizeof(m_aEvent)); } /* CDXBaseNTo1::CDXBaseNTo1 */
/*****************************************************************************
* CDXBaseNTo1::~CDXBaseNTo1 * *---------------------------* * Description: * Constructor *----------------------------------------------------------------------------- * Created By: Ed Connell Date: 07/28/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ CDXBaseNTo1::~CDXBaseNTo1() { DXTDBG_FUNC( "CDXBaseNTo1::~CDXBaseNTo1" ); _ReleaseReferences(); delete[] m_aInputs;
//--- Release event objects
for(ULONG i = 0; i < DXB_MAX_IMAGE_BANDS; ++i ) { if( m_aEvent[i] ) ::CloseHandle( m_aEvent[i] ); } } /* CDXBaseNTo1::~CDXBaseNTo1 */
/*****************************************************************************
* CDXBaseNTo1::_ReleaseRefernces * *--------------------------------* * Description: * Releases all references to input and output objects *----------------------------------------------------------------------------- * Created By: RAL *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ void CDXBaseNTo1::_ReleaseReferences() { //--- Release data objects
if( m_aInputs ) { for( ULONG i = 0; i < m_ulNumInputs; ++i ) { m_aInputs[i].Release(); } }
m_Output.Release();
m_fIsSetup = false; } /* CDXBaseNTo1::_ReleaseRefernces */
STDMETHODIMP CDXBaseNTo1::GetGenerationId(ULONG *pGenerationId) { DXTDBG_FUNC( "CDXBaseNTo1::GetGenerationId" ); if (DXIsBadWritePtr(pGenerationId, sizeof(*pGenerationId))) { return E_POINTER; } Lock(); OnUpdateGenerationId(); *pGenerationId = m_dwGenerationId; Unlock(); return S_OK; }
STDMETHODIMP CDXBaseNTo1::IncrementGenerationId(BOOL bRefresh) { DXTDBG_FUNC( "CDXBaseNTo1::IncrementGenerationId" ); HRESULT hr = S_OK; Lock(); m_dwGenerationId++; if (bRefresh) { //
// If we have any inputs or outputs, call Setup again to refresh all internal
// knowledge about the surfaces (formats, height or width could change, etc.)
//
// Note that we need to AddRef the objects prior to calling Setup becuase the
// DXTransform may be the only object holding a referec
//
ULONG cInputs = m_ulNumInputs; ULONG cOutputs = 0; IUnknown *pOutput = m_Output.m_pUnkOriginalObject; if (pOutput) { cOutputs = 1; pOutput->AddRef(); } IUnknown ** ppInputs = NULL; if (cInputs) { ppInputs = (IUnknown **)_alloca(m_ulNumInputs * sizeof(IUnknown *)); for (ULONG i = 0; i < cInputs; i++) { ppInputs[i] = m_aInputs[i].m_pUnkOriginalObject; if (ppInputs[i]) ppInputs[i]->AddRef(); } } if (cInputs || cOutputs) // If we're not setup, skip this step.
{ hr = Setup(ppInputs, cInputs, &pOutput, cOutputs, 0); if (pOutput) pOutput->Release(); for (ULONG i = 0; i < cInputs; i++) { if (ppInputs[i]) ppInputs[i]->Release(); } } } Unlock(); return hr; }
STDMETHODIMP CDXBaseNTo1::GetObjectSize(ULONG *pcbSize) { DXTDBG_FUNC( "CDXBaseNTo1::GetObjectSize" ); HRESULT hr = S_OK; if (DXIsBadWritePtr(pcbSize, sizeof(*pcbSize))) { hr = E_POINTER; } else { Lock(); *pcbSize = OnGetObjectSize(); Unlock(); } return hr; }
void CDXBaseNTo1::_ReleaseServices(void) { m_cpTransFact.Release(); m_cpSurfFact.Release(); m_cpTaskMgr.Release(); m_cpDirectDraw.Release(); m_cpDirect3DRM.Release(); }
//
// The documentation for SetSite indicates that it is invaid to return
// an error from this function, even if the site does not support the
// functionality we want. So, even if there is no service provider, or
// the required services are not available, we will return S_OK.
//
STDMETHODIMP CDXBaseNTo1::SetSite(IUnknown * pUnkSite) { DXTDBG_FUNC( "CDXBaseNTo1::SetSite" ); HRESULT hr = S_OK; Lock(); m_cpUnkSite = pUnkSite; _ReleaseServices(); if (pUnkSite) { if (DXIsBadInterfacePtr(pUnkSite)) { hr = E_INVALIDARG; } else { HRESULT hr2; hr2 = pUnkSite->QueryInterface(IID_IDXTransformFactory, (void **)&m_cpTransFact); if (SUCCEEDED(hr2)) { //
// Allocate memory for inputs if necessary
//
if (m_aInputs == NULL && m_ulMaxInputs) { m_aInputs = new CDXDataPtr[m_ulMaxInputs]; if (!m_aInputs) { _ASSERT(TRUE); hr2 = E_OUTOFMEMORY; } } hr2 = m_cpTransFact->QueryService( SID_SDXSurfaceFactory, IID_IDXSurfaceFactory, (void **)&m_cpSurfFact); if (SUCCEEDED(hr2)) { hr2 = m_cpTransFact->QueryService( SID_SDXTaskManager, IID_IDXTaskManager, (void **)&m_cpTaskMgr); } if (SUCCEEDED(hr2)) { m_cpTaskMgr->QueryNumProcessors(&m_ulNumProcessors); if (m_ulMaxImageBands && (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)) == 0) { for (ULONG i = 0; SUCCEEDED(hr2) && i < m_ulMaxImageBands; i++) { //
// In theory we could get back here after failing to create an event, or
// by getting a new site, so make sure it's non-null before creating one.
//
if (m_aEvent[i] == NULL) { m_aEvent[i] = ::CreateEvent(NULL, true, false, NULL); if (m_aEvent[i] == NULL) { hr2 = E_OUTOFMEMORY; } }
} } } if (SUCCEEDED(hr2)) { hr2 = m_cpTransFact->QueryService(SID_SDirectDraw, IID_IDXDupDirectDraw, (void**)&m_cpDirectDraw); } if (SUCCEEDED(hr2) && (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER))) { hr2 = m_cpTransFact->QueryService(SID_SDirect3DRM, IID_IDXDupDirect3DRM3, (void **)&m_cpDirect3DRM); } if (FAILED(hr2)) { _ASSERT(TRUE); _ReleaseServices(); } } } } Unlock(); return hr; }
STDMETHODIMP CDXBaseNTo1::GetSite(REFIID riid, void **ppv) { DXTDBG_FUNC( "CDXBaseNTo1::GetSite" ); HRESULT hr = S_OK; if( DXIsBadWritePtr(ppv, sizeof(*ppv)) ) { hr = E_POINTER; } else { Lock(); if (m_cpUnkSite) { hr = m_cpUnkSite->QueryInterface(riid, ppv); } else { *ppv = NULL; hr = E_FAIL; // This is the proper documented return code
// for this interface if no service provider.
} Unlock(); } return hr; }
void CDXBaseNTo1::_UpdateBltFlags(void) { m_dwBltFlags = 0; if ((m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER) == 0) { if (m_dwMiscFlags & DXTMF_BLEND_WITH_OUTPUT) { if ((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) || m_ulNumInputs == 0) { m_dwBltFlags |= DXBOF_DO_OVER; } else { for(ULONG i = 0; i < m_ulNumInputs; ++i ) { if (InputSampleFormat(i) & DXPF_TRANSPARENCY) { m_dwBltFlags |= DXBOF_DO_OVER; break; } } } } //
// Set the dither flag to true only if output error is > at least one input
//
if (m_dwMiscFlags & DXTMF_DITHER_OUTPUT) { ULONG OutputErr = (OutputSampleFormat() & DXPF_ERRORMASK); if (OutputErr) { if (m_ulNumInputs) { for(ULONG i = 0; i < m_ulNumInputs; ++i ) { if (InputSurface(i) && (ULONG)(InputSampleFormat(i) & DXPF_ERRORMASK) < OutputErr) { m_dwBltFlags |= DXBOF_DITHER; break; } } } else { //
// If output has no error then don't set dither in blt flags
//
if (OutputErr) { m_dwBltFlags |= DXBOF_DITHER; } } } } } }
/*****************************************************************************
* CDXBaseNTo1::Setup * *--------------------* * Description: * The Setup method is used to perform any required one-time setup * before the Execute method is called. Single surfaces or SurfaceSets may * be used as arguments in any combination. * If punkOutputs is NULL, Execute will allocate an output result of the * appropriate size and return it. * if punkInputs and punkOutputs are NULL and it is a quick setup, the current * input and output objects are released. *----------------------------------------------------------------------------- * Created By: Ed Connell Date: 07/28/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::Setup( IUnknown * const * punkInputs, ULONG ulNumInputs, IUnknown * const * punkOutputs, ULONG ulNumOutputs, DWORD dwFlags ) { DXTDBG_FUNC( "CDXBaseNTo1::Setup" ); //--- Lock object so state cannot change during setup
DXAUTO_OBJ_LOCK HRESULT hr = S_OK; ULONG i;
//
// Early out for null setup. Forget about all other param validation, just do it.
//
if (ulNumInputs == 0 && ulNumOutputs == 0) { _ReleaseReferences(); OnReleaseObjects(); return hr; }
//--- Validate Params
//--- Make sure we have a reference to the transform factory
if( !m_cpTransFact ) { hr = DXTERR_UNINITIALIZED; DXTDBG_MSG0( _CRT_ERROR, "\nTransform has not been initialized" ); } else { //
// We know that if we have a transform factory that we must also have
// allocated m_aInputs since this is done on SetSite to avoid work during
// each setup.
//
_ASSERT(m_aInputs || m_ulMaxInputs == 0); if( dwFlags || // No flags are valid
ulNumOutputs != 1 || ulNumInputs < m_ulNumInRequired || ulNumInputs > m_ulMaxInputs || (ulNumInputs && DXIsBadReadPtr( punkInputs , sizeof( *punkInputs ) * ulNumInputs )) || DXIsBadReadPtr(punkOutputs, sizeof(*punkOutputs)) || DXIsBadInterfacePtr(punkOutputs[0])) { hr = E_INVALIDARG; DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" ); } else { for( i = 0; i < ulNumInputs; ++i ) { if((punkInputs[i] && DXIsBadInterfacePtr(punkInputs[i])) || (punkInputs[i] == NULL && i < m_ulNumInRequired)) { hr = E_INVALIDARG; DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" ); break; } } } }
//--- Allocate slots for input data object pointers
if( SUCCEEDED( hr ) ) { //--- Release data objects
_ReleaseReferences(); m_ulNumInputs = ulNumInputs; }
//
// Assign
//
for( i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i ) { hr = m_aInputs[i].Assign((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER), punkInputs[i], m_cpSurfFact); }
if( SUCCEEDED(hr) ) { hr = m_Output.Assign((m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER), punkOutputs[0], m_cpSurfFact); }
if (SUCCEEDED(hr) && (m_dwOptionFlags & DXBOF_SAME_SIZE_INPUTS)) { hr = _MakeInputsSameSize(); }
if (SUCCEEDED(hr)) { _UpdateBltFlags(); // Do this before calling OnSetup...
hr = OnSetup(dwFlags); } if (FAILED(hr)) { _ReleaseReferences(); OnReleaseObjects(); DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup failed" ); } else { m_fIsSetup = true; }
return hr; } /* CDXBaseNTo1::Setup */
/*****************************************************************************
* CDXBaseNTo1::_MakeInputsSameSize * *----------------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 03/31/98 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/
HRESULT CDXBaseNTo1::_MakeInputsSameSize(void) { _ASSERT((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) == 0);
HRESULT hr = S_OK; if (m_ulNumInputs > 1) // No need to do this for just one input!
{ CDXDBnds SurfBnds(false); CDXDBnds Union(true); ULONG i; for (i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; i++) { if (InputSurface(i)) { hr = SurfBnds.SetToSurfaceBounds(InputSurface(i)); Union |= SurfBnds; } } for (i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; i++) { if (InputSurface(i)) { hr = SurfBnds.SetToSurfaceBounds(InputSurface(i)); if (SUCCEEDED(hr) && SurfBnds != Union) { IDXSurfaceModifier *pSurfMod; hr = ::CoCreateInstance(CLSID_DXSurfaceModifier, NULL, CLSCTX_INPROC, IID_IDXSurfaceModifier, (void **)&pSurfMod); if (SUCCEEDED(hr)) { POINT p; p.x = p.y = 0; if (m_dwOptionFlags & DXBOF_CENTER_INPUTS) { p.x = (Union.Width() - SurfBnds.Width()) / 2; p.y = (Union.Height() - SurfBnds.Height()) / 2; } pSurfMod->SetForeground(InputSurface(i), FALSE, &p); pSurfMod->SetBounds(&Union); InputSurface(i)->Release(); pSurfMod->QueryInterface(IID_IDXSurface, (void **)&(m_aInputs[i].m_pNativeInterface)); ((IDXSurface *)m_aInputs[i].m_pNativeInterface)->GetPixelFormat(NULL, &m_aInputs[i].m_SampleFormat); pSurfMod->Release(); } } } } } return hr; }
/*****************************************************************************
* CDXBaseNTo1::Execute * *----------------------* * Description: * The Execute method is used to walk the inputs/outputs and break up the * work into suitably sized pieces to spread symetrically accross the available * processors in the system. *----------------------------------------------------------------------------- * Created By: Ed Connell Date: 07/28/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1:: Execute( const GUID* pRequestID, const DXBNDS *pClipBnds, const DXVEC *pPlacement ) { DXTDBG_FUNC( "CDXBaseNTo1::Execute" ); //--- Lock object so state cannot change during execution
DXAUTO_OBJ_LOCK HRESULT hr = S_OK;
//--- Check args
if( !HaveOutput() ) { DXTDBG_MSG0( _CRT_ERROR, "\nTransform has not been initialized" ); return DXTERR_UNINITIALIZED; }
if (m_ulMaxImageBands == 0 || (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER))) { if ((pClipBnds && (m_dwMiscFlags & DXTMF_BOUNDS_SUPPORTED) == 0) || (pPlacement && (m_dwMiscFlags & DXTMF_PLACEMENT_SUPPORTED) == 0) ) { DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" ); return E_INVALIDARG; } return OnExecute( pRequestID, pClipBnds, pPlacement ); }
//--- Banded image working variables
CDXTWorkInfoNTo1 WI;
if ((pClipBnds && pClipBnds->eType != DXBT_DISCRETE) || (pPlacement && pPlacement->eType != DXBT_DISCRETE)) { hr = E_INVALIDARG; DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" ); } else { hr = MapBoundsIn2Out( NULL, 0, 0, &WI.DoBnds ); if( hr == S_OK ) { hr = WI.OutputBnds.SetToSurfaceBounds(OutputSurface()); if (hr == S_OK) { hr = DXClipToOutputWithPlacement(WI.DoBnds, (CDXDBnds *)pClipBnds, WI.OutputBnds, (CDXDVec *)pPlacement); } } }
//--- Check for clipping early exit
if( hr != S_OK ) { return hr; }
//=== Process ====================================================
_ASSERT(m_ulMaxImageBands <= DXB_MAX_IMAGE_BANDS); ULONG ulNumBandsToDo = m_ulNumProcessors; if( ulNumBandsToDo > 1 ) { ulNumBandsToDo = 1 + ((WI.OutputBnds.Width() * WI.OutputBnds.Height()) / 0x1000); if (ulNumBandsToDo > m_ulMaxImageBands) { ulNumBandsToDo = m_ulMaxImageBands; } if (ulNumBandsToDo > m_ulNumProcessors) { ulNumBandsToDo = m_ulNumProcessors; } } hr = OnInitInstData(WI, ulNumBandsToDo); if( SUCCEEDED( hr ) ) { if (ulNumBandsToDo == 1 && pRequestID == NULL) { static BOOL bContinue = TRUE; hr = WorkProc(WI, &bContinue); } else { _ASSERT( ulNumBandsToDo <= DXB_MAX_IMAGE_BANDS ); _ASSERT( m_aEvent[ulNumBandsToDo-1] );
long lStartAtRow = WI.DoBnds[DXB_Y].Min; ULONG ulRowCount = WI.DoBnds[DXB_Y].Max - lStartAtRow; _ASSERT( ( ulRowCount / ulNumBandsToDo ) != 0 );
//--- Init the work info structures
ULONG ulBand, RowsPerBand = ulRowCount / ulNumBandsToDo; CDXTWorkInfoNTo1 *WIArray = (CDXTWorkInfoNTo1*)alloca( sizeof(CDXTWorkInfoNTo1) * ulNumBandsToDo ); DWORD *TaskIDs = (DWORD*)alloca( sizeof(DWORD) * ulNumBandsToDo ); DXTMTASKINFO* TaskInfo = (DXTMTASKINFO*)alloca( sizeof( DXTMTASKINFO ) * ulNumBandsToDo );
//--- Build task info list
WI.hr = S_OK; WI.pvThis = this; long Start = lStartAtRow; ULONG Count = RowsPerBand; long OutputYDelta = WI.OutputBnds[DXB_Y].Min - WI.DoBnds[DXB_Y].Min;
for (ulBand = 0; ulBand < ulNumBandsToDo; ++ulBand) { memcpy(&WIArray[ulBand], &WI, sizeof(WI));
WIArray[ulBand].DoBnds[DXB_Y].Min = Start; WIArray[ulBand].OutputBnds[DXB_Y].Min = Start + OutputYDelta;
// If this is the last band, make sure it includes the last row.
if (ulBand == ulNumBandsToDo - 1) { WIArray[ulBand].DoBnds[DXB_Y].Max = WI.DoBnds[DXB_Y].Max; WIArray[ulBand].OutputBnds[DXB_Y].Max = WI.OutputBnds[DXB_Y].Max; } else // Not the last band.
{ WIArray[ulBand].DoBnds[DXB_Y].Max = Start + Count; WIArray[ulBand].OutputBnds[DXB_Y].Max = Start + Count + OutputYDelta; }
TaskInfo[ulBand].pfnTaskProc = _TaskProc; TaskInfo[ulBand].pTaskData = &WIArray[ulBand]; TaskInfo[ulBand].pfnCompletionAPC = NULL; TaskInfo[ulBand].dwCompletionData = 0; TaskInfo[ulBand].pRequestID = pRequestID;
// Advance.
Start += Count; }
//
// Procedural surfaces (and perhaps some transforms) need to "know" that
// they are in a multi-threaded work procedure to avoid deadlocks. Procedural
// surfaces need to allow LockSurface to work WITHOUT taking the object
// critical section. Other transforms may also want to know this information
// to avoid deadlocks.
//
m_bInMultiThreadWorkProc = TRUE;
//--- Schedule the work and wait for it to complete
hr = m_cpTaskMgr->ScheduleTasks( TaskInfo, m_aEvent, TaskIDs, ulNumBandsToDo, m_ulLockTimeOut );
m_bInMultiThreadWorkProc = FALSE;
//--- Check return codes from work info structures
// return the first bad hr if any
for( ulBand = 0; SUCCEEDED( hr ) && ( ulBand < ulNumBandsToDo ); ++ulBand ) { hr = WIArray[ulBand].hr; if( hr != S_OK ) break; } } OnFreeInstData( WI ); }
#ifdef _DEBUG
if( FAILED( hr ) ) DXTDBG_MSG1( _CRT_ERROR, "\nExecute failed. HR = %X", hr ); #endif
return hr; } /* CDXBaseNTo1::Execute */
/*****************************************************************************
* CDXBaseNTo1::_ImageMapIn2Out * *------------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 07/28/97 *****************************************************************************/ HRESULT CDXBaseNTo1::_ImageMapIn2Out( CDXDBnds & bnds, ULONG ulNumInBnds, const CDXDBnds * pInBounds ) { HRESULT hr = S_OK; if(ulNumInBnds) { for(ULONG i = 0; i < ulNumInBnds; ++i ) { bnds |= pInBounds[i]; } } else { for( ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i ) { if (InputSurface(i)) { CDXDBnds SurfBnds(InputSurface(i), hr); bnds |= SurfBnds; } } } if (SUCCEEDED(hr)) { hr = DetermineBnds(bnds); } return hr; } /* CDXBaseNTo1::_ImageMapIn2Out */
/*****************************************************************************
* CDXBaseNTo1::_MeshMapIn2Out * *-----------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 07/28/97 *****************************************************************************/ HRESULT CDXBaseNTo1::_MeshMapIn2Out(CDXCBnds & bnds, ULONG ulNumInBnds, CDXCBnds * pInBounds) { HRESULT hr = S_OK; if (m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) { if(ulNumInBnds) { for(ULONG i = 0; i < ulNumInBnds; ++i ) { bnds |= pInBounds[i]; } } else { for(ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i ) { if (InputMeshBuilder(i)) { CDXCBnds MeshBnds(InputMeshBuilder(i), hr); bnds |= MeshBnds; } }
} } else { // Already done -> bnds[DXB_T].Min = 0.0f;
bnds[DXB_X].Min = bnds[DXB_Y].Min = bnds[DXB_Z].Min = -1.0f; bnds[DXB_X].Max = bnds[DXB_Y].Max = bnds[DXB_Z].Max = bnds[DXB_T].Max = 1.0f; }
//
// Call the derived class to get the scale values.
//
if (SUCCEEDED(hr)) { // Increase the size just a bit so we won't have rounding errors
// result in bounds that don't actually contain the result.
const float fBndsIncrease = 0.0001F; float fTemp = bnds.Width() * fBndsIncrease;
bnds[DXB_X].Min -= fTemp; bnds[DXB_X].Max += fTemp;
fTemp = fBndsIncrease * bnds.Height(); bnds[DXB_Y].Min -= fTemp; bnds[DXB_Y].Max += fTemp;
fTemp = fBndsIncrease * bnds.Depth(); bnds[DXB_Z].Min -= fTemp; bnds[DXB_Z].Max += fTemp;
hr = DetermineBnds(bnds); } return hr; } /* CDXBaseNTo1::_MeshMapIn2Out */
/*****************************************************************************
* CDXBaseNTo1::MapBoundsIn2Out * *------------------------------* * Description: * The MapBoundsIn2Out method is used to perform coordinate transformation * from the input to the output coordinate space. *----------------------------------------------------------------------------- * Created By: Ed Connell Date: 07/28/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::MapBoundsIn2Out( const DXBNDS *pInBounds, ULONG ulNumInBnds, ULONG ulOutIndex, DXBNDS *pOutBounds ) { DXTDBG_FUNC( "CDXBaseNTo1::MapBoundsIn2Out" ); if((ulNumInBnds && DXIsBadReadPtr( pInBounds, ulNumInBnds * sizeof( *pInBounds ) )) || ulOutIndex) { return E_INVALIDARG; }
if( DXIsBadWritePtr( pOutBounds, sizeof( *pOutBounds ) ) ) { return E_POINTER; } //
// Set the bounds to empty and the appropriate type.
//
memset(pOutBounds, 0, sizeof(*pOutBounds)); _ASSERT(DXBT_DISCRETE == 0); if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER) { pOutBounds->eType = DXBT_CONTINUOUS; }
//
// Make sure all input bounds are of the correct type.
//
if( ulNumInBnds ) { DXBNDTYPE eType = (m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) ? DXBT_CONTINUOUS : DXBT_DISCRETE; for (ULONG i = 0; i < ulNumInBnds; i++) { if (pInBounds[i].eType != eType) { return E_INVALIDARG; } } }
//
// Now do the appropriate mapping
//
if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER) { //
// NOTE: In the case of non-mesh inputs, the inputs are discrete, but they will
// be completely ignored by the function so it's OK to cast them to CDXCBnds
//
return _MeshMapIn2Out(*((CDXCBnds *)pOutBounds), ulNumInBnds, (CDXCBnds *)pInBounds); } else { return _ImageMapIn2Out(*(CDXDBnds *)pOutBounds, ulNumInBnds, (CDXDBnds *)pInBounds); } } /* CDXBaseNTo1::MapBoundsIn2Out */
/*****************************************************************************
* CDXBaseNTo1::MapBoundsOut2In * *------------------------------* * Description: * The MapBoundsOut2In method is used to perform coordinate transformation * from the input to the output coordinate space. *----------------------------------------------------------------------------- * Created By: Ed Connell Date: 07/28/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1:: MapBoundsOut2In( ULONG ulOutIndex, const DXBNDS *pOutBounds, ULONG ulInIndex, DXBNDS *pInBounds ) { DXTDBG_FUNC( "CDXBaseNTo1::MapBoundsOut2In" ); HRESULT hr = S_OK; if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER) { hr = E_NOTIMPL; // This is pointless for meshes.
} else if(ulInIndex >= m_ulMaxInputs || ulOutIndex || DXIsBadReadPtr( pOutBounds, sizeof( *pOutBounds ) ) ) { hr = E_INVALIDARG; } else if( DXIsBadWritePtr( pInBounds, sizeof( *pInBounds ) ) ) { hr = E_POINTER; } else { *pInBounds = *pOutBounds; } return hr; } /* CDXBaseNTo1::MapBoundsOut2In */
/*****************************************************************************
* CDXBaseNTo1::SetMiscFlags * *---------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 10/30.97 *----------------------------------------------------------------------------- * Parameters: * bMiscFlags - New value to set *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::SetMiscFlags( DWORD dwMiscFlags ) { DXTDBG_FUNC( "CDXBaseNTo1::SetMiscFlags" ); HRESULT hr = S_OK; Lock(); WORD wOpts = (WORD)dwMiscFlags; // Ignore high word. Only set low word.
if (((WORD)m_dwMiscFlags) != wOpts) { if ((wOpts & (~DXTMF_VALID_OPTIONS)) || ((wOpts & DXTMF_BLEND_WITH_OUTPUT) && (m_dwMiscFlags & DXTMF_BLEND_SUPPORTED) == 0) || ((wOpts & DXTMF_DITHER_OUTPUT) && (m_dwMiscFlags & DXTMF_DITHER_SUPPORTED) == 0)) { hr = E_INVALIDARG; } else { m_dwMiscFlags &= 0xFFFF0000; m_dwMiscFlags |= wOpts; _UpdateBltFlags(); m_dwGenerationId++; } } Unlock(); return hr; } /* CDXBaseNTo1::SetMiscFlags */
/*****************************************************************************
* CDXBaseNTo1::GetMiscFlags * *----------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 10/30/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::GetMiscFlags( DWORD* pdwMiscFlags ) { if( DXIsBadWritePtr( pdwMiscFlags, sizeof( *pdwMiscFlags ) ) ) { return E_POINTER; } *pdwMiscFlags = m_dwMiscFlags; return S_OK; } /* CDXBaseNTo1::GetMiscFlags */
/*****************************************************************************
* CDXBaseNTo1::SetQuality * *----------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 10/30/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::SetQuality(float fQuality) { if ((m_dwMiscFlags & DXTMF_QUALITY_SUPPORTED) == 0) { return E_NOTIMPL; }
if (fQuality < 0.0f || fQuality > 1.0f) { return E_INVALIDARG; }
Lock(); if (m_fQuality != fQuality) { m_fQuality = fQuality; m_dwGenerationId++; } Unlock();
return S_OK; }
/*****************************************************************************
* CDXBaseNTo1::GetQuality * *-------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 10/30/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/
STDMETHODIMP CDXBaseNTo1::GetQuality(float *pfQuality) { HRESULT hr = S_OK;
if ((m_dwMiscFlags & DXTMF_QUALITY_SUPPORTED) == 0) { hr = E_NOTIMPL; } else { if( DXIsBadWritePtr( pfQuality, sizeof( *pfQuality ) ) ) { hr = E_POINTER; } else { *pfQuality = m_fQuality; } } return hr; }
/*****************************************************************************
* GetInOutInfo *----------------------------------------------------------------------------- * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::GetInOutInfo( BOOL bOutput, ULONG ulIndex, DWORD *pdwFlags, GUID * pIDs, ULONG *pcIDs, IUnknown **ppUnkCurObj ) { DXTDBG_FUNC( "CDXBaseNTo1::GetInOutInfo" ); HRESULT hr = S_FALSE; DWORD dwFlags = 0; BOOL bImage; if( bOutput ) { bImage = !(m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER); if (ulIndex == 0) { hr = S_OK; } } else { bImage = !(m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER); if (ulIndex < m_ulMaxInputs) { hr = S_OK; if (ulIndex >= m_ulNumInRequired) { dwFlags = DXINOUTF_OPTIONAL; } } } if( hr == S_OK ) { if( pdwFlags && !DXIsBadWritePtr( pdwFlags, sizeof( *pdwFlags ) ) ) { *pdwFlags = dwFlags; }
if( pIDs ) { if( DXIsBadWritePtr( pcIDs, sizeof( *pcIDs ) ) || DXIsBadWritePtr( pIDs, *pcIDs * sizeof( *pIDs ) ) ) { hr = E_INVALIDARG; } else { if (bImage) { if (*pcIDs > 0) { pIDs[0] = IID_IDXSurface; } if (*pcIDs > 1) { pIDs[1] = IID_IDXDupDDrawSurface; } else { hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA); } *pcIDs = 2; } else { if (*pcIDs > 0) { pIDs[0] = IID_IDXDupDirect3DRMMeshBuilder3; } else { hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA); } *pcIDs = 1; } } } else if( pcIDs ) { if( DXIsBadWritePtr( pcIDs, sizeof( *pcIDs ) ) ) { hr = E_POINTER; } else { *pcIDs = bImage ? 2 : 1; } } if (hr == S_OK && ppUnkCurObj) { if (DXIsBadWritePtr(ppUnkCurObj, sizeof(*ppUnkCurObj))) { hr = E_POINTER; } else { if (bOutput) { *ppUnkCurObj = m_Output.m_pNativeInterface; } else { *ppUnkCurObj = NULL; if (ulIndex < GetNumInputs()) { *ppUnkCurObj = m_aInputs[ulIndex].m_pUnkOriginalObject; } } if (*ppUnkCurObj) { (*ppUnkCurObj)->AddRef(); } } } } return hr; } /* CDXBaseNTo1::GetInOutInfo */
/*****************************************************************************
* CDXBaseNTo1::OnUpdateGenerationId * *-----------------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ void CDXBaseNTo1::OnUpdateGenerationId(void) { DXTDBG_FUNC( "CDXBaseNTo1::OnUpdateGenerationId" ); if( (m_dwMiscFlags & DXTMF_INPLACE_OPERATION) && m_Output.UpdateGenerationId()) { m_dwGenerationId++; } for (ULONG i = 0; i < m_ulNumInputs; i++) { if (m_aInputs[i].UpdateGenerationId()) { m_dwGenerationId++; } } } /* CDXBaseNTo1::OnUpdateGenerationId */
/*****************************************************************************
* CDXBaseNTo1::OnGetObjectSize * *------------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *****************************************************************************/ ULONG CDXBaseNTo1::OnGetObjectSize(void) { return sizeof(*this); }
//
// Effect interface
//
/*****************************************************************************
* CDXBaseNTo1::get_Progress * *---------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::get_Progress(float *pVal) { DXTDBG_FUNC( "CDXBaseNTo1::get_Progress" ); HRESULT hr = S_OK; if( DXIsBadWritePtr(pVal, sizeof(*pVal)) ) { hr = E_POINTER; } else { *pVal = m_Progress; } return hr; }
/*****************************************************************************
* CDXBaseNTo1::put_Progress * *---------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::put_Progress(float newVal) { DXTDBG_FUNC( "CDXBaseNTo1::put_Progress" ); HRESULT hr = S_OK; if (newVal < 0.0 || newVal > 1.0f) { hr = E_INVALIDARG; } else { Lock(); m_Progress = newVal; m_dwCleanGenId++; // This should not make the transform "dirty" internally
m_dwGenerationId++; Unlock(); } return hr; }
/*****************************************************************************
* CDXBaseNTo1::get_StepResolution * *---------------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::get_StepResolution(float *pVal) { DXTDBG_FUNC( "CDXBaseNTo1::get_StepResolution" ); HRESULT hr = S_OK; if( DXIsBadWritePtr(pVal, sizeof(*pVal)) ) { hr = E_POINTER; } else { *pVal = m_StepResolution; } return hr; }
/*****************************************************************************
* CDXBaseNTo1::get_Duration * *---------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::get_Duration(float *pVal) { DXTDBG_FUNC( "CDXBaseNTo1::get_Duration" ); if( DXIsBadWritePtr(pVal, sizeof(*pVal)) ) { return E_POINTER; } else { *pVal = m_Duration; } return S_OK; }
/*****************************************************************************
* CDXBaseNTo1::put_Duration * *---------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::put_Duration(float newVal) { DXTDBG_FUNC( "CDXBaseNTo1::put_Duration" ); if (newVal <= 0.) { return E_INVALIDARG; } if(newVal != m_Duration) { Lock(); m_dwGenerationId++; m_dwCleanGenId++; // This should not make the transform "dirty" internally
m_Duration = newVal; Unlock(); } return S_OK; }
/*****************************************************************************
* CDXBaseNTo1::PointPick * *------------------------* * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 5/5/98 *****************************************************************************/ STDMETHODIMP CDXBaseNTo1::PointPick(const DXVEC *pPoint, ULONG * pulInputSurfaceIndex, DXVEC *pInputPoint) { HRESULT hr = S_OK; BOOL bFoundIt = FALSE;
// If we haven't been set up yet, we will just act as if we're transparent.
if (!m_fIsSetup) { hr = S_FALSE;
goto done; }
if (DXIsBadReadPtr(pPoint, sizeof(*pPoint)) || pPoint->eType != DXBT_DISCRETE) { hr = E_INVALIDARG; } else { if (DXIsBadWritePtr(pulInputSurfaceIndex, sizeof(*pulInputSurfaceIndex)) || DXIsBadWritePtr(pInputPoint, sizeof(*pInputPoint))) { hr = E_POINTER; } else { HRESULT hr2 = S_OK; CDXDBnds bndsOutput; CDXDBnds OutBndsPoint(*((CDXDVec *)pPoint)); CDXDVec & InVec = *(new(pInputPoint) CDXDVec(*((CDXDVec *)pPoint)));
// Get the output size of the DXTransform. If this point is not on
// the output at all, we can return S_FALSE right now.
hr = MapBoundsIn2Out(NULL, 0, 0, &bndsOutput);
if (FAILED(hr)) { goto done; }
if (!bndsOutput.TestIntersect(OutBndsPoint)) { hr = S_FALSE;
goto done; }
hr2 = OnSurfacePick(OutBndsPoint, *pulInputSurfaceIndex, InVec);
if (hr2 != E_NOTIMPL) { hr = hr2; } else { //--- The derived class does not implement so we will do
// the hit test against the input for them.
ULONG * aulInIndex = (ULONG *)_alloca(sizeof(ULONG) * m_ulMaxInputs); BYTE * aWeights = (BYTE *)_alloca(sizeof(BYTE) * m_ulMaxInputs); ULONG ulNumToTest; OnGetSurfacePickOrder(OutBndsPoint, ulNumToTest, aulInIndex, aWeights);
if( m_bPickDoneByBase && ( m_ulNumInputs > 1 ) ) { //--- We don't know how to do multi-input picking from the base.
hr = E_NOTIMPL; }
for (ULONG i = 0; SUCCEEDED(hr) && i < ulNumToTest; i++) { ULONG ulInput = aulInIndex[i]; if (HaveInput(ulInput) && aWeights[i]) { CDXDBnds Out2InBnds(false); hr = MapBoundsOut2In(0, &OutBndsPoint, ulInput, &Out2InBnds); if (SUCCEEDED(hr)) { CDXDBnds InSurfBnds(InputSurface(ulInput), hr); if (SUCCEEDED(hr) && InSurfBnds.IntersectBounds(Out2InBnds)) { IDXARGBReadPtr * pPtr; hr = InputSurface(ulInput)->LockSurface(&InSurfBnds, m_ulLockTimeOut, DXLOCKF_READ, IID_IDXARGBReadPtr, (void **)&pPtr, NULL); if( SUCCEEDED(hr) ) { DXPMSAMPLE val; pPtr->UnpackPremult(&val, 1, FALSE); pPtr->Release(); if (val.Alpha * aWeights[i] / 255) { InSurfBnds.GetMinVector(InVec); bFoundIt = TRUE; *pulInputSurfaceIndex = ulInput; break; } } } } } } if (SUCCEEDED(hr) & (!bFoundIt)) { hr = S_FALSE; } } } }
done:
return hr; } /* CDXBaseNTo1::PointPick */
/*****************************************************************************
* RegisterTansform (STATIC member function) *----------------------------------------------------------------------------- * Description: *----------------------------------------------------------------------------- * Created By: RAL Date: 12/10/97 *----------------------------------------------------------------------------- * Parameters: *****************************************************************************/ HRESULT CDXBaseNTo1:: RegisterTransform(REFCLSID rcid, int ResourceId, ULONG cCatImpl, const CATID * pCatImpl, ULONG cCatReq, const CATID * pCatReq, BOOL bRegister) { DXTDBG_FUNC( "CDXBaseNTo1::RegisterTransform" ); HRESULT hr = bRegister ? _Module.UpdateRegistryFromResource(ResourceId, bRegister) : S_OK; if (SUCCEEDED(hr)) { CComPtr<ICatRegister> pCatRegister; HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC, IID_ICatRegister, (void **)&pCatRegister); if (SUCCEEDED(hr)) { if (bRegister) { hr = pCatRegister->RegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl); if (SUCCEEDED(hr) && cCatReq && pCatReq) { hr = pCatRegister->RegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq); } } else { pCatRegister->UnRegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl); if (cCatReq && pCatReq) { pCatRegister->UnRegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq); } } } } if ((!bRegister) && SUCCEEDED(hr)) { _Module.UpdateRegistryFromResource(ResourceId, bRegister); } return hr; }
void CDXBaseNTo1::_TaskProc(void* pTaskInfo, BOOL* pbContinue ) { _ASSERT( pTaskInfo ); CDXTWorkInfoNTo1& WI = *((CDXTWorkInfoNTo1 *)pTaskInfo); CDXBaseNTo1& This = *((CDXBaseNTo1 *)WI.pvThis); WI.hr = This.WorkProc(WI, pbContinue); }
|