//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1993. // // File: cliptest.cpp // // Contents: Clipboard Unit tests // // Classes: // // Functions: LEClipTest1 // // History: dd-mmm-yy Author Comment // 23-Mar-94 alexgo author // //-------------------------------------------------------------------------- #include "oletest.h" #include "gendata.h" #include "genenum.h" #include "letest.h" SLETestInfo letiClipTest = { "cntroutl", WM_TEST1 }; // // functions local to this file // void DumpClipboardFormats(FILE *fp); HRESULT LEOle1ClipTest2Callback( void ); HRESULT StressOleFlushClipboard(void); HRESULT StressOleGetClipboard(void); HRESULT StressOleIsCurrentClipboard(void); HRESULT StressOleSetClipboard(void); class CClipEnumeratorTest : public CEnumeratorTest { public: CClipEnumeratorTest( IEnumFORMATETC *penum, LONG clEntries, HRESULT& rhr); BOOL Verify(void *); }; CClipEnumeratorTest::CClipEnumeratorTest( IEnumFORMATETC *penum, LONG clEntries, HRESULT& rhr) : CEnumeratorTest(penum, sizeof(FORMATETC), clEntries, rhr) { // Header does all the work } BOOL CClipEnumeratorTest::Verify(void *) { return TRUE; } //+------------------------------------------------------------------------- // // Function: DumpClipboardFormats // // Synopsis: dumps the formats currently on the clipboard to a file // // Effects: // // Arguments: [fp] -- the file to print the current formats // // Requires: // // Returns: void // // Signals: // // Modifies: // // Algorithm: // // History: dd-mmm-yy Author Comment // 11-Aug-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- void DumpClipboardFormats( FILE *fp ) { char szBuf[256]; UINT cf = 0; fprintf(fp, "==================================================\n\n"); OpenClipboard(NULL); while( (cf = EnumClipboardFormats(cf)) != 0) { GetClipboardFormatName(cf, szBuf, sizeof(szBuf)); fprintf(fp, "%s\n", szBuf); } fprintf(fp, "\n==================================================\n"); CloseClipboard(); return; } //+------------------------------------------------------------------------- // // Function: LEClipTest1 // // Synopsis: runs the clipboard through a series of tests // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: Tests basic OLE32 functionality of the apis: // OleSetClipboard // OleGetClipboard // OleIsCurrentClipboard // OleFlushClipboard // downlevel format and clipboard data object testing is *not* // done by this routine // // History: dd-mmm-yy Author Comment // 23-Mar-94 alexgo author // 22-Jul-94 AlexT Add OleInit/OleUninit call // // Notes: // //-------------------------------------------------------------------------- HRESULT LEClipTest1( void ) { HRESULT hresult = NOERROR; CGenDataObject *pDO; ULONG cRefs; IDataObject * pIDO; pDO = new CGenDataObject; assert(pDO); cRefs = pDO->AddRef(); // if cRefs != 1, then somebody modified this test code; the tests // below will be invalid. assert(cRefs==1); // // Basic Tests // hresult = OleSetClipboard(pDO); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } // the data object should have been AddRef'ed cRefs = pDO->AddRef(); if( cRefs != 3 ) { OutputString("Wrong reference count!! Should be 3, " "was %lu\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO->Release(); // Calling OleInitialize & OleUninitialize should not disturb the // clipboard hresult = OleInitialize(NULL); if (FAILED(hresult)) { OutputString("LEClipTest1: OleInitialize failed - hr = %lx\n", hresult); return ResultFromScode(E_FAIL); } OleUninitialize(); hresult = OleGetClipboard(&pIDO); if( hresult != NOERROR ) { OutputString("OleGetClipboard failed! (%lx)\r\n", hresult); return hresult; } if( pIDO == NULL ) { OutputString("OleGetClipboard returned NULL IDO\r\n"); return ResultFromScode(E_FAIL); } // the reference count on the clipboard data object should have gone up // by one (to be 2). Remember this is not our data object but // the clipboard's. cRefs = pIDO->AddRef(); if( cRefs != 2 ) { OutputString("Wrong ref count!! Should be 2, was %lu\r\n", cRefs); return ResultFromScode(E_FAIL); } // Release the clipboard data object's extra add ref. pIDO->Release(); // Release the clipboard's data object entirely. pIDO->Release(); // the reference count on our data object should be 2 still cRefs = pDO->AddRef(); if( cRefs != 3 ) { OutputString("Wrong ref count!! Should be 3, was %lu\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO->Release(); // now check to see if the we are the current clipboard hresult = OleIsCurrentClipboard( pDO ); if( hresult != NOERROR ) { OutputString("OleIsCurrentClipboard failed! (%lx)\r\n", hresult); return hresult; } // now flush the clipboard, removing the data object hresult = OleFlushClipboard(); if( hresult != NOERROR ) { OutputString("OleFlushClipboard failed! (%lx)\r\n", hresult); return hresult; } // Flush should have released the data object (ref count should // be 1) cRefs = pDO->AddRef(); if( cRefs != 2 ) { OutputString("Wrong ref count!! Should be 2, was %lu\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO->Release(); // take it down to 1 cRefs = pDO->Release(); // should be zero now if(cRefs != 0 ) { OutputString("Wrong ref count on data transfer object! " "Unable to delete\r\n"); return ResultFromScode(E_FAIL); } // if we got this far, basic clipboard tests passed OutputString("Basic Clipboard tests passed\r\n"); // now stress individual API's OutputString("Now stressing clipboard API's\r\n"); if( (hresult = StressOleFlushClipboard()) != NOERROR ) { return hresult; } if( (hresult = StressOleGetClipboard()) != NOERROR ) { return hresult; } if( (hresult = StressOleIsCurrentClipboard()) != NOERROR ) { return hresult; } if( (hresult = StressOleSetClipboard()) != NOERROR ) { return hresult; } OutputString("Clipoard API stress passed!\r\n"); return NOERROR; } //+------------------------------------------------------------------------- // // Function: LEClipTest2 // // Synopsis: Tests the clipboard data object // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: // // History: dd-mmm-yy Author Comment // 15-Apr-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT LEClipTest2( void ) { CGenDataObject * pGenData; IDataObject * pDataObj; HRESULT hresult; IEnumFORMATETC * penum; FORMATETC formatetc; STGMEDIUM medium; ULONG cRefs; pGenData = new CGenDataObject(); assert(pGenData); cRefs = pGenData->AddRef(); // ref count should be 1 assert(cRefs == 1); hresult = OleSetClipboard(pGenData); if( hresult != NOERROR ) { OutputString("Clip2: OleSetClipboard failed! (%lx)\r\n", hresult); goto errRtn2; } hresult = OleFlushClipboard(); if( hresult != NOERROR ) { OutputString("Clip2: OleFlushClipboard failed! (%lx)\r\n", hresult); goto errRtn2; } // get the fake clipboard data object hresult = OleGetClipboard(&pDataObj); if( hresult != NOERROR ) { OutputString("Clip2: OleGetClipboard failed! (%lx)\r\n", hresult); goto errRtn2; } hresult = pDataObj->EnumFormatEtc(DATADIR_GET, &penum); if( hresult != NOERROR ) { OutputString("Clip2: EnumFormatEtc failed! (%lx)\r\n", hresult); goto errRtn; } while( penum->Next( 1, &formatetc, NULL ) == NOERROR ) { if( formatetc.cfFormat == pGenData->m_cfTestStorage || formatetc.cfFormat == pGenData->m_cfEmbeddedObject ) { // we should be told IStorage if( !(formatetc.tymed & TYMED_ISTORAGE) ) { hresult = ResultFromScode(E_FAIL); OutputString("medium mismatch, ISTORAGE"); break; } } hresult = pDataObj->GetData(&formatetc, &medium); if( hresult != NOERROR ) { break; } // verify the data if( !pGenData->VerifyFormatAndMedium(&formatetc, &medium) ) { hresult = ResultFromScode(E_FAIL); OutputString("Clip2: retrieved data doesn't match! " "cf == %d\r\n", formatetc.cfFormat); break; } ReleaseStgMedium(&medium); memset(&medium, 0, sizeof(STGMEDIUM)); } { CClipEnumeratorTest cet(penum, -1, hresult); if (hresult == S_OK) { hresult = cet.TestAll(); } } penum->Release(); errRtn: pDataObj->Release(); errRtn2: pGenData->Release(); if( hresult == NOERROR ) { OutputString("Clipboard data object tests Passed!\r\n"); } return hresult; } //+------------------------------------------------------------------------- // // Function: LEOle1ClipTest1 // // Synopsis: Simple tests of OLE1 clipboard compatibility (copy from // and OLE1 server) // // Effects: // // Arguments: // // Requires: // // Returns: // // Signals: // // Modifies: // // Algorithm: Run through 15 combinations of OLE1 support and verify // everything came out OK // // History: dd-mmm-yy Author Comment // 06-Jun-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT LEOle1ClipTest1( void ) { HRESULT hresult; DWORD flags; CGenDataObject * pGenData = NULL; IDataObject * pDataObj = NULL; IEnumFORMATETC * penum = NULL; FORMATETC formatetc; STGMEDIUM medium; // we are going to take advantage of the fact that the interesting // OLE1 bit flags for this test are the bottom 4 bits. pGenData = new CGenDataObject(); assert(pGenData); for( flags = 1; flags < 16; flags++ ) { // test #8 is not interesting (because no ole1 // formats are offered on the clipboard if( (Ole1TestFlags)flags == OLE1_OWNERLINK_PRECEDES_NATIVE ) { continue; } // setup the OLE1 mode desired pGenData->SetupOle1Mode((Ole1TestFlags)flags); hresult = pGenData->SetOle1ToClipboard(); if( hresult != NOERROR ) { goto errRtn; } // log the formats that are currently on the clipboard DumpClipboardFormats(vApp.m_fpLog); // get the fake clipboard data object hresult = OleGetClipboard(&pDataObj); if( hresult != NOERROR ) { OutputString("Ole1Clip1: OleGetClipboard failed! " "(%lx)\r\n", hresult); goto errRtn; } hresult = pDataObj->EnumFormatEtc(DATADIR_GET, &penum); if( hresult != NOERROR ) { OutputString("Ole1Clip1: EnumFormatEtc failed! " "(%lx)\r\n", hresult); goto errRtn; } while( penum->Next( 1, &formatetc, NULL ) == NOERROR ) { DumpFormatetc(&formatetc, vApp.m_fpLog); #ifdef WIN32 hresult = pDataObj->GetData(&formatetc, &medium); if( hresult != NOERROR ) { goto errRtn; } // verify the data if( !pGenData->VerifyFormatAndMedium(&formatetc, &medium) ) { hresult = ResultFromScode(E_FAIL); OutputString("Ole1Clip1: retrieved data " "doesn't match! cf == %d\r\n", formatetc.cfFormat); goto errRtn; } ReleaseStgMedium(&medium); memset(&medium, 0, sizeof(STGMEDIUM)); #endif // WIN32 } // now release everything penum->Release(); penum = NULL; pDataObj->Release(); pDataObj = NULL; } errRtn: if( penum ) { penum->Release(); } if( pDataObj ) { pDataObj->Release(); } if( pGenData ) { pGenData->Release(); } return hresult; } //+------------------------------------------------------------------------- // // Function: LEOle1ClipTest2 // // Synopsis: Tests OLE1 container support via the clipboard // // Effects: // // Arguments: // // Requires: // // Returns: // // Signals: // // Modifies: // // Algorithm: Start cntroutl, tell it to copy a simpsvr object to the // clipboard. Check the clipboard to make sure OLE1 formats // are available. // // We do this by sheduling a function to check the clipboard // after we've launched the standard copy-to-clipboard // routines. // // History: dd-mmm-yy Author Comment // 16-Jun-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- void LEOle1ClipTest2( void *pv ) { // this will get triggered by the return of WM_TEST1 from // container outline vApp.m_TaskStack.Push(RunApi, (void *)LEOle1ClipTest2Callback); vApp.m_TaskStack.Push(LETest1, (void *)&letiClipTest); // now post a message to ourselves to get things rollling PostMessage(vApp.m_hwndMain, WM_TEST1, 0, 0); return; } //+------------------------------------------------------------------------- // // Function: LEOle1ClipTest2Callback // // Synopsis: checks the clipboard for OLE1 formats // // Effects: // // Arguments: [pv] -- unused // // Requires: // // Returns: // // Signals: // // Modifies: // // Algorithm: // // History: dd-mmm-yy Author Comment // 20-Aug-94 alexgo updated to cfObjectLink test // 16-Jun-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT LEOle1ClipTest2Callback( void ) { HRESULT hresult; IDataObject * pDO; IEnumFORMATETC *penum; FORMATETC formatetc; BOOL fGotNative = FALSE, fGotOwnerLink = FALSE, fGotObjectLink = FALSE; UINT cfNative, cfOwnerLink, cfObjectLink; cfNative = RegisterClipboardFormat("Native"); cfOwnerLink = RegisterClipboardFormat("OwnerLink"); cfObjectLink = RegisterClipboardFormat("ObjectLink"); assert(vApp.m_message == WM_TEST1); hresult = (HRESULT)vApp.m_wparam; if( hresult != NOERROR ) { return hresult; } // we need to wait for cntroutl to shut down before // fetching the clipboard while( (hresult = OleGetClipboard(&pDO)) != NOERROR ) { if( hresult != ResultFromScode(CLIPBRD_E_CANT_OPEN) ) { return hresult; } } hresult = pDO->EnumFormatEtc(DATADIR_GET, &penum); if( hresult != NOERROR ) { return hresult; } while( penum->Next(1, &formatetc, NULL) == NOERROR ) { if( formatetc.cfFormat == cfNative ) { fGotNative = TRUE; } else if( formatetc.cfFormat == cfOwnerLink ) { fGotOwnerLink = TRUE; } else if( formatetc.cfFormat == cfObjectLink ) { fGotObjectLink = TRUE; } } penum->Release(); pDO->Release(); // the OLE1 container compatibility code should put // OLE1 formats on the clipboard. However, they should NOT // be in the enumerator since the stuff was copied from // an OLE2 container. if( (fGotNative || fGotOwnerLink || fGotObjectLink) ) { hresult = ResultFromScode(E_FAIL); return hresult; } if( IsClipboardFormatAvailable(cfNative) ) { fGotNative = TRUE; } if( IsClipboardFormatAvailable(cfOwnerLink) ) { fGotOwnerLink = TRUE; } if( IsClipboardFormatAvailable(cfObjectLink) ) { fGotObjectLink = TRUE; } // NB!! only Native and OwnerLink should be on the clipboard // this test puts an OLE2 *embedding* on the clipbaord, which // an OLE1 container cannot link to. So ObjectLink should not // be available if( !(fGotNative && fGotOwnerLink && !fGotObjectLink) ) { hresult = ResultFromScode(E_FAIL); } return hresult; } //+------------------------------------------------------------------------- // // Function: StressOleFlushClipboard // // Synopsis: // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: stresses the following cases: // 1. Caller is not the clipboard owner (somebody else put // data on the clipboard) // 2. somebody else has the clipboard open // 3. OleFlushClipboard is called twice (second attempt should // not fail). // // History: dd-mmm-yy Author Comment // 28-Mar-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT StressOleFlushClipboard(void) { HRESULT hresult; CGenDataObject *pDO; ULONG cRefs; OutputString("Now stressing OleFlushClipboard() \r\n"); pDO = new CGenDataObject(); assert(pDO); pDO->AddRef(); //initial count of 1 //take ownership of the clipboard if( !OpenClipboard(vApp.m_hwndMain) ) { OutputString("Can't OpenClipboard! \r\n"); return ResultFromScode(CLIPBRD_E_CANT_OPEN); } if( !EmptyClipboard() ) { OutputString("Can't EmptyClipboard! \r\n"); return ResultFromScode(CLIPBRD_E_CANT_EMPTY); } if( !CloseClipboard() ) { OutputString("Can't CloseClipboard! \r\n"); return ResultFromScode(CLIPBRD_E_CANT_CLOSE); } // now to flush the clipboard; we should get E_FAIL hresult = OleFlushClipboard(); if( hresult != ResultFromScode(E_FAIL) ) { OutputString("Unexpected hresult:(%lx)\r\n", hresult); return (hresult) ? hresult : ResultFromScode(E_UNEXPECTED); } // now put something on the clipboard so we can flush it hresult = OleSetClipboard(pDO); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } // open the clipboard with us if( !OpenClipboard(vApp.m_hwndMain) ) { OutputString("Can't OpenClipboard!\r\n"); return ResultFromScode(CLIPBRD_E_CANT_OPEN); } // OleFlushClipboard should return with CLIPBRD_E_CANT_OPEN // since another window has the clipboard open hresult = OleFlushClipboard(); if( hresult != ResultFromScode(CLIPBRD_E_CANT_OPEN) ) { OutputString("Unexpected hresult:(%lx)\r\n", hresult); return (hresult)? hresult :ResultFromScode(E_UNEXPECTED); } cRefs = pDO->AddRef(); // cRefs should be 3 (one from beginning, one from OleSetClipboard // and 1 from above. OleFlushClipboard should *not* remove the // count for the above failure case) if( cRefs != 3 ) { OutputString("Bad ref count, was %lu, should be 3\r\n", cRefs); return ResultFromScode(E_FAIL); } // undo the most recent addref above pDO->Release(); // close the clipboard if( !CloseClipboard() ) { OutputString("Can't CloseClipboard!\r\n"); return ResultFromScode(CLIPBRD_E_CANT_CLOSE); } // now call OleFlushClipboard for real hresult = OleFlushClipboard(); if( hresult != NOERROR ) { OutputString("OleFlushClipboard failed! (%lx)\r\n", hresult); return hresult; } // now call it once more hresult = OleFlushClipboard(); if( hresult != NOERROR ) { OutputString("Second call to OleFlushClipboard should not" "have failed! (%lx)\r\n", hresult); return hresult; } // there should have only been 1 release from the first // OleFlushClipboard call. This next release should nuke the object cRefs = pDO->Release(); if( cRefs != 0 ) { OutputString("Bad ref count, was %lu, should be 0\r\n", cRefs); return ResultFromScode(E_FAIL); } return NOERROR; } //+------------------------------------------------------------------------- // // Function: StressOleGetClipboard // // Synopsis: // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: tests the following cases: // 1. somebody else has the clipboard open // // History: dd-mmm-yy Author Comment // 28-Mar-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT StressOleGetClipboard(void) { HRESULT hresult; IDataObject * pIDO; CGenDataObject *pDO; ULONG cRefs; OutputString("Stressing OleGetClipboard()\r\n"); pDO = new CGenDataObject(); assert(pDO); pDO->AddRef(); hresult = OleSetClipboard(pDO); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } if( !OpenClipboard(vApp.m_hwndMain) ) { OutputString("Can't OpenClipboard!\r\n"); return ResultFromScode(CLIPBRD_E_CANT_OPEN); } hresult = OleGetClipboard(&pIDO); if( hresult != ResultFromScode(CLIPBRD_E_CANT_OPEN) ) { OutputString("Unexpected hresult (%lx)\r\n", hresult); return (hresult) ? hresult : ResultFromScode(E_UNEXPECTED); } // the ref count should not have gone up cRefs = pDO->AddRef(); if( cRefs != 3 ) { OutputString("Bad ref count, was %lu, should be 3\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO->Release(); // now clear stuff out and go home if( !CloseClipboard() ) { OutputString("CloseClipboard failed!\r\n"); return ResultFromScode(E_FAIL); } // this should clear the clipboard hresult = OleSetClipboard(NULL); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } // this should be the final release on the object cRefs = pDO->Release(); if( cRefs != 0 ) { OutputString("Bad ref count, was %lu, should be 0\r\n", cRefs); return ResultFromScode(E_FAIL); } return NOERROR; } //+------------------------------------------------------------------------- // // Function: StressOleIsCurrentClipboard // // Synopsis: // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: tests the following cases // 1. the caller is not the clipboard owner // 2. somebody else has the clipboard open // 2. the data object is NULL // 3. the data object is not the data object put on the clipboard // // History: dd-mmm-yy Author Comment // 28-Mar-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT StressOleIsCurrentClipboard(void) { HRESULT hresult; CGenDataObject *pDO, *pDO2; ULONG cRefs; OutputString("Stressing OleIsCurrentClipboard()\r\n"); pDO = new CGenDataObject(); pDO2 = new CGenDataObject(); assert(pDO); assert(pDO2); pDO->AddRef(); pDO2->AddRef(); //take ownership of the clipboard if( !OpenClipboard(vApp.m_hwndMain) ) { OutputString("Can't OpenClipboard! \r\n"); return ResultFromScode(CLIPBRD_E_CANT_OPEN); } if( !EmptyClipboard() ) { OutputString("Can't EmptyClipboard! \r\n"); return ResultFromScode(CLIPBRD_E_CANT_EMPTY); } if( !CloseClipboard() ) { OutputString("Can't CloseClipboard! \r\n"); return ResultFromScode(CLIPBRD_E_CANT_CLOSE); } // now to flush the clipboard; we should get S_FALSE hresult = OleIsCurrentClipboard(pDO); if( hresult != ResultFromScode(S_FALSE) ) { OutputString("Unexpected hresult:(%lx)\r\n", hresult); return (hresult) ? hresult : ResultFromScode(E_UNEXPECTED); } // now set the clipboard and test w/ the clipboard open // we should not fail in this case hresult = OleSetClipboard(pDO); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } if( !OpenClipboard(vApp.m_hwndMain) ) { OutputString("Can't OpenClipboard!\r\n"); return ResultFromScode(CLIPBRD_E_CANT_OPEN); } hresult = OleIsCurrentClipboard(pDO); if( hresult != NOERROR ) { OutputString("Unexpected hresult (%lx)\r\n", hresult); return (hresult) ? hresult : ResultFromScode(E_UNEXPECTED); } // the ref count should not have gone up cRefs = pDO->AddRef(); if( cRefs != 3 ) { OutputString("Bad ref count, was %lu, should be 3\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO->Release(); // now close the clipboard if( !CloseClipboard() ) { OutputString("CloseClipboard failed!\r\n"); return ResultFromScode(E_FAIL); } // now test for passing NULL hresult = OleIsCurrentClipboard(NULL); if( hresult != ResultFromScode(S_FALSE) ) { OutputString("Unexpected hresult (%lx)\r\n", hresult); return (hresult)? hresult : ResultFromScode(E_FAIL); } // now test for passign other pointer hresult = OleIsCurrentClipboard(pDO2); if( hresult != ResultFromScode(S_FALSE) ) { OutputString("Unexpected hresult (%lx)\r\n", hresult); return (hresult)? hresult : ResultFromScode(E_FAIL); } // now clean stuff up and go home hresult = OleSetClipboard(NULL); if( hresult != NOERROR ) { OutputString("OleSetClipboard(NULL) failed!! (%lx)\r\n", hresult); return hresult; } cRefs = pDO->Release(); // cRefs should be 0 now if( cRefs != 0 ) { OutputString("Bad ref count, was %lu, should be 0\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO2->Release(); return NOERROR; } //+------------------------------------------------------------------------- // // Function: StressOleSetClipboard // // Synopsis: // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: tests the following cases: // 1. somebody else has the clipboard open // 2. Do OleSetClipboard with data and then // OleSetClipboard(NULL) to clear it out // // History: dd-mmm-yy Author Comment // 28-Mar-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT StressOleSetClipboard(void) { HRESULT hresult; CGenDataObject *pDO; ULONG cRefs; OutputString("Stressing OleGetClipboard()\r\n"); pDO = new CGenDataObject(); assert(pDO); pDO->AddRef(); if( !OpenClipboard(vApp.m_hwndMain) ) { OutputString("Can't OpenClipboard!\r\n"); return ResultFromScode(CLIPBRD_E_CANT_OPEN); } hresult = OleSetClipboard(pDO); if( hresult != ResultFromScode(CLIPBRD_E_CANT_OPEN) ) { OutputString("Unexpected hresult (%lx)\r\n", hresult); return (hresult) ? hresult : ResultFromScode(E_UNEXPECTED); } // the ref count should not have gone up cRefs = pDO->AddRef(); if( cRefs != 2 ) { OutputString("Bad ref count, was %lu, should be 2\r\n", cRefs); return ResultFromScode(E_FAIL); } pDO->Release(); if( !CloseClipboard() ) { OutputString("CloseClipboard failed!\r\n"); return ResultFromScode(E_FAIL); } // now really set the clipboard so we can try to clear it hresult = OleSetClipboard(pDO); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } // this should clear the clipboard hresult = OleSetClipboard(NULL); if( hresult != NOERROR ) { OutputString("OleSetClipboard failed! (%lx)\r\n", hresult); return hresult; } // this should be the final release on the object cRefs = pDO->Release(); if( cRefs != 0 ) { OutputString("Bad ref count, was %lu, should be 0\r\n", cRefs); return ResultFromScode(E_FAIL); } return NOERROR; } //+------------------------------------------------------------------------- // // Function: TestOleQueryCreateFromDataMFCHack // // Synopsis: tests the MFC hack put into OleQueryCreateFromData // // Effects: // // Arguments: void // // Requires: // // Returns: HRESULT // // Signals: // // Modifies: // // Algorithm: create a data object that offers private data // put on the clipboard and then retrieve the clipboard data // object. // Call OleQueryCreateFromData on clipboard data object-- // QI for IPS should not be called // Call OleQueryCreateFromData on generic data object // QI for IPS should be called // set EmbeddedObject on the generic data object // Call OleQueryCreateFromData; should return S_OK // // History: dd-mmm-yy Author Comment // 23-Aug-94 alexgo author // // Notes: // //-------------------------------------------------------------------------- HRESULT TestOleQueryCreateFromDataMFCHack( void ) { CGenDataObject * pgendata; IDataObject * pdataobj; HRESULT hresult; pgendata = new CGenDataObject(); assert(pgendata); pgendata->AddRef(); pgendata->SetDataFormats(OFFER_TESTSTORAGE); hresult = OleSetClipboard(pgendata); if( hresult != NOERROR ) { return hresult; } hresult = OleGetClipboard(&pdataobj); if( hresult != NOERROR ) { return hresult; } hresult = OleQueryCreateFromData(pdataobj); // for a clipboard data object, we should not call QueryInterface // for IPersistStorage. if( hresult != S_FALSE || pgendata->HasQIBeenCalled() == TRUE ) { return ResultFromScode(E_FAIL); } // for other data objects, if there are no OLE2 formats, then // we should call QI for IPersistStorage hresult = OleQueryCreateFromData(pgendata); if( hresult != S_FALSE || pgendata->HasQIBeenCalled() == FALSE ) { return ResultFromScode(E_FAIL); } // now clear the clipboard and continue testing pdataobj->Release(); hresult = OleSetClipboard(NULL); if( hresult != NOERROR ) { return hresult; } pgendata->SetDataFormats(OFFER_EMBEDDEDOBJECT); hresult = OleQueryCreateFromData(pgendata); // we just set OLE2 data on the data object. OQCFD should return // S_OK if( hresult != NOERROR ) { return ResultFromScode(E_FAIL); } if( pgendata->Release() == 0 ) { return NOERROR; } else { return ResultFromScode(E_FAIL); } }