4 * Copyright 2007 Robert Shearman
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
32 #include "wine/test.h"
36 METHOD(DO_EnumFormatEtc), \
37 METHOD(DO_QueryGetData), \
38 METHOD(EnumFMT_Next), \
39 METHOD(EnumFMT_Reset), \
40 METHOD(EnumFMT_Skip), \
41 METHOD(DS_QueryContinueDrag), \
42 METHOD(DS_GiveFeedback), \
43 METHOD(DT_DragEnter), \
45 METHOD(DT_DragLeave), \
46 METHOD(DT_DragOver), \
47 METHOD(DoDragDrop_effect_in), \
48 METHOD(DoDragDrop_ret), \
49 METHOD(DoDragDrop_effect_out), \
60 static const char *method_names
[] =
78 const struct method_call
*call_ptr
;
80 static HRESULT
check_expect_(enum method func
, DWORD expect_param
, DWORD
*set_param
, const char *file
, int line
)
86 todo_wine_if(call_ptr
->called_todo
)
87 ok_( file
, line
)( func
== call_ptr
->method
, "unexpected call %s instead of %s\n",
88 method_names
[func
], method_names
[call_ptr
->method
] );
89 if (call_ptr
->method
== func
) break;
90 } while ((++call_ptr
)->method
!= end_seq
);
92 ok_( file
, line
)( expect_param
== call_ptr
->expect_param
, "%s: unexpected param %08x expected %08x\n",
93 method_names
[func
], expect_param
, call_ptr
->expect_param
);
94 if (set_param
) *set_param
= call_ptr
->set_param
;
95 hr
= call_ptr
->set_ret
;
96 if (call_ptr
->method
!= end_seq
) call_ptr
++;
100 #define check_expect(func, expect_param, set_param) \
101 check_expect_((func), (expect_param), (set_param), __FILE__, __LINE__)
104 struct method_call call_lists
[][30] =
106 { /* First QueryContinueDrag rets DRAGDROP_S_DROP */
107 { DoDragDrop_effect_in
, 0, 0, DROPEFFECT_COPY
, 0 },
108 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
109 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
110 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
111 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
112 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
113 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
114 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
116 { DS_QueryContinueDrag
, 0, DRAGDROP_S_DROP
, 0, 0 },
117 { DT_DragEnter
, DROPEFFECT_COPY
, S_OK
, DROPEFFECT_COPY
, 0 },
118 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
119 { DT_Drop
, DROPEFFECT_COPY
, 0xbeefbeef, DROPEFFECT_COPY
, 0 },
121 { DoDragDrop_ret
, 0xbeefbeef, 0, 0, 0, },
122 { DoDragDrop_effect_out
, DROPEFFECT_COPY
, 0, 0, 0 },
123 { end_seq
, 0, 0, 0, 0 }
125 { /* As above, but initial effects == 0 */
126 { DoDragDrop_effect_in
, 0, 0, 0, 0 },
127 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
128 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
129 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
130 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
131 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
132 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
133 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
135 { DS_QueryContinueDrag
, 0, DRAGDROP_S_DROP
, 0, 0 },
136 { DT_DragEnter
, 0, S_OK
, DROPEFFECT_COPY
, 0 },
137 { DS_GiveFeedback
, 0, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
138 { DT_DragLeave
, 0, 0, 0, 0 },
140 { DoDragDrop_ret
, DRAGDROP_S_DROP
, 0, 0, 0 },
141 { DoDragDrop_effect_out
, 0, 0, 0, 0 },
142 { end_seq
, 0, 0, 0, 0 }
144 { /* Multiple initial effects */
145 { DoDragDrop_effect_in
, 0, 0, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0 },
146 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
147 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
148 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
149 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
150 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
151 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
152 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
154 { DS_QueryContinueDrag
, 0, DRAGDROP_S_DROP
, 0, 0 },
155 { DT_DragEnter
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
156 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
157 { DT_Drop
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0, 0, 0 },
159 { DoDragDrop_ret
, DRAGDROP_S_DROP
, 0, 0, 0 },
160 { DoDragDrop_effect_out
, 0, 0, 0, 0 },
161 { end_seq
, 0, 0, 0, 0 }
163 { /* First couple of QueryContinueDrag return S_OK followed by a drop */
164 { DoDragDrop_effect_in
, 0, 0, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0 },
165 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
166 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
167 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
168 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
169 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
170 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
171 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
173 { DS_QueryContinueDrag
, 0, S_OK
, 0, 0 },
174 { DT_DragEnter
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
175 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
176 { DT_DragOver
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
177 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
179 { DS_QueryContinueDrag
, 0, S_OK
, 0, 0 },
180 { DT_DragOver
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
181 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
183 { DS_QueryContinueDrag
, 0, DRAGDROP_S_DROP
, 0, 0 },
184 { DT_Drop
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0, 0, 0 },
186 { DoDragDrop_ret
, DRAGDROP_S_DROP
, 0, 0, 0 },
187 { DoDragDrop_effect_out
, 0, 0, 0, 0 },
188 { end_seq
, 0, 0, 0, 0 }
190 { /* First QueryContinueDrag cancels */
191 { DoDragDrop_effect_in
, 0, 0, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0 },
192 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
193 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
194 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
195 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
196 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
197 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
198 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
200 { DS_QueryContinueDrag
, 0, DRAGDROP_S_CANCEL
, 0, 0 },
202 { DoDragDrop_ret
, DRAGDROP_S_CANCEL
, 0, 0, 0 },
203 { DoDragDrop_effect_out
, 0, 0, 0, 0 },
204 { end_seq
, 0, 0, 0, 0 }
206 { /* First couple of QueryContinueDrag return S_OK followed by a cancel */
207 { DoDragDrop_effect_in
, 0, 0, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0 },
208 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
209 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
210 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
211 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
212 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
213 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
214 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
216 { DS_QueryContinueDrag
, 0, S_OK
, 0, 0 },
217 { DT_DragEnter
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
218 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
219 { DT_DragOver
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
220 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
222 { DS_QueryContinueDrag
, 0, S_OK
, 0, 0 },
223 { DT_DragOver
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
224 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
226 { DS_QueryContinueDrag
, 0, DRAGDROP_S_CANCEL
, 0, 0 },
227 { DT_DragLeave
, 0, 0, 0, 0 },
229 { DoDragDrop_ret
, DRAGDROP_S_CANCEL
, 0, 0, 0 },
230 { DoDragDrop_effect_out
, 0, 0, 0, 0 },
231 { end_seq
, 0, 0, 0, 0 }
233 { /* First couple of QueryContinueDrag return S_OK followed by a E_FAIL */
234 { DoDragDrop_effect_in
, 0, 0, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, 0 },
235 { DO_EnumFormatEtc
, 0, S_OK
, 0, 1 },
236 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
237 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
238 { EnumFMT_Reset
, 0, S_OK
, 0, 1 },
239 { EnumFMT_Next
, 0, S_OK
, 0, 1 },
240 { EnumFMT_Next
, 0, S_FALSE
, 0, 1 },
241 { DO_QueryGetData
, 0, S_OK
, 0, 1 },
243 { DS_QueryContinueDrag
, 0, S_OK
, 0, 0 },
244 { DT_DragEnter
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
245 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
246 { DT_DragOver
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
247 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
249 { DS_QueryContinueDrag
, 0, S_OK
, 0, 0 },
250 { DT_DragOver
, DROPEFFECT_COPY
| DROPEFFECT_MOVE
, S_OK
, DROPEFFECT_COPY
, 0 },
251 { DS_GiveFeedback
, DROPEFFECT_COPY
, DRAGDROP_S_USEDEFAULTCURSORS
, 0, 0 },
253 { DS_QueryContinueDrag
, 0, E_FAIL
, 0, 0 },
254 { DT_DragLeave
, 0, 0, 0, 0 },
256 { DoDragDrop_ret
, E_FAIL
, 0, 0, 0 },
257 { DoDragDrop_effect_out
, 0, 0, 0, 0 },
258 { end_seq
, 0, 0, 0, 0 }
262 static int droptarget_refs
;
264 /* helper macros to make tests a bit leaner */
265 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
267 static HRESULT WINAPI
DropTarget_QueryInterface(IDropTarget
* iface
, REFIID riid
,
270 ok(0, "DropTarget_QueryInterface() shouldn't be called\n");
271 if (IsEqualIID(riid
, &IID_IUnknown
) ||
272 IsEqualIID(riid
, &IID_IDropTarget
))
274 IDropTarget_AddRef(iface
);
279 return E_NOINTERFACE
;
282 static ULONG WINAPI
DropTarget_AddRef(IDropTarget
* iface
)
285 return droptarget_refs
;
288 static ULONG WINAPI
DropTarget_Release(IDropTarget
* iface
)
291 return droptarget_refs
;
294 static HRESULT WINAPI
DropTarget_DragEnter(IDropTarget
* iface
,
295 IDataObject
* pDataObj
,
296 DWORD grfKeyState
, POINTL pt
,
299 return check_expect(DT_DragEnter
, *pdwEffect
, pdwEffect
);
302 static HRESULT WINAPI
DropTarget_DragOver(IDropTarget
* iface
,
307 return check_expect(DT_DragOver
, *pdwEffect
, pdwEffect
);
310 static HRESULT WINAPI
DropTarget_DragLeave(IDropTarget
* iface
)
312 return check_expect(DT_DragLeave
, 0, NULL
);
315 static HRESULT WINAPI
DropTarget_Drop(IDropTarget
* iface
,
316 IDataObject
* pDataObj
, DWORD grfKeyState
,
317 POINTL pt
, DWORD
* pdwEffect
)
319 return check_expect(DT_Drop
, *pdwEffect
, pdwEffect
);
322 static const IDropTargetVtbl DropTarget_VTbl
=
324 DropTarget_QueryInterface
,
327 DropTarget_DragEnter
,
329 DropTarget_DragLeave
,
333 static IDropTarget DropTarget
= { &DropTarget_VTbl
};
335 static HRESULT WINAPI
DropSource_QueryInterface(IDropSource
*iface
, REFIID riid
, void **ppObj
)
337 if (IsEqualIID(riid
, &IID_IUnknown
) ||
338 IsEqualIID(riid
, &IID_IDropSource
))
341 IDropSource_AddRef(iface
);
344 return E_NOINTERFACE
;
347 static ULONG WINAPI
DropSource_AddRef(IDropSource
*iface
)
352 static ULONG WINAPI
DropSource_Release(IDropSource
*iface
)
357 static HRESULT WINAPI
DropSource_QueryContinueDrag(
362 return check_expect(DS_QueryContinueDrag
, 0, NULL
);
365 static HRESULT WINAPI
DropSource_GiveFeedback(
369 return check_expect(DS_GiveFeedback
, dwEffect
, NULL
);
372 static const IDropSourceVtbl dropsource_vtbl
= {
373 DropSource_QueryInterface
,
376 DropSource_QueryContinueDrag
,
377 DropSource_GiveFeedback
380 static IDropSource DropSource
= { &dropsource_vtbl
};
382 static HRESULT WINAPI
EnumFORMATETC_QueryInterface(IEnumFORMATETC
*iface
,
383 REFIID riid
, void **ppvObj
)
385 ok(0, "unexpected call\n");
389 static ULONG WINAPI
EnumFORMATETC_AddRef(IEnumFORMATETC
*iface
)
394 static ULONG WINAPI
EnumFORMATETC_Release(IEnumFORMATETC
*iface
)
399 static HRESULT WINAPI
EnumFORMATETC_Next(IEnumFORMATETC
*iface
,
400 ULONG celt
, FORMATETC
*rgelt
, ULONG
*pceltFetched
)
402 static FORMATETC format
= { CF_TEXT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
};
403 HRESULT hr
= check_expect(EnumFMT_Next
, 0, NULL
);
405 ok(celt
== 1, "celt = %d\n", celt
);
406 ok(rgelt
!= NULL
, "rgelt == NULL\n");
407 ok(pceltFetched
== NULL
, "pceltFetched != NULL\n");
413 static HRESULT WINAPI
EnumFORMATETC_Skip(IEnumFORMATETC
*iface
, ULONG celt
)
415 return check_expect(EnumFMT_Skip
, 0, NULL
);
418 static HRESULT WINAPI
EnumFORMATETC_Reset(IEnumFORMATETC
*iface
)
420 return check_expect(EnumFMT_Reset
, 0, NULL
);
423 static HRESULT WINAPI
EnumFORMATETC_Clone(IEnumFORMATETC
*iface
,
424 IEnumFORMATETC
**ppenum
)
426 ok(0, "unexpected call\n");
430 static const IEnumFORMATETCVtbl enumformatetc_vtbl
= {
431 EnumFORMATETC_QueryInterface
,
432 EnumFORMATETC_AddRef
,
433 EnumFORMATETC_Release
,
440 static IEnumFORMATETC EnumFORMATETC
= { &enumformatetc_vtbl
};
442 static HRESULT WINAPI
DataObject_QueryInterface(
447 if (IsEqualIID(riid
, &IID_IUnknown
) ||
448 IsEqualIID(riid
, &IID_IDataObject
))
451 IDataObject_AddRef(iface
);
455 trace("DataObject_QueryInterface: %s\n", wine_dbgstr_guid(riid
));
456 return E_NOINTERFACE
;
459 static ULONG WINAPI
DataObject_AddRef(IDataObject
*iface
)
464 static ULONG WINAPI
DataObject_Release(IDataObject
*iface
)
469 static HRESULT WINAPI
DataObject_GetData(
471 FORMATETC
*pformatetcIn
,
474 ok(0, "unexpected call\n");
478 static HRESULT WINAPI
DataObject_GetDataHere(
480 FORMATETC
*pformatetc
,
483 ok(0, "unexpected call\n");
487 static HRESULT WINAPI
DataObject_QueryGetData(
489 FORMATETC
*pformatetc
)
491 return check_expect(DO_QueryGetData
, 0, NULL
);
494 static HRESULT WINAPI
DataObject_GetCanonicalFormatEtc(
496 FORMATETC
*pformatectIn
,
497 FORMATETC
*pformatetcOut
)
499 ok(0, "unexpected call\n");
503 static HRESULT WINAPI
DataObject_SetData(
505 FORMATETC
*pformatetc
,
509 ok(0, "unexpected call\n");
513 static HRESULT WINAPI
DataObject_EnumFormatEtc(
516 IEnumFORMATETC
**ppenumFormatEtc
)
518 HRESULT hr
= check_expect(DO_EnumFormatEtc
, 0, NULL
);
519 *ppenumFormatEtc
= &EnumFORMATETC
;
523 static HRESULT WINAPI
DataObject_DAdvise(
525 FORMATETC
*pformatetc
,
527 IAdviseSink
*pAdvSink
,
528 DWORD
*pdwConnection
)
530 ok(0, "unexpected call\n");
534 static HRESULT WINAPI
DataObject_DUnadvise(
538 ok(0, "unexpected call\n");
542 static HRESULT WINAPI
DataObject_EnumDAdvise(
544 IEnumSTATDATA
**ppenumAdvise
)
546 ok(0, "unexpected call\n");
550 static const IDataObjectVtbl dataobject_vtbl
= {
551 DataObject_QueryInterface
,
555 DataObject_GetDataHere
,
556 DataObject_QueryGetData
,
557 DataObject_GetCanonicalFormatEtc
,
559 DataObject_EnumFormatEtc
,
561 DataObject_DUnadvise
,
562 DataObject_EnumDAdvise
565 static IDataObject DataObject
= { &dataobject_vtbl
};
567 static ATOM
register_dummy_class(void)
575 GetModuleHandleA(NULL
),
577 LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
),
578 (HBRUSH
)(COLOR_BTNFACE
+1),
583 return RegisterClassA(&wc
);
586 static void test_Register_Revoke(void)
592 hwnd
= CreateWindowA("WineOleTestClass", "Test", 0,
593 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, NULL
,
596 hr
= RegisterDragDrop(hwnd
, &DropTarget
);
597 ok(hr
== E_OUTOFMEMORY
||
598 broken(hr
== CO_E_NOTINITIALIZED
), /* NT4 */
599 "RegisterDragDrop without OLE initialized should have returned E_OUTOFMEMORY instead of 0x%08x\n", hr
);
603 hr
= RegisterDragDrop(hwnd
, NULL
);
604 ok(hr
== E_INVALIDARG
, "RegisterDragDrop with NULL IDropTarget * should return E_INVALIDARG instead of 0x%08x\n", hr
);
606 hr
= RegisterDragDrop(NULL
, &DropTarget
);
607 ok(hr
== DRAGDROP_E_INVALIDHWND
, "RegisterDragDrop with NULL hwnd should return DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr
);
609 hr
= RegisterDragDrop((HWND
)0xdeadbeef, &DropTarget
);
610 ok(hr
== DRAGDROP_E_INVALIDHWND
, "RegisterDragDrop with garbage hwnd should return DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr
);
612 ok(droptarget_refs
== 0, "DropTarget refs should be zero not %d\n", droptarget_refs
);
613 hr
= RegisterDragDrop(hwnd
, &DropTarget
);
614 ok_ole_success(hr
, "RegisterDragDrop");
615 ok(droptarget_refs
>= 1, "DropTarget refs should be at least one\n");
617 prop
= GetPropA(hwnd
, "OleDropTargetInterface");
618 ok(prop
== &DropTarget
, "expected IDropTarget pointer %p, got %p\n", &DropTarget
, prop
);
620 hr
= RegisterDragDrop(hwnd
, &DropTarget
);
621 ok(hr
== DRAGDROP_E_ALREADYREGISTERED
, "RegisterDragDrop with already registered hwnd should return DRAGDROP_E_ALREADYREGISTERED instead of 0x%08x\n", hr
);
623 ok(droptarget_refs
>= 1, "DropTarget refs should be at least one\n");
626 /* Win 8 releases the ref in OleUninitialize() */
627 if (droptarget_refs
>= 1)
629 hr
= RevokeDragDrop(hwnd
);
630 ok_ole_success(hr
, "RevokeDragDrop");
631 ok(droptarget_refs
== 0 ||
632 broken(droptarget_refs
== 1), /* NT4 */
633 "DropTarget refs should be zero not %d\n", droptarget_refs
);
636 hr
= RevokeDragDrop(NULL
);
637 ok(hr
== DRAGDROP_E_INVALIDHWND
, "RevokeDragDrop with NULL hwnd should return DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr
);
641 /* try to revoke with already destroyed window */
644 hwnd
= CreateWindowA("WineOleTestClass", "Test", 0,
645 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, NULL
,
648 hr
= RegisterDragDrop(hwnd
, &DropTarget
);
649 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
653 hr
= RevokeDragDrop(hwnd
);
654 ok(hr
== DRAGDROP_E_INVALIDHWND
, "got 0x%08x\n", hr
);
659 static void test_DoDragDrop(void)
667 hwnd
= CreateWindowExA(WS_EX_TOPMOST
, "WineOleTestClass", "Test", 0,
668 CW_USEDEFAULT
, CW_USEDEFAULT
, 100, 100, NULL
,
670 ok(IsWindow(hwnd
), "failed to create window\n");
672 hr
= OleInitialize(NULL
);
673 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
675 hr
= RegisterDragDrop(hwnd
, &DropTarget
);
676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
678 /* incomplete arguments set */
679 hr
= DoDragDrop(NULL
, NULL
, 0, NULL
);
680 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
682 hr
= DoDragDrop(NULL
, &DropSource
, 0, NULL
);
683 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
685 hr
= DoDragDrop(&DataObject
, NULL
, 0, NULL
);
686 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
688 hr
= DoDragDrop(NULL
, NULL
, 0, &effect
);
689 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
691 hr
= DoDragDrop(&DataObject
, &DropSource
, 0, NULL
);
692 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
694 hr
= DoDragDrop(NULL
, &DropSource
, 0, &effect
);
695 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
697 hr
= DoDragDrop(&DataObject
, NULL
, 0, &effect
);
698 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
700 ShowWindow(hwnd
, SW_SHOW
);
701 GetWindowRect(hwnd
, &rect
);
702 ok(SetCursorPos(rect
.left
+50, rect
.top
+50), "SetCursorPos failed\n");
704 for (seq
= 0; seq
< sizeof(call_lists
) / sizeof(call_lists
[0]); seq
++)
708 call_ptr
= call_lists
[seq
];
709 effect_in
= call_ptr
->set_param
;
712 hr
= DoDragDrop(&DataObject
, &DropSource
, effect_in
, &effect
);
713 check_expect(DoDragDrop_ret
, hr
, NULL
);
714 check_expect(DoDragDrop_effect_out
, effect
, NULL
);
724 register_dummy_class();
726 test_Register_Revoke();
728 if (!winetest_interactive
&&
729 !strcmp(winetest_platform
, "windows"))
731 skip("ROSTESTS-182: Skipping ole32_winetest:dragdrop test_DoDragDrop because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");