Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1481 lines
28 KiB

//+-------------------------------------------------------------------------
//
// 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);
}
}