|
|
//+----------------------------------------------------------------------------
//
// File:
// multi.cpp
//
// Contents:
// Cache node test which creates multiple nodes, then performs
// various data tests on them.
//
// History:
//
// 04-Sep-94 davepl Created
//
//-----------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
//+----------------------------------------------------------------------------
//
// Member: TestInstance::MultiCache
//
// Synopsis: Caches N unique nodes, where N is large (>100). Saves
// the cache, then reloads it to compare.
//
// Arguments: [dwCount] Number of new nodes to cache
//
// Returns: HRESULT
//
// Notes:
//
// History: 24-Aug-94 Davepl Created
//
//-----------------------------------------------------------------------------
HRESULT TestInstance::MultiCache(DWORD dwCount) { HRESULT hr;
DWORD iCFGEN = 0, iNODES = 0, iSDATA = 0;
TraceLog Log(NULL, "TestInstance::MultiCache", GS_CACHE, VB_MINIMAL); Log.OnEntry (" ( %d )\n", dwCount); Log.OnExit (" ( %X )\n", &hr);
//
// A temporary buffer for creating text clipformat names
//
char szFormatName[ MAX_BUF ];
//
// An array of UINTs to hold our private clipformats, and an
// array of DWORDS to hold the connection IDs
//
CLIPFORMAT *acfArray = (CLIPFORMAT *) malloc(dwCount * sizeof(CLIPFORMAT)); if (NULL == acfArray) { return E_OUTOFMEMORY; }
DWORD *adwConnections = (DWORD *) malloc(dwCount * sizeof(DWORD)); if (NULL == adwConnections) { free(acfArray); return E_OUTOFMEMORY; }
//
// Generate N private clipformats
//
for (iCFGEN=0; iCFGEN < dwCount; iCFGEN++) { sprintf(szFormatName, "LocalFormat%d", iCFGEN);
acfArray[iCFGEN] = (WORD) RegisterClipboardFormat(szFormatName); if (0 == acfArray[iCFGEN]) { free(acfArray); return HRESULT_FROM_WIN32(GetLastError()); } }
//
// Cache N nodes based on those formats
//
FORMATETC fetc = { 0, // Clipformat
NULL, // DVTargetDevice
DVASPECT_CONTENT, // Aspect
-1, // Index
TYMED_HGLOBAL // TYMED
};
STGMEDIUM stgm;
for (iNODES = 0; iNODES < dwCount; iNODES++) { fetc.cfFormat = acfArray[iNODES]; hr = m_pOleCache->Cache(&fetc, ADVF_PRIMEFIRST, &adwConnections[iNODES]);
// We are expecting the cache to return CACHE_S_FORMATETC_NOTSUPPORTED
// for this data, since it cannot draw it.
hr = MassageErrorCode(CACHE_S_FORMATETC_NOTSUPPORTED, hr);
if (S_OK != hr) { break; } }
//
// If all went well adding the nodes, proceed to SetData into
// each of the nodes with some unique data
//
if (S_OK == hr) { for (iSDATA = 0; iSDATA < dwCount; iSDATA++) { HGLOBAL hTmp = GlobalAlloc(GMEM_MOVEABLE, sizeof(DWORD)); if (NULL == hTmp) { break; } DWORD * pdw = (DWORD *) GlobalLock(hTmp); if (NULL == pdw) { GlobalFree(hTmp); break; }
//
// Set the data in the HGLOBAL equal to the clipformat
// for this node
//
*pdw = iSDATA;
GlobalUnlock(hTmp);
stgm.tymed = TYMED_HGLOBAL; stgm.hGlobal = hTmp; fetc.cfFormat = acfArray[iSDATA];
hr = m_pOleCache->SetData(&fetc, &stgm, TRUE /* fRelease */);
if (S_OK != hr) { break; } } }
//
// Save the cache and reload it
//
if (S_OK == hr) { hr = SaveAndReload(); }
//
// Just to make things interesting, let's DiscardCache before we
// start looking for data. This will force the cache to demand-load
// the data as we ask for it. Since we know the cache is not dirty,
// there's no value (practical or from a test perspective) in asking
// the DiscardCache to save along the way.
//
if (S_OK == hr) { hr = m_pOleCache2->DiscardCache(DISCARDCACHE_NOSAVE); }
if (S_OK == hr) { for (iSDATA = 0; iSDATA < dwCount; iSDATA++) { //
// For each of the cache nodes we added, try to
// get the data that was saved in the cache under
// that clipformat
//
fetc.cfFormat = acfArray[iSDATA]; hr = m_pDataObject->GetData(&fetc, &stgm); if (S_OK != hr) { ReleaseStgMedium(&stgm); break; }
//
// Lock the HGLOBAL and compare what is in the cache
// node to what we expect should be there (the index
// into our clipboard format table
//
DWORD * pdw = (DWORD *) GlobalLock(stgm.hGlobal); if (NULL == pdw) { hr = E_OUTOFMEMORY; break; }
if (*pdw != iSDATA) { hr = E_FAIL; GlobalUnlock(stgm.hGlobal); ReleaseStgMedium(&stgm); break; }
GlobalUnlock(stgm.hGlobal); ReleaseStgMedium(&stgm); } }
//
// We want to remove all of the cache nodes we have added.
// Unforunately, there is no easy way to do this; we have to
// enumerate over the cache and toss nodes as we find them, even
// though we _know_ everything about the nodes. Sigh...
//
//
// Get an enumerator on the cache
//
LPENUMSTATDATA pEsd; if (S_OK == hr) { hr = m_pOleCache->EnumCache(&pEsd); }
//
// Since we've got a large number of cache nodes in the cache,
// now is a perfect time to run the generic enumerator tests on
// the cache.
//
if (S_OK == hr) { hr = TestEnumerator((void *) pEsd, sizeof(STATDATA), iSDATA, NULL, NULL,NULL); }
//
// Reset the enumerator before beginning our UnCache loop.
//
if (S_OK == hr) { hr = pEsd->Reset(); }
if (S_OK == hr) { //
// Loop until a failure or until we have removed all of
// the nodes that we thought should exist
//
STATDATA stat;
while (S_OK == hr && iSDATA > 0) { hr = pEsd->Next(1, &stat, NULL);
if (S_OK == hr) { hr = m_pOleCache->Uncache(stat.dwConnection); iSDATA--; } } }
return hr; }
|