--- /dev/null 2014-04-18 17:39:43.000000000 +0400 +++ new/test/java/awt/dnd/Win32TYMEDSelectionTest/child.cpp 2014-04-18 17:39:42.898004200 +0400 @@ -0,0 +1,315 @@ +#define STRICT +#include +#include +#include + +/* + * NOTE: These constants are duplicated in Win32TYMEDSelectionTest.java. + * Be sure to keep them is sync. + */ +static const int CODE_OK = 0; +static const int CODE_INVALID_TYMED_FAILURE = 1; +static const int CODE_INVALID_DATA_FAILURE = 2; +static const int CODE_OTHER_FAILURE = 3; +static const char* TEST_TEXT = "TEST TEXT"; +static const int X = 300; +static const int Y = 300; +static const int WIDTH = 100; +static const int HEIGHT = 100; + +static const char szClassName[] = "test window"; + +class TestDropTarget : virtual public IDropTarget { + public: + TestDropTarget(); + virtual ~TestDropTarget(); + + virtual HRESULT __stdcall QueryInterface(REFIID riid, + void __RPC_FAR*__RPC_FAR *ppvObject); + virtual ULONG __stdcall AddRef(void); + virtual ULONG __stdcall Release(void); + virtual HRESULT __stdcall DragEnter(IDataObject __RPC_FAR *pDataObject, + DWORD grfKeyState, POINTL pt, + DWORD __RPC_FAR *pdwEffect); + virtual HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, + DWORD __RPC_FAR *pdwEffect); + virtual HRESULT __stdcall DragLeave(void); + virtual HRESULT __stdcall Drop(IDataObject __RPC_FAR *pDataObject, + DWORD grfKeyState, POINTL pt, + DWORD __RPC_FAR *pdwEffect); + virtual int CheckTransferTymed(IDataObject __RPC_FAR *pDataObj, + DWORD tymed); + virtual void DumpTestResult(DWORD tymed, int nTestResult); + private: + unsigned int m_refs; +}; + +TestDropTarget::TestDropTarget() { + m_refs = 0U; + AddRef(); +} + +TestDropTarget::~TestDropTarget() {} + +HRESULT __stdcall +TestDropTarget::QueryInterface(REFIID riid, + void __RPC_FAR *__RPC_FAR *ppvObject) { + if (riid == IID_IUnknown) { + *ppvObject = (void __RPC_FAR *__RPC_FAR)(IUnknown*)this; + AddRef(); + return S_OK; + } else if (riid == IID_IDropTarget) { + *ppvObject = (void __RPC_FAR *__RPC_FAR)(IDropTarget*)this; + AddRef(); + return S_OK; + } else { + *ppvObject = (void __RPC_FAR *__RPC_FAR)NULL; + return E_NOINTERFACE; + } +} + +ULONG __stdcall +TestDropTarget::AddRef() { + return (ULONG)++m_refs; +} + +ULONG __stdcall +TestDropTarget::Release() { + int refs; + if ((refs = --m_refs) == 0) delete this; + return (ULONG)refs; +} + +HRESULT __stdcall +TestDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, + POINTL pt, DWORD __RPC_FAR *pdwEffect) { + *pdwEffect = DROPEFFECT_COPY; + return S_OK; +} + +HRESULT __stdcall +TestDropTarget::DragOver(DWORD grfKeyState, POINTL pt, + DWORD __RPC_FAR *pdwEffect) { + *pdwEffect = DROPEFFECT_COPY; + return S_OK; +} + +HRESULT __stdcall +TestDropTarget::DragLeave() { + return S_OK; +} + +HRESULT __stdcall +TestDropTarget::Drop(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, + POINTL pt, DWORD __RPC_FAR *pdwEffect) { + int nExitCode = CODE_OTHER_FAILURE; + HRESULT res = S_OK; + + *pdwEffect = DROPEFFECT_NONE; + + nExitCode = CheckTransferTymed(pDataObj, TYMED_HGLOBAL); + if (nExitCode == CODE_OK) { + nExitCode = CheckTransferTymed(pDataObj, TYMED_ISTREAM); + } + if (nExitCode == CODE_OK) { + nExitCode = CheckTransferTymed(pDataObj, TYMED_ENHMF); + } + + if (nExitCode == CODE_OK) { + *pdwEffect = DROPEFFECT_COPY; + } + ::PostQuitMessage(nExitCode); + return res; +} + +int +TestDropTarget::CheckTransferTymed(IDataObject __RPC_FAR *pDataObj, + DWORD tymed) { + int nExitCode = CODE_OTHER_FAILURE; + FORMATETC format; + + switch (tymed) { + case TYMED_HGLOBAL: + case TYMED_ISTREAM: + format.cfFormat = CF_TEXT; + break; + case TYMED_ENHMF: + format.cfFormat = CF_ENHMETAFILE; + break; + } + format.ptd = NULL; + format.lindex = -1; + format.dwAspect = DVASPECT_CONTENT; + format.tymed = tymed; + + STGMEDIUM stgmedium; + + HRESULT res = pDataObj->GetData(&format, &stgmedium); + if (res == S_OK) { + if (stgmedium.tymed == tymed) { + nExitCode = CODE_INVALID_DATA_FAILURE; + + switch (tymed) { + case TYMED_HGLOBAL: { + DWORD size = ::GlobalSize(stgmedium.hGlobal); + if (size != 0) { + LPVOID data = ::GlobalLock(stgmedium.hGlobal); + if (strcmp((const char*)data, TEST_TEXT) == 0) { + nExitCode = CODE_OK; + } + } + break; + } + case TYMED_ISTREAM: { + IStream* pstm = stgmedium.pstm; + if (pstm != NULL) { + STATSTG statstg; + if (pstm->Stat(&statstg, STATFLAG_NONAME) == S_OK) { + if (statstg.cbSize.LowPart >= strlen(TEST_TEXT) && + statstg.cbSize.HighPart == 0) { + ULONG size = (ULONG)statstg.cbSize.QuadPart; + ULONG act = 0; + LPVOID buf = calloc(1, size); + if (buf != NULL) { + if (pstm->Read((void*)buf,size,&act) == S_OK && + strcmp((const char*)buf, TEST_TEXT) == 0) { + + nExitCode = CODE_OK; + } + free(buf); + } + } + } + } + break; + } + case TYMED_ENHMF: { + HENHMETAFILE hemf = stgmedium.hEnhMetaFile; + UINT size = ::GetEnhMetaFileHeader(hemf, 0, NULL); + BOOL headerValid = FALSE; + if (size != 0) { + LPENHMETAHEADER lpemh = (LPENHMETAHEADER)calloc(1, size); + if (lpemh != NULL) { + if (::GetEnhMetaFileHeader(hemf, size, lpemh) == size) { + headerValid = TRUE; + } + free(lpemh); + } + } + if (headerValid == TRUE) { + UINT size = ::GetEnhMetaFileBits(hemf, 0, NULL); + if (size != 0) { + LPBYTE lpbits = (LPBYTE)calloc(1, size); + if (lpbits != NULL) { + if (::GetEnhMetaFileBits(hemf, size, lpbits) == size) { + nExitCode = CODE_OK; + } + free(lpbits); + } + } + } + break; + } + } + } else { + nExitCode = CODE_INVALID_TYMED_FAILURE; + } + } + + DumpTestResult(tymed, nExitCode); + ::ReleaseStgMedium(&stgmedium); + return nExitCode; +} + +void +TestDropTarget::DumpTestResult(DWORD tymed, int nTestResult) { + switch (tymed) { + case TYMED_HGLOBAL: + fprintf(stderr,"Test transfer for TYMED_HGLOBAL: "); + break; + case TYMED_ISTREAM: + fprintf(stderr,"Test transfer for TYMED_ISTREAM: "); + break; + case TYMED_ENHMF: + fprintf(stderr,"Test transfer for TYMED_ENHMF: "); + break; + default: + fprintf(stderr,"Test transfer for unknown TYMED %d: ", tymed); + break; + } + + switch (nTestResult) { + case CODE_OK: + fprintf(stderr,"PASSED"); + break; + case CODE_INVALID_TYMED_FAILURE: + fprintf(stderr,"FAILED: invalid TYMED detected"); + break; + case CODE_INVALID_DATA_FAILURE: + fprintf(stderr,"FAILED: invalid transfer data detected"); + break; + case CODE_OTHER_FAILURE: + fprintf(stderr,"FAILED: other failure detected"); + break; + default: + fprintf(stderr,"FAILED: unknown test result %d", nTestResult); + break; + } + + fprintf(stderr,"\n"); +} + +LRESULT CALLBACK +WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ) { + switch (iMessage) { + case WM_DESTROY: + ::RevokeDragDrop(hWnd); + ::OleUninitialize(); + ::PostQuitMessage(0); + break; + default: + return ::DefWindowProc( hWnd, iMessage, wParam, lParam ); + } + return 0; +} + +int +main(int argc, char* argv[]) { + + HMODULE hInstance = ::GetModuleHandle(NULL); + WNDCLASS wndclass; + wndclass.style = CS_OWNDC; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = NULL; + wndclass.hCursor = NULL; + wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szClassName; + if (::RegisterClass(&wndclass) == 0) { + exit( FALSE ); + } + HWND hMainWnd = ::CreateWindowEx(WS_EX_CLIENTEDGE, szClassName, szClassName, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + X, Y, WIDTH, HEIGHT, + NULL, NULL, hInstance, NULL); + if (hMainWnd == NULL) { + exit(FALSE); + } + ::ShowWindow(hMainWnd, SW_SHOWNORMAL); + ::UpdateWindow(hMainWnd); + ::OleInitialize(NULL); + HRESULT res = ::RegisterDragDrop(hMainWnd, new TestDropTarget()); + MSG msg; + + while (::GetMessage(&msg, NULL, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::OleUninitialize(); + ::UnregisterClass(szClassName, hInstance); + return msg.wParam; +}