hlink: Add a missing prototype and update win32.api to fix the winapi_check warnings.
[wine/testsucceed.git] / dlls / ole32 / tests / clipboard.c
blob0127ce5e44cc7e5050242a9e2185cbb89b345cb2
1 /*
2 * Clipboard unit tests
4 * Copyright 2006 Kevin Koltzau
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.
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.
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
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
29 #include "wine/test.h"
31 #define InitFormatEtc(fe, cf, med) \
33 (fe).cfFormat=cf;\
34 (fe).dwAspect=DVASPECT_CONTENT;\
35 (fe).ptd=NULL;\
36 (fe).tymed=med;\
37 (fe).lindex=-1;\
40 typedef struct DataObjectImpl {
41 const IDataObjectVtbl *lpVtbl;
42 LONG ref;
44 FORMATETC *fmtetc;
45 UINT fmtetc_cnt;
47 HANDLE text;
48 } DataObjectImpl;
50 typedef struct EnumFormatImpl {
51 const IEnumFORMATETCVtbl *lpVtbl;
52 LONG ref;
54 FORMATETC *fmtetc;
55 UINT fmtetc_cnt;
57 UINT cur;
58 } EnumFormatImpl;
60 static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);
62 static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFIID riid, LPVOID *ppvObj)
64 EnumFormatImpl *This = (EnumFormatImpl*)iface;
66 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumFORMATETC)) {
67 IEnumFORMATETC_AddRef(iface);
68 *ppvObj = (LPVOID)This;
69 return S_OK;
71 *ppvObj = NULL;
72 return E_NOINTERFACE;
75 static ULONG WINAPI EnumFormatImpl_AddRef(IEnumFORMATETC *iface)
77 EnumFormatImpl *This = (EnumFormatImpl*)iface;
78 LONG ref = InterlockedIncrement(&This->ref);
79 return ref;
82 static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
84 EnumFormatImpl *This = (EnumFormatImpl*)iface;
85 ULONG ref = InterlockedDecrement(&This->ref);
87 if(!ref) {
88 HeapFree(GetProcessHeap(), 0, This->fmtetc);
89 HeapFree(GetProcessHeap(), 0, This);
92 return ref;
95 static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt,
96 FORMATETC *rgelt, ULONG *pceltFetched)
98 EnumFormatImpl *This = (EnumFormatImpl*)iface;
99 ULONG count = 0;
101 if(!rgelt)
102 return E_INVALIDARG;
104 count = min(celt, This->fmtetc_cnt-This->cur);
105 if(count > 0) {
106 memcpy(rgelt, This->fmtetc+This->cur, count*sizeof(FORMATETC));
107 This->cur += count;
109 if(pceltFetched)
110 *pceltFetched = count;
111 return count == celt ? S_OK : S_FALSE;
114 static HRESULT WINAPI EnumFormatImpl_Skip(IEnumFORMATETC *iface, ULONG celt)
116 ok(0, "unexpected call\n");
117 return E_NOTIMPL;
120 static HRESULT WINAPI EnumFormatImpl_Reset(IEnumFORMATETC *iface)
122 EnumFormatImpl *This = (EnumFormatImpl*)iface;
124 This->cur = 0;
125 return S_OK;
128 static HRESULT WINAPI EnumFormatImpl_Clone(IEnumFORMATETC *iface, IEnumFORMATETC **ppenum)
130 ok(0, "unexpected call\n");
131 return E_NOTIMPL;
134 static const IEnumFORMATETCVtbl VT_EnumFormatImpl = {
135 EnumFormatImpl_QueryInterface,
136 EnumFormatImpl_AddRef,
137 EnumFormatImpl_Release,
138 EnumFormatImpl_Next,
139 EnumFormatImpl_Skip,
140 EnumFormatImpl_Reset,
141 EnumFormatImpl_Clone
144 static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFORMATETC **lplpformatetc)
146 EnumFormatImpl *ret;
148 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumFormatImpl));
149 ret->lpVtbl = &VT_EnumFormatImpl;
150 ret->ref = 1;
151 ret->cur = 0;
152 ret->fmtetc_cnt = fmtetc_cnt;
153 ret->fmtetc = HeapAlloc(GetProcessHeap(), 0, fmtetc_cnt*sizeof(FORMATETC));
154 memcpy(ret->fmtetc, fmtetc, fmtetc_cnt*sizeof(FORMATETC));
155 *lplpformatetc = (LPENUMFORMATETC)ret;
156 return S_OK;
159 static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, LPVOID *ppvObj)
161 DataObjectImpl *This = (DataObjectImpl*)iface;
163 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject)) {
164 IDataObject_AddRef(iface);
165 *ppvObj = (LPVOID)This;
166 return S_OK;
168 *ppvObj = NULL;
169 return E_NOINTERFACE;
172 static ULONG WINAPI DataObjectImpl_AddRef(IDataObject* iface)
174 DataObjectImpl *This = (DataObjectImpl*)iface;
175 ULONG ref = InterlockedIncrement(&This->ref);
176 return ref;
179 static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
181 DataObjectImpl *This = (DataObjectImpl*)iface;
182 ULONG ref = InterlockedDecrement(&This->ref);
184 if(!ref) {
185 if(This->text) GlobalFree(This->text);
186 if(This->fmtetc) GlobalFree(This->fmtetc);
187 HeapFree(GetProcessHeap(), 0, This);
190 return ref;
193 static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
195 DataObjectImpl *This = (DataObjectImpl*)iface;
197 if(pformatetc->lindex != -1)
198 return DV_E_LINDEX;
200 if(!(pformatetc->tymed & TYMED_HGLOBAL))
201 return DV_E_TYMED;
203 if(This->text && pformatetc->cfFormat == CF_TEXT)
204 U(*pmedium).hGlobal = This->text;
205 else
206 return DV_E_FORMATETC;
208 pmedium->tymed = TYMED_HGLOBAL;
209 pmedium->pUnkForRelease = (LPUNKNOWN)iface;
210 IUnknown_AddRef(pmedium->pUnkForRelease);
211 return S_OK;
214 static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
216 ok(0, "unexpected call\n");
217 return E_NOTIMPL;
220 static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC *pformatetc)
222 DataObjectImpl *This = (DataObjectImpl*)iface;
223 UINT i;
224 BOOL foundFormat = FALSE;
226 if(pformatetc->lindex != -1)
227 return DV_E_LINDEX;
229 for(i=0; i<This->fmtetc_cnt; i++) {
230 if(This->fmtetc[i].cfFormat == pformatetc->cfFormat) {
231 foundFormat = TRUE;
232 if(This->fmtetc[i].tymed == pformatetc->tymed)
233 return S_OK;
236 return foundFormat?DV_E_FORMATETC:DV_E_TYMED;
239 static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject* iface, FORMATETC *pformatectIn,
240 FORMATETC *pformatetcOut)
242 ok(0, "unexpected call\n");
243 return E_NOTIMPL;
246 static HRESULT WINAPI DataObjectImpl_SetData(IDataObject* iface, FORMATETC *pformatetc,
247 STGMEDIUM *pmedium, BOOL fRelease)
249 ok(0, "unexpected call\n");
250 return E_NOTIMPL;
253 static HRESULT WINAPI DataObjectImpl_EnumFormatEtc(IDataObject* iface, DWORD dwDirection,
254 IEnumFORMATETC **ppenumFormatEtc)
256 DataObjectImpl *This = (DataObjectImpl*)iface;
258 if(dwDirection != DATADIR_GET) {
259 ok(0, "unexpected direction %d\n", dwDirection);
260 return E_NOTIMPL;
262 return EnumFormatImpl_Create(This->fmtetc, This->fmtetc_cnt, ppenumFormatEtc);
265 static HRESULT WINAPI DataObjectImpl_DAdvise(IDataObject* iface, FORMATETC *pformatetc, DWORD advf,
266 IAdviseSink *pAdvSink, DWORD *pdwConnection)
268 ok(0, "unexpected call\n");
269 return E_NOTIMPL;
272 static HRESULT WINAPI DataObjectImpl_DUnadvise(IDataObject* iface, DWORD dwConnection)
274 ok(0, "unexpected call\n");
275 return E_NOTIMPL;
278 static HRESULT WINAPI DataObjectImpl_EnumDAdvise(IDataObject* iface, IEnumSTATDATA **ppenumAdvise)
280 ok(0, "unexpected call\n");
281 return E_NOTIMPL;
284 static const IDataObjectVtbl VT_DataObjectImpl =
286 DataObjectImpl_QueryInterface,
287 DataObjectImpl_AddRef,
288 DataObjectImpl_Release,
289 DataObjectImpl_GetData,
290 DataObjectImpl_GetDataHere,
291 DataObjectImpl_QueryGetData,
292 DataObjectImpl_GetCanonicalFormatEtc,
293 DataObjectImpl_SetData,
294 DataObjectImpl_EnumFormatEtc,
295 DataObjectImpl_DAdvise,
296 DataObjectImpl_DUnadvise,
297 DataObjectImpl_EnumDAdvise
300 static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
302 DataObjectImpl *obj;
304 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
305 obj->lpVtbl = &VT_DataObjectImpl;
306 obj->ref = 1;
307 obj->text = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
308 strcpy(GlobalLock(obj->text), text);
309 GlobalUnlock(obj->text);
311 obj->fmtetc_cnt = 1;
312 obj->fmtetc = HeapAlloc(GetProcessHeap(), 0, obj->fmtetc_cnt*sizeof(FORMATETC));
313 InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
315 *lplpdataobj = (LPDATAOBJECT)obj;
316 return S_OK;
319 static void test_set_clipboard(void)
321 HRESULT hr;
322 ULONG ref;
323 LPDATAOBJECT data1, data2;
324 hr = DataObjectImpl_CreateText("data1", &data1);
325 ok(SUCCEEDED(hr), "Failed to create data1 object: 0x%08x\n", hr);
326 if(FAILED(hr))
327 return;
328 hr = DataObjectImpl_CreateText("data2", &data2);
329 ok(SUCCEEDED(hr), "Failed to create data2 object: 0x%08x\n", hr);
330 if(FAILED(hr))
331 return;
333 hr = OleSetClipboard(data1);
334 todo_wine
335 ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard should have failed with CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
337 CoInitialize(NULL);
338 hr = OleSetClipboard(data1);
339 todo_wine
340 ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard should have failed with CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
341 CoUninitialize();
343 hr = OleInitialize(NULL);
344 ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
346 hr = OleSetClipboard(data1);
347 ok(hr == S_OK, "failed to set clipboard to data1, hr = 0x%08x\n", hr);
348 hr = OleIsCurrentClipboard(data1);
349 ok(hr == S_OK, "expected current clipboard to be data1, hr = 0x%08x\n", hr);
350 hr = OleIsCurrentClipboard(data2);
351 ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08x\n", hr);
353 hr = OleSetClipboard(data2);
354 ok(hr == S_OK, "failed to set clipboard to data2, hr = 0x%08x\n", hr);
355 hr = OleIsCurrentClipboard(data1);
356 ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08x\n", hr);
357 hr = OleIsCurrentClipboard(data2);
358 ok(hr == S_OK, "expected current clipboard to be data2, hr = 0x%08x\n", hr);
360 hr = OleFlushClipboard();
361 ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
362 hr = OleIsCurrentClipboard(data1);
363 ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08x\n", hr);
364 hr = OleIsCurrentClipboard(data2);
365 ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08x\n", hr);
367 ok(OleSetClipboard(NULL) == S_OK, "failed to clear clipboard, hr = 0x%08x\n", hr);
369 ref = IDataObject_Release(data1);
370 ok(ref == 0, "expected data1 ref=0, got %d\n", ref);
371 ref = IDataObject_Release(data2);
372 ok(ref == 0, "expected data2 ref=0, got %d\n", ref);
374 OleUninitialize();
378 START_TEST(clipboard)
380 test_set_clipboard();