Listing 4
// Listing 4: Implementation of enumerator handlers /* ///////////////////////////////////////////////////////////// * ... * * Extract from MOCtlFns.c * * Copyright (C) 1998-2003, Synesis Software Pty Ltd. * (Licensed under the Synesis Software Standard Public License: * http://www.synesis.com.au/licenses/ssspl.html) * * ... * ////////////////////////////////////////////////////////// */ /* IEnumXXXX */ HRESULT EnumXXXX_Reset(LPVOID itf) { LPENUMSTRING pen = (LPENUMSTRING)itf; return pen->lpVtbl->Reset(pen); } /* IEnumString */ HRESULT EnumString_NextItem(LPVOID itf, LPEnum2WndItem pitem, LPVOID *pvalue) { LPENUMSTRING pen = (LPENUMSTRING)itf; HRESULT hr = pen->lpVtbl->Next(pen, 1, &pitem->olestr, NULL); if(hr == S_OK) { *pvalue = pitem->olestr; } return hr; } void EnumString_ClearItem(LPVOID pen, LPEnum2WndItem pitem, LPVOID value) { CoTaskMemFree(pitem->olestr); } /* IEnumBSTR */ HRESULT EnumBSTR_NextItem(LPVOID itf, LPEnum2WndItem pitem, LPVOID *pvalue) { LPENUMBSTR pen = (LPENUMBSTR)itf; HRESULT hr = pen->lpVtbl->Next(pen, 1, &pitem->bstr, NULL); if(hr == S_OK) { *pvalue = pitem->bstr; } return hr; } void EnumBSTR_ClearItem(LPVOID pen, LPEnum2WndItem pitem, LPVOID value) { SysFreeString(pitem->bstr); } /* IEnumVARIANT */ HRESULT EnumVARIANT_NextItem(LPVOID itf, LPEnum2WndItem pitem, LPVOID *pvalue) { LPENUMVARIANT pen = (LPENUMVARIANT)itf; HRESULT hr = pen->lpVtbl->Next(pen, 1, &pitem->var, NULL); if(hr == S_OK) { hr = VariantChangeType(&pitem->var, &pitem->var, VARIANT_ALPHABOOL, VT_BSTR); if(SUCCEEDED(hr)) { *pvalue = pitem->var.bstrVal; } else { VariantClear(&pitem->var); } } return hr; } void EnumVARIANT_ClearItem(LPVOID pen, LPEnum2WndItem pitem, LPVOID value) { VariantClear(&pitem->var); } /* IEnumGUID */ HRESULT EnumGUID_NextItem(LPVOID itf, LPEnum2WndItem pitem, LPVOID *pvalue) { LPENUMGUID pen = (LPENUMGUID)itf; HRESULT hr = pen->lpVtbl->Next(pen, 1, &pitem->guid, NULL); if(hr == S_OK) { hr = StringFromCLSID(&pitem->guid, SyCastRaw(LPOLESTR*, pvalue)); } return hr; } void EnumGUID_ClearItem(LPVOID pen, LPEnum2WndItem pitem, LPVOID value) { OleString_Destroy(SyCastRaw(LPOLESTR*, &value)); } /* IEnumUnknown */ HRESULT EnumUnknown_NextItem(LPVOID itf, LPEnum2WndItem pitem, LPVOID *pvalue) { LPENUMUNKNOWN pen = (LPENUMUNKNOWN)itf; HRESULT hr = pen->lpVtbl->Next(pen, 1, &pitem->punk, NULL); if(hr == S_OK) { /* Use the VariantChangeType() mechanism to get the value property of * the object. */ VARIANT dest; VariantInit(&dest); hr = Dispatch_GetProperty(pitem->punk, DISPID_VALUE, &dest); if(SUCCEEDED(hr)) { hr = VariantChangeType(&dest, &dest, VARIANT_ALPHABOOL, VT_BSTR); if(SUCCEEDED(hr)) { *pvalue = OleString_Dup(dest.bstrVal); } VariantClear(&dest); } if(NULL != pitem->punk) { pitem->punk->lpVtbl->Release(pitem->punk); } } return hr; } void EnumUnknown_ClearItem(LPVOID pen, LPEnum2WndItem pitem, LPVOID value) { OleString_Destroy(SyCastRaw(LPOLESTR*, &value)); }