Listing 3 Implemenation of ListExchange_PutItems_Base()
/* ///////////////////////////////////////////////////////////// * ... * * 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) * * ... * ////////////////////////////////////////////////////////// */ SInt32 ListExchange_PutItems_Base( HWND hwndList, LPUNKNOWN punkEnumItems, UInt32 flags, UInt32 param, EnumeratorHandler const *enumerators, UInt32 cEnumerators, ControlHandler const *controls, UInt32 cControls) { HRESULT hr; _ASSERTE(IsWindow(hwndList)); if( !(flags & SYLXF_RESETCONTENT) && ( NULL == punkEnumItems || NULL == enumerators || 0 == cEnumerators)) { hr = E_INVALIDARG; } else if(!IsWindow(hwndList) || 0 == cControls || NULL == controls) { hr = E_INVALIDARG; } else { LPUNKNOWN punkEnum = NULL; UInt32 i; /* Find the window class */ for(hr = E_FAIL, i = 0; FAILED(hr) && i < cControls; ++i) { if(IsWindowClass(hwndList, controls[i].className)) { hr = S_OK; break; } } if(FAILED(hr)) { ErrorInfo_SetDescW(L"Window not of recognised class"); hr = E_INVALIDARG; } else { ControlHandler const *control = &controls[i]; if(NULL == punkEnumItems) { /* Only want to clear the window */ _ASSERTE((flags & SYLXF_RESETCONTENT) == SYLXF_RESETCONTENT); control->pfnReset(hwndList); } else { /* Find the interface */ for(hr = E_NOINTERFACE, i = 0; i < cEnumerators; ++i) { #ifdef __cplusplus hr = punkEnumItems->QueryInterface( #else hr = punkEnumItems->lpVtbl->QueryInterface( punkEnumItems, #endif /* __cplusplus */ enumerators[i].iid, (LPPVoid)(&punkEnum)); if(SUCCEEDED(hr)) { break; } } if(FAILED(hr)) { ErrorInfo_SetDescW(L"Enumerator not of recognised type"); hr = E_INVALIDARG; } else { EnumeratorHandler const *enumerator = &enumerators[i]; /* Erase the existing content */ if((flags & SYLXF_RESETCONTENT) == SYLXF_RESETCONTENT) { control->pfnReset(hwndList); } /* Now enumerate over the sequence, inserting as we go. */ for(hr = S_OK, enumerator->pfnReset(punkEnum); SUCCEEDED(hr); ) { Enum2WndItem item; LPVOID value; hr = enumerator->pfnNextItem(punkEnum, &item, &value); if(hr == S_OK) { /* Add to the control ... */ hr = control->pfnPutItem(hwndList, value, flags); /* ... and release any resources from enumerator */ enumerator->pfnClearItem(punkEnum, &item, value); } else if(hr == S_FALSE) { hr = S_OK; break; } } #ifdef __cplusplus punkEnum->Release(); #else punkEnum->lpVtbl->Release(punkEnum); #endif /* __cplusplus */ } } } } return hr; }