ReactOS 0.4.16-dev-2332-g4cba65d
clipboard.c
Go to the documentation of this file.
1/*
2 * Clipboard unit tests
3 *
4 * Copyright 2006 Kevin Koltzau
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define COBJMACROS
22#define CONST_VTABLE
23
24#include <stdarg.h>
25#include <stdio.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "objbase.h"
30#include "shellapi.h"
31#include "shlobj.h"
32
33#include "wine/test.h"
34
35#define InitFormatEtc(fe, cf, med) \
36 {\
37 (fe).cfFormat=cf;\
38 (fe).dwAspect=DVASPECT_CONTENT;\
39 (fe).ptd=NULL;\
40 (fe).tymed=med;\
41 (fe).lindex=-1;\
42 };
43
44static inline char *dump_fmtetc(FORMATETC *fmt)
45{
46 static char buf[100];
47
48 sprintf(buf, "cf %04x ptd %p aspect %lx lindex %ld tymed %lx",
49 fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
50 return buf;
51}
52
53typedef struct DataObjectImpl {
55 LONG ref;
56
57 FORMATETC *fmtetc;
59
63 HMETAFILEPICT hmfp;
65
66typedef struct EnumFormatImpl {
68 LONG ref;
69
70 FORMATETC *fmtetc;
72
73 UINT cur;
75
80
82
83static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);
84
85static HMETAFILE create_mf(void)
86{
87 RECT rect = {0, 0, 100, 100};
89 ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
90 return CloseMetaFile(hdc);
91}
92
93static HMETAFILEPICT create_metafilepict(void)
94{
97 mf->mm = MM_ANISOTROPIC;
98 mf->xExt = 100;
99 mf->yExt = 200;
100 mf->hMF = create_mf();
102 return ret;
103}
104
106{
107 return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface);
108}
109
111{
112 return CONTAINING_RECORD(iface, EnumFormatImpl, IEnumFORMATETC_iface);
113}
114
116{
118
120 IEnumFORMATETC_AddRef(iface);
121 *ppvObj = &This->IEnumFORMATETC_iface;
122 return S_OK;
123 }
124 *ppvObj = NULL;
125 return E_NOINTERFACE;
126}
127
129{
132 return ref;
133}
134
136{
139
140 if(!ref) {
141 free(This->fmtetc);
142 free(This);
143 }
144
145 return ref;
146}
147
149 FORMATETC *rgelt, ULONG *pceltFetched)
150{
152 ULONG count, i;
153
154 if (winetest_debug > 1)
155 trace("next: count %ld cur %d\n", celt, This->cur);
156
157 if(!rgelt)
158 return E_INVALIDARG;
159
160 count = min(celt, This->fmtetc_cnt - This->cur);
161 for(i = 0; i < count; i++, This->cur++, rgelt++)
162 {
163 *rgelt = This->fmtetc[This->cur];
164 if(rgelt->ptd)
165 {
166 DWORD size = This->fmtetc[This->cur].ptd->tdSize;
167 rgelt->ptd = CoTaskMemAlloc(size);
168 memcpy(rgelt->ptd, This->fmtetc[This->cur].ptd, size);
169 }
170 }
171 if(pceltFetched)
172 *pceltFetched = count;
173 return count == celt ? S_OK : S_FALSE;
174}
175
177{
178 ok(0, "unexpected call\n");
179 return E_NOTIMPL;
180}
181
183{
185
186 This->cur = 0;
187 return S_OK;
188}
189
191{
192 ok(0, "unexpected call\n");
193 return E_NOTIMPL;
194}
195
196static const IEnumFORMATETCVtbl VT_EnumFormatImpl = {
204};
205
206static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFORMATETC **lplpformatetc)
207{
209
210 ret = malloc(sizeof(EnumFormatImpl));
211 ret->IEnumFORMATETC_iface.lpVtbl = &VT_EnumFormatImpl;
212 ret->ref = 1;
213 ret->cur = 0;
214 ret->fmtetc_cnt = fmtetc_cnt;
215 ret->fmtetc = malloc(fmtetc_cnt * sizeof(FORMATETC));
216 memcpy(ret->fmtetc, fmtetc, fmtetc_cnt*sizeof(FORMATETC));
217 *lplpformatetc = &ret->IEnumFORMATETC_iface;
218 return S_OK;
219}
220
222{
224
226 IDataObject_AddRef(iface);
227 *ppvObj = &This->IDataObject_iface;
228 return S_OK;
229 }
230 *ppvObj = NULL;
231 return E_NOINTERFACE;
232}
233
235{
238 return ref;
239}
240
242{
245
246 if(!ref)
247 {
248 int i;
249 if(This->text) GlobalFree(This->text);
250 for(i = 0; i < This->fmtetc_cnt; i++)
251 free(This->fmtetc[i].ptd);
252 free(This->fmtetc);
253 if(This->stm) IStream_Release(This->stm);
254 if(This->stg) IStorage_Release(This->stg);
255 if(This->hmfp) {
256 METAFILEPICT *mfp = GlobalLock(This->hmfp);
257 DeleteMetaFile(mfp->hMF);
258 GlobalUnlock(This->hmfp);
259 GlobalFree(This->hmfp);
260 }
261 free(This);
262 }
263
264 return ref;
265}
266
267static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
268{
270 UINT i;
271
272 trace("getdata: %s\n", dump_fmtetc(pformatetc));
273
275
276 ok(pmedium->tymed == 0, "pmedium->tymed = %lu\n", pmedium->tymed);
277 ok(pmedium->hGlobal == NULL, "pmedium->hGlobal = %p\n", pmedium->hGlobal);
278 ok(pmedium->pUnkForRelease == NULL, "pmedium->pUnkForRelease = %p\n", pmedium->pUnkForRelease);
279
280 if(pformatetc->lindex != -1)
281 return DV_E_FORMATETC;
282
283 for(i = 0; i < This->fmtetc_cnt; i++)
284 {
285 if(This->fmtetc[i].cfFormat == pformatetc->cfFormat)
286 {
287 if(This->fmtetc[i].tymed & pformatetc->tymed)
288 {
289 pmedium->pUnkForRelease = (LPUNKNOWN)iface;
290 IUnknown_AddRef(pmedium->pUnkForRelease);
291
292 if(pformatetc->cfFormat == CF_TEXT || pformatetc->cfFormat == cf_global)
293 {
294 pmedium->tymed = TYMED_HGLOBAL;
295 pmedium->hGlobal = This->text;
296 }
297 else if(pformatetc->cfFormat == cf_stream)
298 {
299 pmedium->tymed = TYMED_ISTREAM;
300 IStream_AddRef(This->stm);
301 pmedium->pstm = This->stm;
302 }
303 else if(pformatetc->cfFormat == cf_storage || pformatetc->cfFormat == cf_another)
304 {
305 pmedium->tymed = TYMED_ISTORAGE;
306 IStorage_AddRef(This->stg);
307 pmedium->pstg = This->stg;
308 }
309 else if(pformatetc->cfFormat == CF_METAFILEPICT)
310 {
311 pmedium->tymed = TYMED_MFPICT;
312 pmedium->hMetaFilePict = This->hmfp;
313 }
314 return S_OK;
315 }
316 }
317 }
318
319 return E_FAIL;
320}
321
322static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
323{
324 trace("getdatahere: %s\n", dump_fmtetc(pformatetc));
326
327 return E_NOTIMPL;
328}
329
330static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC *pformatetc)
331{
333 UINT i;
334 BOOL foundFormat = FALSE;
335
336 trace("querygetdata: %s\n", dump_fmtetc(pformatetc));
338 ok(0, "unexpected call to DataObjectImpl_QueryGetData\n");
339
340 if(pformatetc->lindex != -1)
341 return DV_E_LINDEX;
342
343 for(i=0; i<This->fmtetc_cnt; i++) {
344 if(This->fmtetc[i].cfFormat == pformatetc->cfFormat) {
345 foundFormat = TRUE;
346 if(This->fmtetc[i].tymed == pformatetc->tymed)
347 return S_OK;
348 }
349 }
350 return foundFormat?DV_E_FORMATETC:DV_E_TYMED;
351}
352
353static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject* iface, FORMATETC *pformatectIn,
354 FORMATETC *pformatetcOut)
355{
356 ok(0, "unexpected call\n");
357 return E_NOTIMPL;
358}
359
360static HRESULT WINAPI DataObjectImpl_SetData(IDataObject* iface, FORMATETC *pformatetc,
361 STGMEDIUM *pmedium, BOOL fRelease)
362{
363 ok(0, "unexpected call\n");
364 return E_NOTIMPL;
365}
366
368 IEnumFORMATETC **ppenumFormatEtc)
369{
371
373
374 if(dwDirection != DATADIR_GET) {
375 ok(0, "unexpected direction %ld\n", dwDirection);
376 return E_NOTIMPL;
377 }
378 return EnumFormatImpl_Create(This->fmtetc, This->fmtetc_cnt, ppenumFormatEtc);
379}
380
381static HRESULT WINAPI DataObjectImpl_DAdvise(IDataObject* iface, FORMATETC *pformatetc, DWORD advf,
382 IAdviseSink *pAdvSink, DWORD *pdwConnection)
383{
384 ok(0, "unexpected call\n");
385 return E_NOTIMPL;
386}
387
389{
390 ok(0, "unexpected call\n");
391 return E_NOTIMPL;
392}
393
395{
396 ok(0, "unexpected call\n");
397 return E_NOTIMPL;
398}
399
400static const IDataObjectVtbl VT_DataObjectImpl =
401{
414};
415
417{
419
420 obj = malloc(sizeof(DataObjectImpl));
422 obj->ref = 1;
423 obj->text = text;
424 obj->stm = NULL;
425 obj->stg = NULL;
426 obj->hmfp = NULL;
427
428 obj->fmtetc_cnt = 1;
429 obj->fmtetc = malloc(obj->fmtetc_cnt * sizeof(FORMATETC));
430 InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
431
432 *dataobj = &obj->IDataObject_iface;
433 return S_OK;
434}
435
437{
441 return DataObjectImpl_CreateFromHGlobal(h, lplpdataobj);
442}
443
444static const char *cmpl_stm_data = "complex stream";
445static const char *cmpl_text_data = "complex text";
446static const WCHAR device_name[] = {'m','y','d','e','v',0};
447
449{
451 ILockBytes *lbs;
452 DEVMODEW dm;
453
454 obj = malloc(sizeof(DataObjectImpl));
456 obj->ref = 1;
459 GlobalUnlock(obj->text);
461 IStream_Write(obj->stm, cmpl_stm_data, strlen(cmpl_stm_data), NULL);
462
465 ILockBytes_Release(lbs);
466
467 obj->hmfp = create_metafilepict();
468
469 obj->fmtetc_cnt = 9;
470 /* zeroing here since FORMATETC has a hole in it, and it's confusing to have this uninitialised. */
471 obj->fmtetc = calloc(obj->fmtetc_cnt, sizeof(FORMATETC));
472 InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
473 InitFormatEtc(obj->fmtetc[1], cf_stream, TYMED_ISTREAM);
474 InitFormatEtc(obj->fmtetc[2], cf_storage, TYMED_ISTORAGE);
475 InitFormatEtc(obj->fmtetc[3], cf_another, TYMED_ISTORAGE|TYMED_ISTREAM|TYMED_HGLOBAL);
476 if (0) /* Causes crashes on both Wine and Windows */
477 {
478 memset(&dm, 0, sizeof(dm));
479 dm.dmSize = sizeof(dm);
480 dm.dmDriverExtra = 0;
482 obj->fmtetc[3].ptd = malloc(FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
483 obj->fmtetc[3].ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
484 obj->fmtetc[3].ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
485 obj->fmtetc[3].ptd->tdDeviceNameOffset = 0;
486 obj->fmtetc[3].ptd->tdPortNameOffset = 0;
487 obj->fmtetc[3].ptd->tdExtDevmodeOffset = obj->fmtetc[3].ptd->tdDriverNameOffset + sizeof(device_name);
488 lstrcpyW((WCHAR*)obj->fmtetc[3].ptd->tdData, device_name);
489 memcpy(obj->fmtetc[3].ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
490 }
491
492 InitFormatEtc(obj->fmtetc[4], cf_global, TYMED_HGLOBAL);
493 InitFormatEtc(obj->fmtetc[5], cf_another, TYMED_HGLOBAL);
494 InitFormatEtc(obj->fmtetc[6], cf_another, 0xfffff);
495 InitFormatEtc(obj->fmtetc[7], cf_another, 0xfffff);
496 obj->fmtetc[7].dwAspect = DVASPECT_ICON;
497 InitFormatEtc(obj->fmtetc[8], CF_METAFILEPICT, TYMED_MFPICT);
498
499 *lplpdataobj = &obj->IDataObject_iface;
500 return S_OK;
501}
502
504{
505 REFCLSID rclsid = &CLSID_InternetZoneManager;
506 IDataObject *pDObj;
507 IUnknown *pUnk;
508 HRESULT hr;
509
510 pDObj = (IDataObject *)0xdeadbeef;
511 hr = OleGetClipboard(&pDObj);
512 ok(hr == S_OK, "OleGetClipboard() got 0x%08lx instead of 0x%08lx\n", hr, S_OK);
513 ok(!!pDObj && pDObj != (IDataObject *)0xdeadbeef, "Got unexpected pDObj %p.\n", pDObj);
514
515 /* COM is still not initialized. */
516 hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
517 ok(hr == CO_E_NOTINITIALIZED, "Got unexpected hr %#lx.\n", hr);
518
520 ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
521
522 hr = OleIsCurrentClipboard(pDObj);
523 ok(hr == S_FALSE, "Got unexpected hr %#lx.\n", hr);
524
525 IDataObject_Release(pDObj);
526}
527
528static void test_get_clipboard(void)
529{
530 HRESULT hr;
531 IDataObject *data_obj;
532 FORMATETC fmtetc;
533 STGMEDIUM stgmedium;
534
536 ok(hr == E_INVALIDARG, "OleGetClipboard(NULL) should return E_INVALIDARG instead of 0x%08lx\n", hr);
537
538 hr = OleGetClipboard(&data_obj);
539 ok(hr == S_OK, "OleGetClipboard failed with error 0x%08lx\n", hr);
540
541 /* test IDataObject_QueryGetData */
542
543 /* clipboard's IDataObject_QueryGetData shouldn't defer to our IDataObject_QueryGetData */
545
546 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
547 hr = IDataObject_QueryGetData(data_obj, &fmtetc);
548 ok(hr == S_OK, "IDataObject_QueryGetData failed with error 0x%08lx\n", hr);
549
550 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
551 fmtetc.dwAspect = 0xdeadbeef;
552 hr = IDataObject_QueryGetData(data_obj, &fmtetc);
553 ok(hr == DV_E_FORMATETC, "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08lx\n", hr);
554
555 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
556 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
557 hr = IDataObject_QueryGetData(data_obj, &fmtetc);
558 ok(hr == DV_E_FORMATETC, "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08lx\n", hr);
559
560 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
561 fmtetc.lindex = 256;
562 hr = IDataObject_QueryGetData(data_obj, &fmtetc);
563 ok(hr == DV_E_FORMATETC || broken(hr == S_OK),
564 "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08lx\n", hr);
565
566 InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL);
567 hr = IDataObject_QueryGetData(data_obj, &fmtetc);
568 ok(hr == DV_E_CLIPFORMAT, "IDataObject_QueryGetData should have failed with DV_E_CLIPFORMAT instead of 0x%08lx\n", hr);
569
570 InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE);
571 hr = IDataObject_QueryGetData(data_obj, &fmtetc);
572 ok(hr == S_OK, "IDataObject_QueryGetData failed with error 0x%08lx\n", hr);
573
575
576 /* test IDataObject_GetData */
577
579
580 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
581 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
582 ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08lx\n", hr);
583 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
584
585 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
586 fmtetc.dwAspect = 0xdeadbeef;
587 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
588 ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08lx\n", hr);
589 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
590
591 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
592 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
593 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
594 ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08lx\n", hr);
595 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
596
597 InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
598 fmtetc.lindex = 256;
599 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
600 ok(hr == DV_E_FORMATETC || broken(hr == S_OK), "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08lx\n", hr);
601 if (hr == S_OK)
602 {
603 /* undo the unexpected success */
605 ReleaseStgMedium(&stgmedium);
606 }
607
608 InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL);
609 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
610 ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08lx\n", hr);
611 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
612
613 InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE);
614 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
615 ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08lx\n", hr);
616 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
617
618 ok(DataObjectImpl_GetData_calls == 6, "DataObjectImpl_GetData should have been called 6 times instead of %ld times\n", DataObjectImpl_GetData_calls);
619
620 IDataObject_Release(data_obj);
621}
622
624{
625 HRESULT hr;
627 IEnumFORMATETC *enum_fmt, *src_enum;
628 FORMATETC fmt, src_fmt;
629 DWORD count = 0;
630
632 ok(hr == S_OK, "OleGetClipboard failed with error 0x%08lx\n", hr);
633
634 hr = IDataObject_EnumFormatEtc(data, DATADIR_SET, &enum_fmt);
635 ok(hr == E_NOTIMPL ||
636 broken(hr == E_INVALIDARG), /* win98 (not win98SE) */
637 "got %08lx\n", hr);
638
640 hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
641 ok(hr == S_OK, "got %08lx\n", hr);
642 ok(DataObjectImpl_EnumFormatEtc_calls == 0, "EnumFormatEtc was called\n");
643 if (FAILED(hr))
644 {
645 skip("EnumFormatEtc failed, skipping tests.\n");
646 return;
647 }
648
649 if(src) IDataObject_EnumFormatEtc(src, DATADIR_GET, &src_enum);
650
651 while((hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL)) == S_OK)
652 {
653 ok(src != NULL, "shouldn't be here\n");
654 hr = IEnumFORMATETC_Next(src_enum, 1, &src_fmt, NULL);
655 ok(hr == S_OK, "%ld: got %08lx\n", count, hr);
656 trace("%ld: %s\n", count, dump_fmtetc(&fmt));
657 ok(fmt.cfFormat == src_fmt.cfFormat, "%ld: %04x %04x\n", count, fmt.cfFormat, src_fmt.cfFormat);
658 ok(fmt.dwAspect == src_fmt.dwAspect, "%ld: %08lx %08lx\n", count, fmt.dwAspect, src_fmt.dwAspect);
659 ok(fmt.lindex == src_fmt.lindex, "%ld: %08lx %08lx\n", count, fmt.lindex, src_fmt.lindex);
660 ok(fmt.tymed == src_fmt.tymed, "%ld: %08lx %08lx\n", count, fmt.tymed, src_fmt.tymed);
661 if(fmt.ptd)
662 {
663 ok(src_fmt.ptd != NULL, "%ld: expected non-NULL\n", count);
664 CoTaskMemFree(fmt.ptd);
665 CoTaskMemFree(src_fmt.ptd);
666 }
667 count++;
668 }
669
670 ok(hr == S_FALSE, "%ld: got %08lx\n", count, hr);
671
672 if(src)
673 {
674 hr = IEnumFORMATETC_Next(src_enum, 1, &src_fmt, NULL);
675 ok(hr == S_FALSE, "%ld: got %08lx\n", count, hr);
676 IEnumFORMATETC_Release(src_enum);
677 }
678
679 hr = IEnumFORMATETC_Reset(enum_fmt);
680 ok(hr == S_OK, "got %08lx\n", hr);
681
682 if(src) /* Exercise the enumerator a bit */
683 {
684 IEnumFORMATETC *clone;
685 FORMATETC third_fmt;
686
687 hr = IEnumFORMATETC_Next(enum_fmt, 1, &third_fmt, NULL);
688 ok(hr == S_OK, "got %08lx\n", hr);
689 hr = IEnumFORMATETC_Next(enum_fmt, 1, &third_fmt, NULL);
690 ok(hr == S_OK, "got %08lx\n", hr);
691 hr = IEnumFORMATETC_Next(enum_fmt, 1, &third_fmt, NULL);
692 ok(hr == S_OK, "got %08lx\n", hr);
693
694 hr = IEnumFORMATETC_Reset(enum_fmt);
695 ok(hr == S_OK, "got %08lx\n", hr);
696 hr = IEnumFORMATETC_Skip(enum_fmt, 2);
697 ok(hr == S_OK, "got %08lx\n", hr);
698
699 hr = IEnumFORMATETC_Clone(enum_fmt, &clone);
700 ok(hr == S_OK, "got %08lx\n", hr);
701 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
702 ok(hr == S_OK, "got %08lx\n", hr);
703 ok(fmt.cfFormat == third_fmt.cfFormat, "formats don't match\n");
704 hr = IEnumFORMATETC_Next(clone, 1, &fmt, NULL);
705 ok(hr == S_OK, "got %08lx\n", hr);
706 ok(fmt.cfFormat == third_fmt.cfFormat, "formats don't match\n");
707 IEnumFORMATETC_Release(clone);
708 }
709
710 IEnumFORMATETC_Release(enum_fmt);
711 IDataObject_Release(data);
712}
713
714static void test_no_cf_dataobject(void)
715{
716 UINT cf_dataobject = RegisterClipboardFormatA("DataObject");
717 UINT cf_ole_priv_data = RegisterClipboardFormatA("Ole Private Data");
718 HANDLE h;
720
721 h = GetClipboardData(cf_dataobject);
722 ok(!h, "got %p\n", h);
723 h = GetClipboardData(cf_ole_priv_data);
724 ok(!h, "got %p\n", h);
725
727}
728
730{
731 UINT cf = 0;
732 UINT cf_dataobject = RegisterClipboardFormatA("DataObject");
733 UINT cf_ole_priv_data = RegisterClipboardFormatA("Ole Private Data");
734 BOOL found_dataobject = FALSE, found_priv_data = FALSE;
735
737 do
738 {
740 if(cf == cf_dataobject)
741 {
743 HWND *ptr = GlobalLock(h);
745 HWND clip_owner = GetClipboardOwner();
746
747 found_dataobject = TRUE;
748 ok(size >= sizeof(*ptr), "size %ld\n", size);
749 if(data)
750 ok(*ptr == clip_owner, "hwnd %p clip_owner %p\n", *ptr, clip_owner);
751 else /* ole clipboard flushed */
752 ok(*ptr == NULL, "hwnd %p\n", *ptr);
754 }
755 else if(cf == cf_ole_priv_data)
756 {
757 found_priv_data = TRUE;
758 if(data)
759 {
761 DWORD *ptr = GlobalLock(h);
763
764 if(size != ptr[1])
765 win_skip("Ole Private Data in win9x format\n");
766 else
767 {
768 HRESULT hr;
769 IEnumFORMATETC *enum_fmt;
770 DWORD count = 0;
771 FORMATETC fmt;
772 struct formatetcetc
773 {
774 FORMATETC fmt;
775 BOOL first_use_of_cf;
776 DWORD res[2];
777 } *fmt_ptr;
778 struct priv_data
779 {
780 DWORD res1;
781 DWORD size;
782 DWORD res2;
783 DWORD count;
784 DWORD res3[2];
785 struct formatetcetc fmts[1];
786 } *priv = (struct priv_data*)ptr;
787 CLIPFORMAT cfs_seen[10];
788
789 hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
790 ok(hr == S_OK, "got %08lx\n", hr);
791 fmt_ptr = priv->fmts;
792
793 while(IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL) == S_OK)
794 {
795 int i;
796 BOOL seen_cf = FALSE;
797
798 ok(fmt_ptr->fmt.cfFormat == fmt.cfFormat,
799 "got %08x expected %08x\n", fmt_ptr->fmt.cfFormat, fmt.cfFormat);
800 ok(fmt_ptr->fmt.dwAspect == fmt.dwAspect, "got %08lx expected %08lx\n",
801 fmt_ptr->fmt.dwAspect, fmt.dwAspect);
802 ok(fmt_ptr->fmt.lindex == fmt.lindex, "got %08lx expected %08lx\n",
803 fmt_ptr->fmt.lindex, fmt.lindex);
804 ok(fmt_ptr->fmt.tymed == fmt.tymed, "got %08lx expected %08lx\n",
805 fmt_ptr->fmt.tymed, fmt.tymed);
806 for(i = 0; i < count; i++)
807 if(fmt_ptr->fmt.cfFormat == cfs_seen[i])
808 {
809 seen_cf = TRUE;
810 break;
811 }
812 cfs_seen[count] = fmt.cfFormat;
813 ok(fmt_ptr->first_use_of_cf != seen_cf, "got %08x expected %08x\n",
814 fmt_ptr->first_use_of_cf, !seen_cf);
815 ok(fmt_ptr->res[0] == 0, "got %08lx\n", fmt_ptr->res[0]);
816 ok(fmt_ptr->res[1] == 0, "got %08lx\n", fmt_ptr->res[1]);
817 if(fmt.ptd)
818 {
819 DVTARGETDEVICE *target;
820
821 ok(fmt_ptr->fmt.ptd != NULL, "target device offset zero\n");
822 target = (DVTARGETDEVICE*)((char*)priv + (DWORD_PTR)fmt_ptr->fmt.ptd);
823 ok(!memcmp(target, fmt.ptd, fmt.ptd->tdSize), "target devices differ\n");
824 CoTaskMemFree(fmt.ptd);
825 }
826 fmt_ptr++;
827 count++;
828 }
829 ok(priv->res1 == 0, "got %08lx\n", priv->res1);
830 ok(priv->res2 == 1, "got %08lx\n", priv->res2);
831 ok(priv->count == count, "got %08lx expected %08lx\n", priv->count, count);
832 ok(priv->res3[0] == 0, "got %08lx\n", priv->res3[0]);
833
834 /* win64 sets the lsb */
835 if(sizeof(fmt_ptr->fmt.ptd) == 8)
836 todo_wine ok(priv->res3[1] == 1, "got %08lx\n", priv->res3[1]);
837 else
838 ok(priv->res3[1] == 0, "got %08lx\n", priv->res3[1]);
839
841 IEnumFORMATETC_Release(enum_fmt);
842 }
843 }
844 }
845 else if(cf == cf_stream)
846 {
847 HGLOBAL h;
848 void *ptr;
849 DWORD size;
850
854 ptr = GlobalLock(h);
855 size = GlobalSize(h);
857 "expected %d got %ld\n", lstrlenA(cmpl_stm_data), size);
858 ok(!memcmp(ptr, cmpl_stm_data, strlen(cmpl_stm_data)), "mismatch\n");
860 }
861 else if(cf == cf_global)
862 {
863 HGLOBAL h;
864 void *ptr;
865 DWORD size;
866
870 ptr = GlobalLock(h);
871 size = GlobalSize(h);
873 "expected %d got %ld\n", lstrlenA(cmpl_text_data) + 1, size);
874 ok(!memcmp(ptr, cmpl_text_data, strlen(cmpl_text_data) + 1), "mismatch\n");
876 }
877 } while(cf);
879 ok(found_dataobject, "didn't find cf_dataobject\n");
880 ok(found_priv_data, "didn't find cf_ole_priv_data\n");
881}
882
884{
885 HRESULT hr;
886 IDataObject *data_obj;
887 FORMATETC fmtetc;
888 STGMEDIUM stgmedium;
889
890 hr = OleGetClipboard(&data_obj);
891 ok(hr == S_OK, "OleGetClipboard failed with error 0x%08lx\n", hr);
892
894
895 InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_MFPICT);
896 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
897 ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08lx\n", hr);
898 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
899
900 InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_HGLOBAL);
901 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
902 ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08lx\n", hr);
903 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
904
905 InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_HGLOBAL);
906 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
907 ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08lx\n", hr);
908 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
909
910 InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_ENHMF);
911 hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
912 ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08lx\n", hr);
913 if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
914
916 "DataObjectImpl_GetData called 5 times instead of %ld times\n",
918 IDataObject_Release(data_obj);
919}
920
921static void test_set_clipboard(void)
922{
923 HRESULT hr;
924 ULONG ref;
925 LPDATAOBJECT data1, data2, data_cmpl;
926 HGLOBAL hblob, h;
927 void *ptr;
928
929 cf_stream = RegisterClipboardFormatA("stream format");
930 cf_storage = RegisterClipboardFormatA("storage format");
931 cf_global = RegisterClipboardFormatA("global format");
932 cf_another = RegisterClipboardFormatA("another format");
933 cf_onemore = RegisterClipboardFormatA("one more format");
934
936 ok(hr == S_OK, "Failed to create data1 object: 0x%08lx\n", hr);
937 if(FAILED(hr))
938 return;
940 ok(hr == S_OK, "Failed to create data2 object: 0x%08lx\n", hr);
941 if(FAILED(hr))
942 return;
943 hr = DataObjectImpl_CreateComplex(&data_cmpl);
944 ok(hr == S_OK, "Failed to create complex data object: 0x%08lx\n", hr);
945 if(FAILED(hr))
946 return;
947
949 ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard should have failed with CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr);
950
953 ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard failed with 0x%08lx\n", hr);
955
957 ok(hr == S_OK, "OleInitialize failed with error 0x%08lx\n", hr);
958
960 ok(hr == S_OK, "failed to set clipboard to data1, hr = 0x%08lx\n", hr);
961
963
965 ok(hr == S_OK, "expected current clipboard to be data1, hr = 0x%08lx\n", hr);
967 ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08lx\n", hr);
969 ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08lx\n", hr);
970
972
974 ok(hr == S_OK, "failed to set clipboard to data2, hr = 0x%08lx\n", hr);
976 ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08lx\n", hr);
978 ok(hr == S_OK, "expected current clipboard to be data2, hr = 0x%08lx\n", hr);
980 ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08lx\n", hr);
981
982 /* put a format directly onto the clipboard to show
983 OleFlushClipboard doesn't empty the clipboard */
985 ptr = GlobalLock( hblob );
986 ok( ptr && ptr != hblob, "got fixed block %p / %p\n", ptr, hblob );
987 GlobalUnlock( hblob );
988 ok( OpenClipboard(NULL), "OpenClipboard failed\n" );
989 h = SetClipboardData(cf_onemore, hblob);
990 ok(h == hblob, "got %p\n", h);
992 ok(h == hblob, "got %p / %p\n", h, hblob);
993 ptr = GlobalLock( h );
994 ok( ptr && ptr != h, "got fixed block %p / %p\n", ptr, h );
995 GlobalUnlock( hblob );
996 ok( CloseClipboard(), "CloseClipboard failed\n" );
997
999 ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08lx\n", hr);
1001 ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08lx\n", hr);
1003 ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08lx\n", hr);
1005 ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08lx\n", hr);
1006
1007 /* format should survive the flush */
1008 ok( OpenClipboard(NULL), "OpenClipboard failed\n" );
1010 ok(h == hblob, "got %p\n", h);
1011 ptr = GlobalLock( h );
1012 ok( ptr && ptr != h, "got fixed block %p / %p\n", ptr, h );
1013 GlobalUnlock( hblob );
1014 ok( CloseClipboard(), "CloseClipboard failed\n" );
1015
1017
1019 ok(hr == S_OK, "Failed to clear clipboard, hr = 0x%08lx\n", hr);
1020
1023 ok(h == NULL, "got %p\n", h);
1025
1026 trace("setting complex\n");
1027 hr = OleSetClipboard(data_cmpl);
1028 ok(hr == S_OK, "failed to set clipboard to complex data, hr = 0x%08lx\n", hr);
1030 test_cf_dataobject(data_cmpl);
1031 test_enum_fmtetc(data_cmpl);
1032
1034 ok(hr == S_OK, "failed to clear clipboard, hr = 0x%08lx.\n", hr);
1035
1038
1039 ref = IDataObject_Release(data1);
1040 ok(ref == 0, "expected data1 ref=0, got %ld\n", ref);
1041 ref = IDataObject_Release(data2);
1042 ok(ref == 0, "expected data2 ref=0, got %ld\n", ref);
1043 ref = IDataObject_Release(data_cmpl);
1044 ok(ref == 0, "expected data_cmpl ref=0, got %ld\n", ref);
1045
1047}
1048
1052
1054{
1055 LRESULT ret;
1056
1057 switch (msg)
1058 {
1059 case WM_DRAWCLIPBOARD:
1061 if (clip_data)
1062 {
1063 /* if this is the WM_DRAWCLIPBOARD of a previous change, the data isn't current yet */
1064 /* this demonstrates an issue in Qt where it will free the data while it's being set */
1066 ok( hr == (wm_drawclipboard > 1) ? S_OK : S_FALSE,
1067 "OleIsCurrentClipboard returned %lx\n", hr );
1068 }
1069 break;
1070 case WM_CHANGECBCHAIN:
1071 if (next_wnd == (HWND)wp) next_wnd = (HWND)lp;
1072 else if (next_wnd) SendMessageA( next_wnd, msg, wp, lp );
1073 break;
1074 case WM_USER:
1076 wm_drawclipboard = 0;
1077 return ret;
1078 }
1079
1080 return DefWindowProcA(hwnd, msg, wp, lp);
1081}
1082
1084{
1089 return 0;
1090}
1091
1092/* test that WM_DRAWCLIPBOARD can be delivered for a previous change during OleSetClipboard */
1094{
1096 HRESULT hr;
1097 WNDCLASSA cls;
1098 HWND viewer;
1099 int ret;
1100 HANDLE thread;
1101
1102 hr = DataObjectImpl_CreateText("data", &data);
1103 ok(hr == S_OK, "Failed to create data object: 0x%08lx\n", hr);
1104
1105 memset(&cls, 0, sizeof(cls));
1108 cls.lpszClassName = "clipboard_test";
1109 RegisterClassA(&cls);
1110
1111 viewer = CreateWindowA("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0);
1112 ok(viewer != NULL, "CreateWindow failed: %ld\n", GetLastError());
1113 next_wnd = SetClipboardViewer( viewer );
1114
1115 ret = SendMessageA( viewer, WM_USER, 0, 0 );
1116 ok( ret == 1, "%u WM_DRAWCLIPBOARD received\n", ret );
1117
1119 ok(hr == S_OK, "OleInitialize failed with error 0x%08lx\n", hr);
1120
1121 ret = SendMessageA( viewer, WM_USER, 0, 0 );
1122 ok( !ret, "%u WM_DRAWCLIPBOARD received\n", ret );
1123
1125 ok(thread != NULL, "CreateThread failed (%ld)\n", GetLastError());
1127 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
1128
1129 clip_data = data;
1131 ok(hr == S_OK, "failed to set clipboard to data, hr = 0x%08lx\n", hr);
1132
1133 ret = SendMessageA( viewer, WM_USER, 0, 0 );
1134 ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
1135
1136 clip_data = NULL;
1138 ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08lx\n", hr);
1139 ret = IDataObject_Release(data);
1140 ok(ret == 0, "got %d\n", ret);
1141
1143 ChangeClipboardChain( viewer, next_wnd );
1144 DestroyWindow( viewer );
1145}
1146
1148{
1149 IDataObject_AddRef(d);
1150 return IDataObject_Release(d);
1151}
1152
1153static void test_consumer_refs(void)
1154{
1155 HRESULT hr;
1156 IDataObject *src, *src2, *get1, *get2, *get3;
1157 ULONG refs, old_refs;
1158 FORMATETC fmt;
1159 STGMEDIUM med;
1160
1161 InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
1162
1164
1165 /* First show that each clipboard state results in
1166 a different data object */
1167
1168 hr = DataObjectImpl_CreateText("data1", &src);
1169 ok(hr == S_OK, "got %08lx\n", hr);
1170 hr = DataObjectImpl_CreateText("data2", &src2);
1171 ok(hr == S_OK, "got %08lx\n", hr);
1172
1174 ok(hr == S_OK, "got %08lx\n", hr);
1175
1176 hr = OleGetClipboard(&get1);
1177 ok(hr == S_OK, "got %08lx\n", hr);
1178
1179 hr = OleGetClipboard(&get2);
1180 ok(hr == S_OK, "got %08lx\n", hr);
1181
1182 ok(get1 == get2, "data objects differ\n");
1183 refs = IDataObject_Release(get2);
1184 ok(refs == (get1 == get2 ? 1 : 0), "got %ld\n", refs);
1185
1187
1189 hr = IDataObject_GetData(get1, &fmt, &med);
1190 ok(hr == S_OK, "got %08lx\n", hr);
1191 ok(DataObjectImpl_GetData_calls == 0, "GetData called\n");
1192 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1193
1194 hr = OleGetClipboard(&get2);
1195 ok(hr == S_OK, "got %08lx\n", hr);
1196
1197 ok(get1 != get2, "data objects match\n");
1198
1200 ok(hr == S_OK, "Failed to clear clipboard, hr %#lx.\n", hr);
1201
1202 hr = OleGetClipboard(&get3);
1203 ok(hr == S_OK, "got %08lx\n", hr);
1204
1205 ok(get1 != get3, "data objects match\n");
1206 ok(get2 != get3, "data objects match\n");
1207
1208 IDataObject_Release(get3);
1209 IDataObject_Release(get2);
1210 IDataObject_Release(get1);
1211
1212 /* Now call GetData before the flush and show that this
1213 takes a ref on our src data obj. */
1214
1216 ok(hr == S_OK, "got %08lx\n", hr);
1217
1218 old_refs = count_refs(src);
1219
1220 hr = OleGetClipboard(&get1);
1221 ok(hr == S_OK, "got %08lx\n", hr);
1222
1223 refs = count_refs(src);
1224 ok(refs == old_refs, "%ld %ld\n", refs, old_refs);
1225
1227 hr = IDataObject_GetData(get1, &fmt, &med);
1228 ok(hr == S_OK, "got %08lx\n", hr);
1229 ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
1230 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1231 refs = count_refs(src);
1232 ok(refs == old_refs + 1, "%ld %ld\n", refs, old_refs);
1233
1235
1237 hr = IDataObject_GetData(get1, &fmt, &med);
1238 ok(hr == S_OK, "got %08lx\n", hr);
1239 ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
1240 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1241
1242 refs = count_refs(src);
1243 ok(refs == 2, "%ld\n", refs);
1244
1245 IDataObject_Release(get1);
1246
1247 refs = count_refs(src);
1248 ok(refs == 1, "%ld\n", refs);
1249
1250 /* Now set a second src object before the call to GetData
1251 and show that GetData calls that second src. */
1252
1254 ok(hr == S_OK, "got %08lx\n", hr);
1255
1256 old_refs = count_refs(src);
1257
1258 hr = OleGetClipboard(&get1);
1259 ok(hr == S_OK, "got %08lx\n", hr);
1260
1261 refs = count_refs(src);
1262 ok(refs == old_refs, "%ld %ld\n", refs, old_refs);
1263
1264 hr = OleSetClipboard(src2);
1265 ok(hr == S_OK, "got %08lx\n", hr);
1266
1267 old_refs = count_refs(src2);
1268
1270 hr = IDataObject_GetData(get1, &fmt, &med);
1271 ok(hr == S_OK, "got %08lx\n", hr);
1272 ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
1273 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1274
1275 refs = count_refs(src);
1276 ok(refs == 1, "%ld\n", refs);
1277 refs = count_refs(src2);
1278 ok(refs == old_refs + 1, "%ld %ld\n", refs, old_refs);
1279
1281 ok(hr == S_OK, "Failed to clear clipboard, hr %#lx.\n", hr);
1282
1283 refs = count_refs(src2);
1284 ok(refs == 2, "%ld\n", refs);
1285
1286 IDataObject_Release(get1);
1287
1288 IDataObject_Release(src2);
1289
1290 /* Show that OleUninitialize() doesn't release the
1291 dataobject's ref, and thus the object is leaked. */
1292 old_refs = count_refs(src);
1293 ok(old_refs == 1, "%ld\n", old_refs);
1294
1296 ok(hr == S_OK, "Failed to clear clipboard, hr %#lx.\n", hr);
1297 refs = count_refs(src);
1298 ok(refs > old_refs, "%ld %ld\n", refs, old_refs);
1299
1301 refs = count_refs(src);
1302 ok(refs == 2, "%ld\n", refs);
1303
1306 ok(hr == S_OK, "Failed to clear clipboard, hr %#lx.\n", hr);
1307
1309
1310 refs = count_refs(src);
1311 ok(refs == 2, "%ld\n", refs);
1312
1313 IDataObject_Release(src);
1314}
1315
1317{
1318 ILockBytes *ilb;
1319 IStorage *stg;
1320 HGLOBAL hg;
1321 HRESULT hr;
1322
1324 ok(hr == S_OK, "got %08lx\n", hr);
1326 ok(hr == S_OK, "got %08lx\n", hr);
1327 IStorage_Release(stg);
1329 ok(hr == S_OK, "got %08lx\n", hr);
1330 ILockBytes_Release(ilb);
1331 return hg;
1332}
1333
1334static void test_flushed_getdata(void)
1335{
1336 HRESULT hr;
1337 IDataObject *src, *get;
1338 FORMATETC fmt;
1339 STGMEDIUM med;
1340 STATSTG stat;
1341 DEVMODEW dm;
1342
1344
1346 ok(hr == S_OK, "got %08lx\n", hr);
1347
1349 ok(hr == S_OK, "got %08lx\n", hr);
1350
1352 ok(hr == S_OK, "got %08lx\n", hr);
1353
1355 ok(hr == S_OK, "got %08lx\n", hr);
1356
1357 /* global format -> global & stream */
1358
1359 InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
1360 hr = IDataObject_GetData(get, &fmt, &med);
1361 ok(hr == S_OK, "got %08lx\n", hr);
1362 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1363 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1364
1365 InitFormatEtc(fmt, CF_TEXT, TYMED_ISTREAM);
1366 hr = IDataObject_GetData(get, &fmt, &med);
1367 ok(hr == S_OK, "got %08lx\n", hr);
1368 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1369 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1370
1371 InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
1372 hr = IDataObject_GetData(get, &fmt, &med);
1373 ok(hr == E_FAIL, "got %08lx\n", hr);
1374 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1375
1376 InitFormatEtc(fmt, CF_TEXT, 0xffff);
1377 hr = IDataObject_GetData(get, &fmt, &med);
1378 ok(hr == S_OK, "got %08lx\n", hr);
1379 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1380 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1381
1382 /* stream format -> global & stream */
1383
1384 InitFormatEtc(fmt, cf_stream, TYMED_ISTREAM);
1385 hr = IDataObject_GetData(get, &fmt, &med);
1386 ok(hr == S_OK, "got %08lx\n", hr);
1387 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1388 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1389
1390 InitFormatEtc(fmt, cf_stream, TYMED_ISTORAGE);
1391 hr = IDataObject_GetData(get, &fmt, &med);
1392 ok(hr == E_FAIL, "got %08lx\n", hr);
1393 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1394
1395 InitFormatEtc(fmt, cf_stream, TYMED_HGLOBAL);
1396 hr = IDataObject_GetData(get, &fmt, &med);
1397 ok(hr == S_OK, "got %08lx\n", hr);
1398 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1399 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1400
1401 InitFormatEtc(fmt, cf_stream, 0xffff);
1402 hr = IDataObject_GetData(get, &fmt, &med);
1403 ok(hr == S_OK, "got %08lx\n", hr);
1404 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1405 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1406
1407 /* storage format -> global, stream & storage */
1408
1409 InitFormatEtc(fmt, cf_storage, TYMED_ISTORAGE);
1410 hr = IDataObject_GetData(get, &fmt, &med);
1411 ok(hr == S_OK, "got %08lx\n", hr);
1412 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1413 if(SUCCEEDED(hr)) {
1414 hr = IStorage_Stat(med.pstg, &stat, STATFLAG_NONAME);
1415 ok(hr == S_OK, "got %08lx\n", hr);
1416 ok(stat.grfMode == (STGM_SHARE_EXCLUSIVE | STGM_READWRITE), "got %08lx\n", stat.grfMode);
1417 ReleaseStgMedium(&med);
1418 }
1419
1420 InitFormatEtc(fmt, cf_storage, TYMED_ISTREAM);
1421 hr = IDataObject_GetData(get, &fmt, &med);
1422 ok(hr == S_OK, "got %08lx\n", hr);
1423 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1424 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1425
1426 InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL);
1427 hr = IDataObject_GetData(get, &fmt, &med);
1428 ok(hr == S_OK, "got %08lx\n", hr);
1429 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1430 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1431
1432 InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL | TYMED_ISTREAM);
1433 hr = IDataObject_GetData(get, &fmt, &med);
1434 ok(hr == S_OK, "got %08lx\n", hr);
1435 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1436 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1437
1438 InitFormatEtc(fmt, cf_storage, 0xffff);
1439 hr = IDataObject_GetData(get, &fmt, &med);
1440 ok(hr == S_OK, "got %08lx\n", hr);
1441 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1442 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1443
1444 /* complex format with target device */
1445
1446 InitFormatEtc(fmt, cf_another, 0xffff);
1447 hr = IDataObject_GetData(get, &fmt, &med);
1448 ok(hr == S_OK, "got %08lx\n", hr);
1449 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1450
1451 if (0) /* Causes crashes on both Wine and Windows */
1452 {
1453 InitFormatEtc(fmt, cf_another, 0xffff);
1454 memset(&dm, 0, sizeof(dm));
1455 dm.dmSize = sizeof(dm);
1456 dm.dmDriverExtra = 0;
1458 fmt.ptd = malloc(FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
1459 fmt.ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
1460 fmt.ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
1461 fmt.ptd->tdDeviceNameOffset = 0;
1462 fmt.ptd->tdPortNameOffset = 0;
1463 fmt.ptd->tdExtDevmodeOffset = fmt.ptd->tdDriverNameOffset + sizeof(device_name);
1464 lstrcpyW((WCHAR*)fmt.ptd->tdData, device_name);
1465 memcpy(fmt.ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
1466
1467 hr = IDataObject_GetData(get, &fmt, &med);
1468 ok(hr == S_OK, "got %08lx\n", hr);
1469 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1470 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1471
1472 free(fmt.ptd);
1473 }
1474
1475 /* CF_ENHMETAFILE format */
1476 InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF);
1477 hr = IDataObject_GetData(get, &fmt, &med);
1478 ok(hr == S_OK, "got %08lx\n", hr);
1479 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1480
1481 IDataObject_Release(get);
1482 IDataObject_Release(src);
1483
1485 ok(hr == S_OK, "got %08lx\n", hr);
1486
1488 ok(hr == S_OK, "got %08lx\n", hr);
1489
1491 ok(hr == S_OK, "got %08lx\n", hr);
1492 InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
1493 hr = IDataObject_GetData(get, &fmt, &med);
1494 ok(hr == S_OK, "got %08lx\n", hr);
1495 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1496 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1497 IDataObject_Release(get);
1498
1500 ok(hr == S_OK, "got %08lx\n", hr);
1501
1503 ok(hr == S_OK, "got %08lx\n", hr);
1504
1505 InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
1506 hr = IDataObject_GetData(get, &fmt, &med);
1507 ok(hr == S_OK, "got %08lx\n", hr);
1508 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1509 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1510
1511 InitFormatEtc(fmt, CF_TEXT, 0xffff);
1512 hr = IDataObject_GetData(get, &fmt, &med);
1513 ok(hr == S_OK, "got %08lx\n", hr);
1514 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1515 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1516
1517 IDataObject_Release(get);
1518 IDataObject_Release(src);
1519
1521}
1522
1524{
1526 char *p = GlobalLock(h);
1527 strcpy(p, "test");
1528 GlobalUnlock(h);
1529 return h;
1530}
1531
1532static HENHMETAFILE create_emf(void)
1533{
1534 const RECT rect = {0, 0, 100, 100};
1535 HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
1536 ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
1537 return CloseEnhMetaFile(hdc);
1538}
1539
1540static HDROP create_dropped_file(void)
1541{
1542 WCHAR path[] = L"C:\\testfile1\0";
1543 DROPFILES *dropfiles;
1544 DWORD offset;
1545 HDROP hdrop;
1546
1547 offset = sizeof(DROPFILES);
1548 hdrop = GlobalAlloc(GHND, offset + sizeof(path));
1549 dropfiles = GlobalLock(hdrop);
1550 dropfiles->pFiles = offset;
1551 dropfiles->fWide = TRUE;
1552 memcpy((char *)dropfiles + offset, path, sizeof(path));
1553 GlobalUnlock(hdrop);
1554
1555 return hdrop;
1556}
1557
1558static void test_nonole_clipboard(void)
1559{
1560 HRESULT hr;
1561 BOOL r;
1563 IEnumFORMATETC *enum_fmt;
1564 FORMATETC fmt;
1565 HGLOBAL h, hblob, htext, hstorage;
1566 HENHMETAFILE emf;
1567 STGMEDIUM med;
1568 DWORD obj_type;
1569 HDROP hdrop;
1570
1571 r = OpenClipboard(NULL);
1572 ok(r, "gle %ld\n", GetLastError());
1573 r = EmptyClipboard();
1574 ok(r, "gle %ld\n", GetLastError());
1575 r = CloseClipboard();
1576 ok(r, "gle %ld\n", GetLastError());
1577
1579
1580 /* empty clipboard */
1582 ok(hr == S_OK, "got %08lx\n", hr);
1583 hr = IDataObject_EnumFormatEtc(get, DATADIR_GET, &enum_fmt);
1584 ok(hr == S_OK, "got %08lx\n", hr);
1585
1586 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1587 ok(hr == S_FALSE, "got %08lx\n", hr);
1588 IEnumFORMATETC_Release(enum_fmt);
1589
1590 IDataObject_Release(get);
1591
1592 /* set a user defined clipboard type */
1593
1594 htext = create_text();
1596 emf = create_emf();
1597 hstorage = create_storage();
1598 hdrop = create_dropped_file();
1599
1600 r = OpenClipboard(NULL);
1601 ok(r, "gle %ld\n", GetLastError());
1602 h = SetClipboardData(CF_TEXT, htext);
1603 ok(h == htext, "got %p\n", h);
1604 h = SetClipboardData(cf_onemore, hblob);
1605 ok(h == hblob, "got %p\n", h);
1607 ok(h == emf, "got %p\n", h);
1608 h = SetClipboardData(cf_storage, hstorage);
1609 ok(h == hstorage, "got %p\n", h);
1610 h = SetClipboardData(CF_HDROP, hdrop);
1611 ok(h == hdrop, "got %p\n", h);
1612 r = CloseClipboard();
1613 ok(r, "gle %ld\n", GetLastError());
1614
1616 ok(hr == S_OK, "got %08lx\n", hr);
1617 hr = IDataObject_EnumFormatEtc(get, DATADIR_GET, &enum_fmt);
1618 ok(hr == S_OK, "got %08lx\n", hr);
1619 if (FAILED(hr))
1620 {
1621 skip("EnumFormatEtc failed, skipping tests.\n");
1622 return;
1623 }
1624
1625 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1626 ok(hr == S_OK, "got %08lx\n", hr);
1627 ok(fmt.cfFormat == CF_TEXT, "cf %04x\n", fmt.cfFormat);
1628 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1629 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1630 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1631 ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1632
1633 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1634 ok(hr == S_OK, "got %08lx\n", hr);
1635 ok(fmt.cfFormat == cf_onemore, "cf %04x\n", fmt.cfFormat);
1636 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1637 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1638 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1639 ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1640
1641 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1642 ok(hr == S_OK, "got %08lx\n", hr);
1643 ok(fmt.cfFormat == CF_ENHMETAFILE, "cf %04x\n", fmt.cfFormat);
1644 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1645 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1646 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1647 ok(fmt.tymed == TYMED_ENHMF, "tymed %lx\n", fmt.tymed);
1648
1649 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1650 ok(hr == S_OK, "got %08lx\n", hr);
1651 ok(fmt.cfFormat == cf_storage, "cf %04x\n", fmt.cfFormat);
1652 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1653 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1654 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1655 ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1656
1657 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1658 ok(hr == S_OK, "got %08lx\n", hr);
1659 ok(fmt.cfFormat == CF_HDROP, "cf %04x\n", fmt.cfFormat);
1660 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1661 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1662 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1663 ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1664
1665 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1666 ok(hr == S_OK, "got %08lx\n", hr); /* User32 adds some synthesised formats */
1667
1668 ok(fmt.cfFormat == CF_LOCALE, "cf %04x\n", fmt.cfFormat);
1669 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1670 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1671 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1672 todo_wine ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1673
1674 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1675 ok(hr == S_OK, "got %08lx\n", hr);
1676
1677 ok(fmt.cfFormat == CF_OEMTEXT, "cf %04x\n", fmt.cfFormat);
1678 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1679 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1680 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1681 ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1682
1683 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1684 ok(hr == S_OK, "got %08lx\n", hr);
1685 ok(fmt.cfFormat == CF_UNICODETEXT, "cf %04x\n", fmt.cfFormat);
1686 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1687 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1688 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1689 ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %lx\n", fmt.tymed);
1690
1691 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1692 ok(hr == S_OK, "got %08lx\n", hr);
1693 ok(fmt.cfFormat == CF_METAFILEPICT, "cf %04x\n", fmt.cfFormat);
1694 ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1695 ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %lx\n", fmt.dwAspect);
1696 ok(fmt.lindex == -1, "lindex %ld\n", fmt.lindex);
1697 ok(fmt.tymed == TYMED_MFPICT, "tymed %lx\n", fmt.tymed);
1698
1699 hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1700 ok(hr == S_FALSE, "got %08lx\n", hr);
1701 IEnumFORMATETC_Release(enum_fmt);
1702
1703 InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF);
1704 hr = IDataObject_GetData(get, &fmt, &med);
1705 ok(hr == S_OK, "got %08lx\n", hr);
1706 obj_type = GetObjectType(med.hEnhMetaFile);
1707 ok(obj_type == OBJ_ENHMETAFILE, "got %ld\n", obj_type);
1708 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1709
1710 InitFormatEtc(fmt, cf_storage, TYMED_ISTORAGE);
1711 hr = IDataObject_GetData(get, &fmt, &med);
1712 ok(hr == S_OK, "got %08lx\n", hr);
1713 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1714 if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1715
1716 IDataObject_Release(get);
1717
1718 r = OpenClipboard(NULL);
1719 ok(r, "gle %ld\n", GetLastError());
1720 r = EmptyClipboard();
1721 ok(r, "gle %ld\n", GetLastError());
1722 r = CloseClipboard();
1723 ok(r, "gle %ld\n", GetLastError());
1724
1726}
1727
1728static void test_getdatahere(void)
1729{
1730 HRESULT hr;
1731 IDataObject *src, *get;
1732 FORMATETC fmt;
1733 STGMEDIUM med;
1734
1736
1738 ok(hr == S_OK, "got %08lx\n", hr);
1739
1741 ok(hr == S_OK, "got %08lx\n", hr);
1742
1744 ok(hr == S_OK, "got %08lx\n", hr);
1745
1746 /* global format -> global & stream */
1747
1750
1751 InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
1752
1753 med.pUnkForRelease = NULL;
1754 med.tymed = TYMED_HGLOBAL;
1755 med.hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
1756 hr = IDataObject_GetDataHere(get, &fmt, &med);
1757 ok(hr == S_OK, "got %08lx\n", hr);
1758 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1759 ReleaseStgMedium(&med);
1762
1764
1765 med.pUnkForRelease = NULL;
1766 med.tymed = TYMED_HGLOBAL;
1767 med.hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
1768 hr = IDataObject_GetDataHere(get, &fmt, &med);
1769 ok(hr == S_OK, "got %08lx\n", hr);
1770 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1771 ReleaseStgMedium(&med);
1774
1775 med.pUnkForRelease = NULL;
1776 med.tymed = TYMED_HGLOBAL;
1777 med.hGlobal = GlobalAlloc(GMEM_MOVEABLE, 1);
1778 hr = IDataObject_GetDataHere(get, &fmt, &med);
1779 ok(hr == E_FAIL, "got %08lx\n", hr);
1780 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1781 ReleaseStgMedium(&med);
1784
1785 med.pUnkForRelease = NULL;
1786 med.tymed = TYMED_ISTREAM;
1787 CreateStreamOnHGlobal(NULL, TRUE, &med.pstm);
1788 hr = IDataObject_GetDataHere(get, &fmt, &med);
1789 ok(hr == S_OK, "got %08lx\n", hr);
1790 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1791 ReleaseStgMedium(&med);
1794
1795 med.pUnkForRelease = NULL;
1796 med.tymed = TYMED_ISTORAGE;
1798 hr = IDataObject_GetDataHere(get, &fmt, &med);
1799 ok(hr == E_FAIL, "got %08lx\n", hr);
1800 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1801 ReleaseStgMedium(&med);
1804
1806
1807 med.pUnkForRelease = NULL;
1808 med.tymed = TYMED_HGLOBAL;
1809 med.hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
1810 hr = IDataObject_GetDataHere(get, &fmt, &med);
1811 ok(hr == S_OK, "got %08lx\n", hr);
1812 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1813 ReleaseStgMedium(&med);
1816
1817 med.pUnkForRelease = NULL;
1818 med.tymed = TYMED_ISTREAM;
1819 CreateStreamOnHGlobal(NULL, TRUE, &med.pstm);
1820 hr = IDataObject_GetDataHere(get, &fmt, &med);
1821 ok(hr == S_OK, "got %08lx\n", hr);
1822 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1823 ReleaseStgMedium(&med);
1826
1827 med.pUnkForRelease = NULL;
1828 med.tymed = TYMED_ISTORAGE;
1830 hr = IDataObject_GetDataHere(get, &fmt, &med);
1831 ok(hr == E_FAIL, "got %08lx\n", hr);
1832 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1833 ReleaseStgMedium(&med);
1836
1838
1839 med.pUnkForRelease = NULL;
1840 med.tymed = TYMED_HGLOBAL;
1841 med.hGlobal = GlobalAlloc(GMEM_MOVEABLE, 3000);
1842 hr = IDataObject_GetDataHere(get, &fmt, &med);
1843 ok(hr == S_OK, "got %08lx\n", hr);
1844 ok(med.tymed == TYMED_HGLOBAL, "got %lx\n", med.tymed);
1845 ReleaseStgMedium(&med);
1848
1849 med.pUnkForRelease = NULL;
1850 med.tymed = TYMED_ISTREAM;
1851 CreateStreamOnHGlobal(NULL, TRUE, &med.pstm);
1852 hr = IDataObject_GetDataHere(get, &fmt, &med);
1853 ok(hr == S_OK, "got %08lx\n", hr);
1854 ok(med.tymed == TYMED_ISTREAM, "got %lx\n", med.tymed);
1855 ReleaseStgMedium(&med);
1858
1859 med.pUnkForRelease = NULL;
1860 med.tymed = TYMED_ISTORAGE;
1862 hr = IDataObject_GetDataHere(get, &fmt, &med);
1863 ok(hr == S_OK, "got %08lx\n", hr);
1864 ok(med.tymed == TYMED_ISTORAGE, "got %lx\n", med.tymed);
1865 ReleaseStgMedium(&med);
1868
1869
1870 IDataObject_Release(get);
1871 IDataObject_Release(src);
1872
1874
1875}
1876
1878{
1879 IDataObject *data_obj = arg;
1880
1881 IDataObject_Release(data_obj);
1882 return 0;
1883}
1884
1886{
1887 IDataObject *data_obj;
1888 HANDLE thread;
1889 HRESULT hr;
1890 DWORD ret;
1891
1893
1894 hr = OleGetClipboard(&data_obj);
1895 ok(hr == S_OK, "OleGetClipboard returned %lx\n", hr);
1896
1897 thread = CreateThread(NULL, 0, test_data_obj, data_obj, 0, NULL);
1898 ok(thread != NULL, "CreateThread failed (%ld)\n", GetLastError());
1900 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %lx\n", ret);
1901
1902 hr = OleGetClipboard(&data_obj);
1903 ok(hr == S_OK, "OleGetClipboard returned %lx\n", hr);
1904 IDataObject_Release(data_obj);
1905
1907}
1908
1910{
1911 HRESULT hr;
1912 IDataObject *pDObj;
1913
1915
1916 pDObj = (IDataObject *)0xdeadbeef;
1917 /* lock clipboard */
1919 hr = OleGetClipboard(&pDObj);
1920 todo_wine ok(hr == CLIPBRD_E_CANT_OPEN, "OleGetClipboard() got 0x%08lx instead of 0x%08lx\n", hr, CLIPBRD_E_CANT_OPEN);
1921 todo_wine ok(pDObj == NULL, "OleGetClipboard() got 0x%p instead of NULL\n",pDObj);
1922 if (pDObj) IDataObject_Release(pDObj);
1924
1926}
1927
1928START_TEST(clipboard)
1929{
1939}
#define CO_E_NOTINITIALIZED
static POBJECT_TYPE GetObjectType(IN PCWSTR TypeName)
Definition: ObTypes.c:15
#define stat
Definition: acwin.h:99
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_METAFILEPICT
Definition: constants.h:398
#define CF_WAVE
Definition: constants.h:407
#define CF_HDROP
Definition: constants.h:410
#define CF_LOCALE
Definition: constants.h:411
#define CF_ENHMETAFILE
Definition: constants.h:409
#define CF_TEXT
Definition: constants.h:396
#define CF_RIFF
Definition: constants.h:406
#define CF_OEMTEXT
Definition: constants.h:402
void get(int argc, const char *argv[])
Definition: cmds.c:480
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
static LPVOID LPUNKNOWN
Definition: dinput.c:53
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
HANDLE HWND
Definition: compat.h:19
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
const WCHAR * text
Definition: package.c:1794
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
HRESULT WINAPI OleIsCurrentClipboard(IDataObject *data)
Definition: clipboard.c:2329
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2192
static snapshot * impl_from_IDataObject(IDataObject *iface)
Definition: clipboard.c:157
static const char * dump_fmtetc(FORMATETC *fmt)
Definition: clipboard.c:275
static enum_fmtetc * impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
Definition: clipboard.c:296
HRESULT WINAPI OleFlushClipboard(void)
Definition: clipboard.c:2290
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2246
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:162
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2014
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:218
HRESULT WINAPI StgCreateDocfileOnILockBytes(ILockBytes *plkbyt, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8891
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8597
struct EnumFormatImpl EnumFormatImpl
static ULONG WINAPI EnumFormatImpl_AddRef(IEnumFORMATETC *iface)
Definition: clipboard.c:74
static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
Definition: clipboard.c:239
static ULONG WINAPI DataObjectImpl_AddRef(IDataObject *iface)
Definition: clipboard.c:191
static HRESULT WINAPI EnumFormatImpl_Skip(IEnumFORMATETC *iface, ULONG celt)
Definition: clipboard.c:116
static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc)
static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
Definition: clipboard.c:82
static const IDataObjectVtbl VT_DataObjectImpl
Definition: clipboard.c:324
static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject *iface, FORMATETC *pformatetc)
Definition: clipboard.c:246
static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
Definition: clipboard.c:96
static HRESULT WINAPI DataObjectImpl_DAdvise(IDataObject *iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
Definition: clipboard.c:302
static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, LPVOID *ppvObj)
Definition: clipboard.c:177
static HRESULT WINAPI DataObjectImpl_DUnadvise(IDataObject *iface, DWORD dwConnection)
Definition: clipboard.c:310
static HRESULT WINAPI DataObjectImpl_EnumFormatEtc(IDataObject *iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
Definition: clipboard.c:287
static ULONG WINAPI DataObjectImpl_Release(IDataObject *iface)
Definition: clipboard.c:199
static HRESULT WINAPI DataObjectImpl_GetData(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
Definition: clipboard.c:215
static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject *iface, FORMATETC *pformatetcIn, FORMATETC *pformatetcOut)
Definition: clipboard.c:266
static HRESULT WINAPI EnumFormatImpl_Clone(IEnumFORMATETC *iface, IEnumFORMATETC **ppenum)
Definition: clipboard.c:136
static HRESULT WINAPI DataObjectImpl_EnumDAdvise(IDataObject *iface, IEnumSTATDATA **ppenumAdvise)
Definition: clipboard.c:317
static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFIID riid, LPVOID *ppvObj)
Definition: clipboard.c:60
static HRESULT WINAPI DataObjectImpl_SetData(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
Definition: clipboard.c:279
static HRESULT WINAPI EnumFormatImpl_Reset(IEnumFORMATETC *iface)
Definition: clipboard.c:127
struct DataObjectImpl DataObjectImpl
static const IEnumFORMATETCVtbl VT_EnumFormatImpl
Definition: clipboard.c:150
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define d
Definition: ke_i.h:81
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes *iface, HGLOBAL *phglobal)
Definition: memlockbytes.c:143
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL global, BOOL delete_on_release, ILockBytes **ret)
Definition: memlockbytes.c:96
int winetest_debug
#define win_skip
Definition: minitest.h:67
#define todo_wine
Definition: minitest.h:80
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
static struct fmt fmts[]
static LPDATAOBJECT clip_data
Definition: clipboard.c:1049
static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
Definition: clipboard.c:436
static UINT wm_drawclipboard
Definition: clipboard.c:1051
static HGLOBAL create_text(void)
Definition: clipboard.c:1523
static ULONG DataObjectImpl_GetData_calls
Definition: clipboard.c:77
static const char * cmpl_stm_data
Definition: clipboard.c:444
static void test_nonole_clipboard(void)
Definition: clipboard.c:1558
static HMETAFILE create_mf(void)
Definition: clipboard.c:85
static UINT cf_onemore
Definition: clipboard.c:81
static void test_cf_dataobject(IDataObject *data)
Definition: clipboard.c:729
static HGLOBAL create_storage(void)
Definition: clipboard.c:1316
static HENHMETAFILE create_emf(void)
Definition: clipboard.c:1532
static ULONG DataObjectImpl_EnumFormatEtc_calls
Definition: clipboard.c:79
static void test_enum_fmtetc(IDataObject *src)
Definition: clipboard.c:623
static void test_consumer_refs(void)
Definition: clipboard.c:1153
static const WCHAR device_name[]
Definition: clipboard.c:446
static HRESULT DataObjectImpl_CreateFromHGlobal(HGLOBAL text, LPDATAOBJECT *dataobj)
Definition: clipboard.c:416
static BOOL expect_DataObjectImpl_QueryGetData
Definition: clipboard.c:76
static DWORD CALLBACK test_data_obj(void *arg)
Definition: clipboard.c:1877
static const char * cmpl_text_data
Definition: clipboard.c:445
static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
Definition: clipboard.c:448
static UINT cf_storage
Definition: clipboard.c:81
static void test_no_cf_dataobject(void)
Definition: clipboard.c:714
static UINT cf_another
Definition: clipboard.c:81
static void test_getdatahere(void)
Definition: clipboard.c:1728
static void test_get_clipboard_locked(void)
Definition: clipboard.c:1909
static void test_complex_get_clipboard(void)
Definition: clipboard.c:883
static UINT cf_stream
Definition: clipboard.c:81
static void test_multithreaded_clipboard(void)
Definition: clipboard.c:1885
static void test_get_clipboard(void)
Definition: clipboard.c:528
static UINT cf_global
Definition: clipboard.c:81
static ULONG count_refs(IDataObject *d)
Definition: clipboard.c:1147
static void test_set_clipboard_DRAWCLIPBOARD(void)
Definition: clipboard.c:1093
static void test_flushed_getdata(void)
Definition: clipboard.c:1334
static void test_set_clipboard(void)
Definition: clipboard.c:921
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: clipboard.c:1053
static DWORD CALLBACK set_clipboard_thread(void *arg)
Definition: clipboard.c:1083
static void test_get_clipboard_uninitialized(void)
Definition: clipboard.c:503
static HWND next_wnd
Definition: clipboard.c:1050
static ULONG DataObjectImpl_GetDataHere_calls
Definition: clipboard.c:78
static HMETAFILEPICT create_metafilepict(void)
Definition: clipboard.c:93
static HDROP create_dropped_file(void)
Definition: clipboard.c:1540
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define STGM_CREATE
Definition: objbase.h:943
#define STGM_READWRITE
Definition: objbase.h:936
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:940
#define STGM_DELETEONRELEASE
Definition: objbase.h:942
interface IEnumFORMATETC * LPENUMFORMATETC
Definition: objfwd.h:24
interface IDataObject * LPDATAOBJECT
Definition: objfwd.h:21
#define OBJ_ENHMETAFILE
Definition: objidl.idl:1026
const GUID IID_IEnumFORMATETC
const GUID IID_IDataObject
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define calloc
Definition: rosglue.h:14
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
struct _DROPFILES DROPFILES
& rect
Definition: startmenu.cpp:1413
HMETAFILEPICT hmfp
Definition: clipboard.c:63
IStorage * stg
Definition: clipboard.c:62
HANDLE text
Definition: clipboard.c:60
IStream * stm
Definition: clipboard.c:61
FORMATETC * fmtetc
Definition: clipboard.c:31
IDataObject IDataObject_iface
Definition: clipboard.c:28
UINT fmtetc_cnt
Definition: clipboard.c:32
IEnumFORMATETC IEnumFORMATETC_iface
Definition: clipboard.c:39
FORMATETC * fmtetc
Definition: clipboard.c:42
UINT fmtetc_cnt
Definition: clipboard.c:43
DWORD pFiles
Definition: shlobj.h:2315
BOOL fWide
Definition: shlobj.h:2318
HINSTANCE hInstance
Definition: winuser.h:3269
LPCSTR lpszClassName
Definition: winuser.h:3274
WNDPROC lpfnWndProc
Definition: winuser.h:3266
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:2063
WORD dmDriverExtra
Definition: wingdi.h:2067
WORD dmSize
Definition: wingdi.h:2066
Definition: tftpd.h:126
Definition: tftpd.h:138
Definition: emfdc.c:45
Definition: dsound.c:943
IDataObject IDataObject_iface
Definition: usrmarshal.c:1273
Definition: send.c:48
Definition: stat.h:66
HMETAFILE hMF
Definition: wingdi.h:3054
Definition: tools.h:99
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define DWORD_PTR
Definition: treelist.c:76
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GMEM_ZEROINIT
Definition: winbase.h:330
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define GHND
Definition: winbase.h:321
#define GMEM_MOVEABLE
Definition: winbase.h:318
#define GMEM_DDESHARE
Definition: winbase.h:322
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
_In_ FONTOBJ _In_ ULONG _In_ HGLYPH hg
Definition: winddi.h:3871
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define DV_E_TYMED
Definition: winerror.h:3749
#define DV_E_CLIPFORMAT
Definition: winerror.h:3750
#define CLIPBRD_E_CANT_OPEN
Definition: winerror.h:3880
#define DV_E_FORMATETC
Definition: winerror.h:3744
#define DV_E_LINDEX
Definition: winerror.h:3748
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
HDC WINAPI CreateMetaFileA(_In_opt_ LPCSTR)
#define MM_ANISOTROPIC
Definition: wingdi.h:867
HMETAFILE WINAPI CloseMetaFile(_In_ HDC hdc)
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
HDC WINAPI CreateEnhMetaFileA(_In_opt_ HDC, _In_opt_ LPCSTR, _In_opt_ LPCRECT, _In_opt_ LPCSTR)
#define ETO_OPAQUE
Definition: wingdi.h:647
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4417
#define WM_DRAWCLIPBOARD
Definition: winuser.h:1897
HANDLE WINAPI SetClipboardData(_In_ UINT, _In_opt_ HANDLE)
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
HWND WINAPI GetClipboardOwner(void)
Definition: ntwrapper.h:196
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
UINT WINAPI EnumClipboardFormats(_In_ UINT)
#define WM_CHANGECBCHAIN
Definition: winuser.h:1902
HANDLE WINAPI GetClipboardData(_In_ UINT)
HWND WINAPI SetClipboardViewer(_In_ HWND)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
BOOL WINAPI ChangeClipboardChain(_In_ HWND, _In_ HWND)
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
#define WM_USER
Definition: winuser.h:1923
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
BOOL WINAPI DestroyWindow(_In_ HWND)
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180