📄 compositemoniker.c
字号:
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 = 1;
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_GetComparisonData
};
static const IMarshalVtbl VT_MarshalImpl =
{
CompositeMonikerMarshalImpl_QueryInterface,
CompositeMonikerMarshalImpl_AddRef,
CompositeMonikerMarshalImpl_Release,
CompositeMonikerMarshalImpl_GetUnmarshalClass,
CompositeMonikerMarshalImpl_GetMarshalSizeMax,
CompositeMonikerMarshalImpl_MarshalInterface,
CompositeMonikerMarshalImpl_UnmarshalInterface,
CompositeMonikerMarshalImpl_ReleaseMarshalData,
CompositeMonikerMarshalImpl_DisconnectObject
};
/******************************************************************************
* Composite-Moniker_Construct (local function)
*******************************************************************************/
static HRESULT
CompositeMonikerImpl_Construct(IMoniker** ppMoniker,
LPMONIKER pmkFirst, LPMONIKER pmkRest)
{
DWORD mkSys;
IEnumMoniker *enumMoniker;
IMoniker *tempMk;
HRESULT res;
CompositeMonikerImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This)
return E_OUTOFMEMORY;
TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
/* Initialize the virtual function table. */
This->lpvtbl1 = &VT_CompositeMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->lpvtblMarshal= &VT_MarshalImpl;
This->ref = 1;
This->tabSize=BLOCK_TAB_SIZE;
This->tabLastIndex=0;
This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
if (!pmkFirst && !pmkRest)
{
*ppMoniker = (IMoniker *)This;
return S_OK;
}
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);
}
/* only one moniker, then just return it */
if (This->tabLastIndex == 1)
{
*ppMoniker = This->tabMoniker[0];
IMoniker_AddRef(*ppMoniker);
IMoniker_Release((IMoniker *)This);
}
else
*ppMoniker = (IMoniker *)This;
return S_OK;
}
/******************************************************************************
* CreateGenericComposite [OLE32.@]
******************************************************************************/
HRESULT WINAPI
CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
LPMONIKER* ppmkComposite)
{
IMoniker* moniker = 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;
hr = CompositeMonikerImpl_Construct(&moniker,pmkFirst,pmkRest);
if (FAILED(hr))
return hr;
hr = IMoniker_QueryInterface(moniker,&IID_IMoniker,(void**)ppmkComposite);
IMoniker_Release(moniker);
return hr;
}
/******************************************************************************
* MonikerCommonPrefixWith [OLE32.@]
******************************************************************************/
HRESULT WINAPI
MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
}
static HRESULT WINAPI CompositeMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI CompositeMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI CompositeMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI CompositeMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IMoniker* pMoniker;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CompositeMonikerImpl_Construct(&pMoniker, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
IMoniker_Release(pMoniker);
}
return hr;
}
static HRESULT WINAPI CompositeMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl CompositeMonikerCFVtbl =
{
CompositeMonikerCF_QueryInterface,
CompositeMonikerCF_AddRef,
CompositeMonikerCF_Release,
CompositeMonikerCF_CreateInstance,
CompositeMonikerCF_LockServer
};
static const IClassFactoryVtbl *CompositeMonikerCF = &CompositeMonikerCFVtbl;
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&CompositeMonikerCF, riid, ppv);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -