📄 compositemoniker.c
字号:
if (pmkToLeft)
{
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
if (FAILED(res)) return res;
}
else
leftMk = iface;
IMoniker_Enum(iface, FALSE, &enumMoniker);
IEnumMoniker_Next(enumMoniker, 1, &mostRigthMk, NULL);
IEnumMoniker_Release(enumMoniker);
res = CreateAntiMoniker(&antiMk);
if (FAILED(res)) return res;
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
if (FAILED(res)) return res;
IMoniker_Release(antiMk);
res = IMoniker_BindToStorage(mostRigthMk, pbc, tempMk, riid, ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (pmkToLeft)
IMoniker_Release(leftMk);
return res;
}
/******************************************************************************
* CompositeMoniker_Reduce
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
/* This method recursively calls Reduce for each of its component monikers. */
if (ppmkToLeft==NULL){
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
return IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
}
else if (*ppmkToLeft==NULL)
return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);
else{
/* separate the composite moniker in to left and right moniker */
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
/* If any of the components reduces itself, the method returns S_OK and passes back a composite */
/* of the reduced components */
if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) &&
IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
)
return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced);
else{
/* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
IMoniker_AddRef(iface);
*ppmkReduced=iface;
return MK_S_REDUCED_TO_SELF;
}
}
}
/******************************************************************************
* CompositeMoniker_ComposeWith
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{
TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
if ((ppmkComposite==NULL)||(pmkRight==NULL))
return E_POINTER;
*ppmkComposite=0;
/* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
/* otherwise, the method returns the result of combining the two monikers by calling the */
/* CreateGenericComposite function */
if (fOnlyIfNotGeneric)
return MK_E_NEEDGENERIC;
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}
/******************************************************************************
* CompositeMoniker_Enum
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
if (ppenumMoniker == NULL)
return E_POINTER;
return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker);
}
/******************************************************************************
* CompositeMoniker_IsEqual
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
IEnumMoniker *enumMoniker1,*enumMoniker2;
IMoniker *tempMk1,*tempMk2;
HRESULT res1,res2,res;
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
if (pmkOtherMoniker==NULL)
return S_FALSE;
/* This method returns S_OK if the components of both monikers are equal when compared in the */
/* left-to-right order.*/
IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1);
if (enumMoniker1==NULL)
return S_FALSE;
IMoniker_Enum(iface,TRUE,&enumMoniker2);
while(1){
res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
if((res1==S_OK)&&(res2==S_OK)){
if(IMoniker_IsEqual(tempMk1,tempMk2)==S_FALSE){
res= S_FALSE;
break;
}
else
continue;
}
else if ( (res1==S_FALSE) && (res2==S_FALSE) ){
res = S_OK;
break;
}
else{
res = S_FALSE;
break;
}
if (res1==S_OK)
IMoniker_Release(tempMk1);
if (res2==S_OK)
IMoniker_Release(tempMk2);
}
IEnumMoniker_Release(enumMoniker1);
IEnumMoniker_Release(enumMoniker2);
return res;
}
/******************************************************************************
* CompositeMoniker_Hash
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
IEnumMoniker *enumMoniker;
IMoniker *tempMk;
HRESULT res;
DWORD tempHash;
TRACE("(%p,%p)\n",iface,pdwHash);
if (pdwHash==NULL)
return E_POINTER;
res = IMoniker_Enum(iface,TRUE,&enumMoniker);
if(FAILED(res))
return res;
*pdwHash = 0;
while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
res = IMoniker_Hash(tempMk, &tempHash);
if(FAILED(res))
break;
*pdwHash = *pdwHash ^ tempHash;
IMoniker_Release(tempMk);
}
IEnumMoniker_Release(enumMoniker);
return res;
}
/******************************************************************************
* CompositeMoniker_IsRunning
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
{
IRunningObjectTable* rot;
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
/* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
if (pmkToLeft!=NULL){
CreateGenericComposite(pmkToLeft,iface,&tempMk);
res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning);
IMoniker_Release(tempMk);
return res;
}
else
/* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
/* to this moniker */
if (pmkNewlyRunning!=NULL)
if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK)
return S_OK;
else
return S_FALSE;
else{
if (pbc==NULL)
return E_POINTER;
/* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
/* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */
/* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
/* the composite as the pmkToLeft parameter for that call. */
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
if (FAILED(res))
return res;
res = IRunningObjectTable_IsRunning(rot,iface);
IRunningObjectTable_Release(rot);
if(res==S_OK)
return S_OK;
else{
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=IMoniker_IsRunning(mostRigthMk,pbc,tempMk,pmkNewlyRunning);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
return res;
}
}
}
/******************************************************************************
* CompositeMoniker_GetTimeOfLastChange
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, FILETIME* pCompositeTime)
{
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
if (pCompositeTime==NULL)
return E_INVALIDARG;
/* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */
/* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
/* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
/* of the composite as the pmkToLeft parameter for that call. */
if (pmkToLeft)
{
IRunningObjectTable* rot;
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
res = IBindCtx_GetRunningObjectTable(pbc,&rot);
if (FAILED(res))
{
IMoniker_Release(leftMk);
return res;
}
if (IRunningObjectTable_GetTimeOfLastChange(rot,leftMk,pCompositeTime)==S_OK)
{
IMoniker_Release(leftMk);
return res;
}
}
else
leftMk = iface;
IMoniker_Enum(iface, FALSE, &enumMoniker);
IEnumMoniker_Next(enumMoniker, 1, &mostRigthMk, NULL);
IEnumMoniker_Release(enumMoniker);
res = CreateAntiMoniker(&antiMk);
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
IMoniker_Release(antiMk);
res = IMoniker_GetTimeOfLastChange(mostRigthMk, pbc, tempMk, pCompositeTime);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (pmkToLeft)
IMoniker_Release(leftMk);
return res;
}
/******************************************************************************
* CompositeMoniker_Inverse
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk,*tempInvMk,*mostRigthInvMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p)\n",iface,ppmk);
if (ppmk==NULL)
return E_POINTER;
/* This method returns a composite moniker that consists of the inverses of each of the components */
/* of the original composite, stored in reverse order */
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
if (tempMk==NULL)
return IMoniker_Inverse(iface,ppmk);
else{
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
IMoniker_Inverse(mostRigthMk,&mostRigthInvMk);
CompositeMonikerImpl_Inverse(tempMk,&tempInvMk);
res=CreateGenericComposite(mostRigthInvMk,tempInvMk,ppmk);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -