📄 compositemoniker.c
字号:
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
return E_NOINTERFACE;
/* Query Interface always increases the reference count by one when it is successful */
IEnumMoniker_AddRef(iface);
return S_OK;
}
/******************************************************************************
* EnumMonikerImpl_AddRef
******************************************************************************/
static ULONG WINAPI
EnumMonikerImpl_AddRef(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p)\n",This);
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
* EnumMonikerImpl_Release
******************************************************************************/
static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
ULONG i;
ULONG ref;
TRACE("(%p)\n",This);
ref = InterlockedDecrement(&This->ref);
/* destroy the object if there's no more reference on it */
if (ref == 0) {
for(i=0;i<This->tabSize;i++)
IMoniker_Release(This->tabMoniker[i]);
HeapFree(GetProcessHeap(),0,This->tabMoniker);
HeapFree(GetProcessHeap(),0,This);
}
return ref;
}
/******************************************************************************
* EnumMonikerImpl_Next
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt,
ULONG* pceltFethed)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
ULONG i;
/* retrieve the requested number of moniker from the current position */
for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
rgelt[i]=This->tabMoniker[This->currentPos++];
if (pceltFethed!=NULL)
*pceltFethed= i;
if (i==celt)
return S_OK;
else
return S_FALSE;
}
/******************************************************************************
* EnumMonikerImpl_Skip
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
if ((This->currentPos+celt) >= This->tabSize)
return S_FALSE;
This->currentPos+=celt;
return S_OK;
}
/******************************************************************************
* EnumMonikerImpl_Reset
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
This->currentPos=0;
return S_OK;
}
/******************************************************************************
* EnumMonikerImpl_Clone
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
}
/********************************************************************************/
/* Virtual function table for the IROTData class */
static const IEnumMonikerVtbl VT_EnumMonikerImpl =
{
EnumMonikerImpl_QueryInterface,
EnumMonikerImpl_AddRef,
EnumMonikerImpl_Release,
EnumMonikerImpl_Next,
EnumMonikerImpl_Skip,
EnumMonikerImpl_Reset,
EnumMonikerImpl_Clone
};
/******************************************************************************
* EnumMonikerImpl_CreateEnumMoniker
******************************************************************************/
static HRESULT
EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize,
ULONG currentPos, BOOL leftToRigth, IEnumMoniker ** ppmk)
{
EnumMonikerImpl* newEnumMoniker;
int i;
if (currentPos > tabSize)
return E_INVALIDARG;
newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
if (newEnumMoniker == 0)
return STG_E_INSUFFICIENTMEMORY;
/* Initialize the virtual function table. */
newEnumMoniker->lpVtbl = &VT_EnumMonikerImpl;
newEnumMoniker->ref = 0;
newEnumMoniker->tabSize=tabSize;
newEnumMoniker->currentPos=currentPos;
newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(IMoniker));
if (newEnumMoniker->tabMoniker==NULL) {
HeapFree(GetProcessHeap(), 0, newEnumMoniker);
return E_OUTOFMEMORY;
}
if (leftToRigth)
for (i=0;i<tabSize;i++){
newEnumMoniker->tabMoniker[i]=tabMoniker[i];
IMoniker_AddRef(tabMoniker[i]);
}
else
for (i=tabSize-1;i>=0;i--){
newEnumMoniker->tabMoniker[tabSize-i-1]=tabMoniker[i];
IMoniker_AddRef(tabMoniker[i]);
}
*ppmk=(IEnumMoniker*)newEnumMoniker;
return S_OK;
}
/********************************************************************************/
/* Virtual function table for the CompositeMonikerImpl class which includes */
/* IPersist, IPersistStream and IMoniker functions. */
static const IMonikerVtbl VT_CompositeMonikerImpl =
{
CompositeMonikerImpl_QueryInterface,
CompositeMonikerImpl_AddRef,
CompositeMonikerImpl_Release,
CompositeMonikerImpl_GetClassID,
CompositeMonikerImpl_IsDirty,
CompositeMonikerImpl_Load,
CompositeMonikerImpl_Save,
CompositeMonikerImpl_GetSizeMax,
CompositeMonikerImpl_BindToObject,
CompositeMonikerImpl_BindToStorage,
CompositeMonikerImpl_Reduce,
CompositeMonikerImpl_ComposeWith,
CompositeMonikerImpl_Enum,
CompositeMonikerImpl_IsEqual,
CompositeMonikerImpl_Hash,
CompositeMonikerImpl_IsRunning,
CompositeMonikerImpl_GetTimeOfLastChange,
CompositeMonikerImpl_Inverse,
CompositeMonikerImpl_CommonPrefixWith,
CompositeMonikerImpl_RelativePathTo,
CompositeMonikerImpl_GetDisplayName,
CompositeMonikerImpl_ParseDisplayName,
CompositeMonikerImpl_IsSystemMoniker
};
/********************************************************************************/
/* Virtual function table for the IROTData class. */
static const IROTDataVtbl VT_ROTDataImpl =
{
CompositeMonikerROTDataImpl_QueryInterface,
CompositeMonikerROTDataImpl_AddRef,
CompositeMonikerROTDataImpl_Release,
CompositeMonikerROTDataImpl_GetComparaisonData
};
/******************************************************************************
* Composite-Moniker_Construct (local function)
*******************************************************************************/
static HRESULT
CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
LPMONIKER pmkFirst, LPMONIKER pmkRest)
{
DWORD mkSys;
IEnumMoniker *enumMoniker;
IMoniker *tempMk;
HRESULT res;
TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
/* Initialize the virtual function table. */
This->lpvtbl1 = &VT_CompositeMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->tabSize=BLOCK_TAB_SIZE;
This->tabLastIndex=0;
This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
/* put the first moniker contents in the beginning of the table */
if (mkSys!=MKSYS_GENERICCOMPOSITE){
This->tabMoniker[(This->tabLastIndex)++]=pmkFirst;
IMoniker_AddRef(pmkFirst);
}
else{
IMoniker_Enum(pmkFirst,TRUE,&enumMoniker);
while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
if (++This->tabLastIndex==This->tabSize){
This->tabSize+=BLOCK_TAB_SIZE;
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
}
}
IEnumMoniker_Release(enumMoniker);
}
/* put the rest moniker contents after the first one and make simplification if needed */
IMoniker_IsSystemMoniker(pmkRest,&mkSys);
if (mkSys!=MKSYS_GENERICCOMPOSITE){
/* add a simple moniker to the moniker table */
res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk);
if (res==MK_E_NEEDGENERIC){
/* there's no simplification in this case */
This->tabMoniker[This->tabLastIndex]=pmkRest;
This->tabLastIndex++;
IMoniker_AddRef(pmkRest);
}
else if (tempMk==NULL){
/* we have an antimoniker after a simple moniker so we can make a simplification in this case */
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
This->tabLastIndex--;
}
else if (SUCCEEDED(res)){
/* the non-generic composition was successful so we can make a simplification in this case */
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
This->tabMoniker[This->tabLastIndex-1]=tempMk;
} else
return res;
/* resize tabMoniker if needed */
if (This->tabLastIndex==This->tabSize){
This->tabSize+=BLOCK_TAB_SIZE;
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
}
}
else{
/* add a composite moniker to the moniker table (do the same thing
* for each moniker within the composite moniker as a simple moniker
* (see above for how to add a simple moniker case) )
*/
IMoniker_Enum(pmkRest,TRUE,&enumMoniker);
while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk);
if (res==MK_E_NEEDGENERIC){
This->tabLastIndex++;
}
else if (tempMk==NULL){
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
IMoniker_Release(This->tabMoniker[This->tabLastIndex]);
This->tabLastIndex--;
}
else{
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
This->tabMoniker[This->tabLastIndex-1]=tempMk;
}
if (This->tabLastIndex==This->tabSize){
This->tabSize+=BLOCK_TAB_SIZE;
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
}
}
IEnumMoniker_Release(enumMoniker);
}
return S_OK;
}
/******************************************************************************
* CreateGenericComposite [OLE32.@]
******************************************************************************/
HRESULT WINAPI
CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
LPMONIKER* ppmkComposite)
{
CompositeMonikerImpl* newCompositeMoniker = 0;
HRESULT hr = S_OK;
TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
if (ppmkComposite==NULL)
return E_POINTER;
*ppmkComposite=0;
if (pmkFirst==NULL && pmkRest!=NULL){
*ppmkComposite=pmkRest;
return S_OK;
}
else if (pmkFirst!=NULL && pmkRest==NULL){
*ppmkComposite=pmkFirst;
return S_OK;
}
else if (pmkFirst==NULL && pmkRest==NULL)
return S_OK;
newCompositeMoniker = HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl));
if (newCompositeMoniker == 0)
return STG_E_INSUFFICIENTMEMORY;
hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest);
if (FAILED(hr)){
HeapFree(GetProcessHeap(),0,newCompositeMoniker);
return hr;
}
if (newCompositeMoniker->tabLastIndex==1)
hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite);
else
hr = IMoniker_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite);
return hr;
}
/******************************************************************************
* MonikerCommonPrefixWith [OLE32.@]
******************************************************************************/
HRESULT WINAPI
MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -