ReactOS  0.4.13-dev-92-gf251225
dragdrop.c
Go to the documentation of this file.
1 /*
2  * Drag and Drop Tests
3  *
4  * Copyright 2007 Robert Shearman
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 _WIN32_DCOM
22 #define COBJMACROS
23 #define CONST_VTABLE
24 
25 #include <stdarg.h>
26 #include <stdio.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "objbase.h"
31 
32 #include "wine/test.h"
33 
34 
35 #define METHOD_LIST \
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), \
44  METHOD(DT_Drop), \
45  METHOD(DT_DragLeave), \
46  METHOD(DT_DragOver), \
47  METHOD(DoDragDrop_effect_in), \
48  METHOD(DoDragDrop_ret), \
49  METHOD(DoDragDrop_effect_out), \
50  METHOD(end_seq)
51 
52 #define METHOD(x) x
53 enum method
54 {
56 };
57 #undef METHOD
58 
59 #define METHOD(x) #x
60 static const char *method_names[] =
61 {
63 };
64 #undef METHOD
65 #undef METHOD_LIST
66 
68 {
69  enum method method;
71 
74 
75  int called_todo : 1;
76 };
77 
78 const struct method_call *call_ptr;
79 
81 {
82  HRESULT hr;
83 
84  do
85  {
86  todo_wine_if(call_ptr->called_todo)
87  ok_( file, line )( func == call_ptr->method, "unexpected call %s instead of %s\n",
89  if (call_ptr->method == func) break;
90  } while ((++call_ptr)->method != end_seq);
91 
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++;
97  return hr;
98 }
99 
100 #define check_expect(func, expect_param, set_param) \
101  check_expect_((func), (expect_param), (set_param), __FILE__, __LINE__)
102 
103 
104 struct method_call call_lists[][30] =
105 {
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 },
115 
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 },
120 
121  { DoDragDrop_ret, 0xbeefbeef, 0, 0, 0, },
122  { DoDragDrop_effect_out, DROPEFFECT_COPY, 0, 0, 0 },
123  { end_seq, 0, 0, 0, 0 }
124  },
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 },
134 
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 },
139 
140  { DoDragDrop_ret, DRAGDROP_S_DROP, 0, 0, 0 },
141  { DoDragDrop_effect_out, 0, 0, 0, 0 },
142  { end_seq, 0, 0, 0, 0 }
143  },
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 },
153 
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 },
158 
159  { DoDragDrop_ret, DRAGDROP_S_DROP, 0, 0, 0 },
160  { DoDragDrop_effect_out, 0, 0, 0, 0 },
161  { end_seq, 0, 0, 0, 0 }
162  },
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 },
172 
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 },
178 
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 },
182 
183  { DS_QueryContinueDrag, 0, DRAGDROP_S_DROP, 0, 0 },
184  { DT_Drop, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0, 0, 0 },
185 
186  { DoDragDrop_ret, DRAGDROP_S_DROP, 0, 0, 0 },
187  { DoDragDrop_effect_out, 0, 0, 0, 0 },
188  { end_seq, 0, 0, 0, 0 }
189  },
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 },
199 
200  { DS_QueryContinueDrag, 0, DRAGDROP_S_CANCEL, 0, 0 },
201 
202  { DoDragDrop_ret, DRAGDROP_S_CANCEL, 0, 0, 0 },
203  { DoDragDrop_effect_out, 0, 0, 0, 0 },
204  { end_seq, 0, 0, 0, 0 }
205  },
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 },
215 
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 },
221 
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 },
225 
226  { DS_QueryContinueDrag, 0, DRAGDROP_S_CANCEL, 0, 0 },
227  { DT_DragLeave, 0, 0, 0, 0 },
228 
229  { DoDragDrop_ret, DRAGDROP_S_CANCEL, 0, 0, 0 },
230  { DoDragDrop_effect_out, 0, 0, 0, 0 },
231  { end_seq, 0, 0, 0, 0 }
232  },
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 },
242 
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 },
248 
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 },
252 
253  { DS_QueryContinueDrag, 0, E_FAIL, 0, 0 },
254  { DT_DragLeave, 0, 0, 0, 0 },
255 
256  { DoDragDrop_ret, E_FAIL, 0, 0, 0 },
257  { DoDragDrop_effect_out, 0, 0, 0, 0 },
258  { end_seq, 0, 0, 0, 0 }
259  },
260 };
261 
262 static int droptarget_refs;
263 
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)
266 
268  void** ppvObject)
269 {
270  ok(0, "DropTarget_QueryInterface() shouldn't be called\n");
271  if (IsEqualIID(riid, &IID_IUnknown) ||
272  IsEqualIID(riid, &IID_IDropTarget))
273  {
274  IDropTarget_AddRef(iface);
275  *ppvObject = iface;
276  return S_OK;
277  }
278  *ppvObject = NULL;
279  return E_NOINTERFACE;
280 }
281 
283 {
284  droptarget_refs++;
285  return droptarget_refs;
286 }
287 
289 {
290  droptarget_refs--;
291  return droptarget_refs;
292 }
293 
295  IDataObject* pDataObj,
296  DWORD grfKeyState, POINTL pt,
297  DWORD* pdwEffect)
298 {
299  return check_expect(DT_DragEnter, *pdwEffect, pdwEffect);
300 }
301 
303  DWORD grfKeyState,
304  POINTL pt,
305  DWORD* pdwEffect)
306 {
307  return check_expect(DT_DragOver, *pdwEffect, pdwEffect);
308 }
309 
311 {
312  return check_expect(DT_DragLeave, 0, NULL);
313 }
314 
316  IDataObject* pDataObj, DWORD grfKeyState,
317  POINTL pt, DWORD* pdwEffect)
318 {
319  return check_expect(DT_Drop, *pdwEffect, pdwEffect);
320 }
321 
322 static const IDropTargetVtbl DropTarget_VTbl =
323 {
331 };
332 
334 
336 {
337  if (IsEqualIID(riid, &IID_IUnknown) ||
338  IsEqualIID(riid, &IID_IDropSource))
339  {
340  *ppObj = iface;
341  IDropSource_AddRef(iface);
342  return S_OK;
343  }
344  return E_NOINTERFACE;
345 }
346 
348 {
349  return 2;
350 }
351 
353 {
354  return 1;
355 }
356 
358  IDropSource *iface,
359  BOOL fEscapePressed,
360  DWORD grfKeyState)
361 {
362  return check_expect(DS_QueryContinueDrag, 0, NULL);
363 }
364 
366  IDropSource *iface,
367  DWORD dwEffect)
368 {
369  return check_expect(DS_GiveFeedback, dwEffect, NULL);
370 }
371 
372 static const IDropSourceVtbl dropsource_vtbl = {
378 };
379 
381 
383  REFIID riid, void **ppvObj)
384 {
385  ok(0, "unexpected call\n");
386  return E_NOTIMPL;
387 }
388 
390 {
391  return 2;
392 }
393 
395 {
396  return 1;
397 }
398 
400  ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
401 {
402  static FORMATETC format = { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
403  HRESULT hr = check_expect(EnumFMT_Next, 0, NULL);
404 
405  ok(celt == 1, "celt = %d\n", celt);
406  ok(rgelt != NULL, "rgelt == NULL\n");
407  ok(pceltFetched == NULL, "pceltFetched != NULL\n");
408 
409  *rgelt = format;
410  return hr;
411 }
412 
414 {
415  return check_expect(EnumFMT_Skip, 0, NULL);
416 }
417 
419 {
420  return check_expect(EnumFMT_Reset, 0, NULL);
421 }
422 
424  IEnumFORMATETC **ppenum)
425 {
426  ok(0, "unexpected call\n");
427  return E_NOTIMPL;
428 }
429 
430 static const IEnumFORMATETCVtbl enumformatetc_vtbl = {
438 };
439 
441 
443  IDataObject *iface,
444  REFIID riid,
445  void **pObj)
446 {
447  if (IsEqualIID(riid, &IID_IUnknown) ||
449  {
450  *pObj = iface;
451  IDataObject_AddRef(iface);
452  return S_OK;
453  }
454 
455  trace("DataObject_QueryInterface: %s\n", wine_dbgstr_guid(riid));
456  return E_NOINTERFACE;
457 }
458 
460 {
461  return 2;
462 }
463 
465 {
466  return 1;
467 }
468 
470  IDataObject *iface,
471  FORMATETC *pformatetcIn,
472  STGMEDIUM *pmedium)
473 {
474  ok(0, "unexpected call\n");
475  return E_NOTIMPL;
476 }
477 
479  IDataObject *iface,
480  FORMATETC *pformatetc,
481  STGMEDIUM *pmedium)
482 {
483  ok(0, "unexpected call\n");
484  return E_NOTIMPL;
485 }
486 
488  IDataObject *iface,
489  FORMATETC *pformatetc)
490 {
491  return check_expect(DO_QueryGetData, 0, NULL);
492 }
493 
495  IDataObject *iface,
496  FORMATETC *pformatectIn,
497  FORMATETC *pformatetcOut)
498 {
499  ok(0, "unexpected call\n");
500  return E_NOTIMPL;
501 }
502 
504  IDataObject *iface,
505  FORMATETC *pformatetc,
506  STGMEDIUM *pmedium,
507  BOOL fRelease)
508 {
509  ok(0, "unexpected call\n");
510  return E_NOTIMPL;
511 }
512 
514  IDataObject *iface,
515  DWORD dwDirection,
516  IEnumFORMATETC **ppenumFormatEtc)
517 {
518  HRESULT hr = check_expect(DO_EnumFormatEtc, 0, NULL);
519  *ppenumFormatEtc = &EnumFORMATETC;
520  return hr;
521 }
522 
524  IDataObject *iface,
525  FORMATETC *pformatetc,
526  DWORD advf,
527  IAdviseSink *pAdvSink,
528  DWORD *pdwConnection)
529 {
530  ok(0, "unexpected call\n");
531  return E_NOTIMPL;
532 }
533 
535  IDataObject *iface,
536  DWORD dwConnection)
537 {
538  ok(0, "unexpected call\n");
539  return E_NOTIMPL;
540 }
541 
543  IDataObject *iface,
544  IEnumSTATDATA **ppenumAdvise)
545 {
546  ok(0, "unexpected call\n");
547  return E_NOTIMPL;
548 }
549 
550 static const IDataObjectVtbl dataobject_vtbl = {
563 };
564 
566 
568 {
569  WNDCLASSA wc =
570  {
571  0,
573  0,
574  0,
576  NULL,
578  (HBRUSH)(COLOR_BTNFACE+1),
579  NULL,
580  "WineOleTestClass",
581  };
582 
583  return RegisterClassA(&wc);
584 }
585 
586 static void test_Register_Revoke(void)
587 {
588  HANDLE prop;
589  HRESULT hr;
590  HWND hwnd;
591 
592  hwnd = CreateWindowA("WineOleTestClass", "Test", 0,
594  NULL, NULL, NULL);
595 
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);
600 
602 
604  ok(hr == E_INVALIDARG, "RegisterDragDrop with NULL IDropTarget * should return E_INVALIDARG instead of 0x%08x\n", hr);
605 
607  ok(hr == DRAGDROP_E_INVALIDHWND, "RegisterDragDrop with NULL hwnd should return DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr);
608 
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);
611 
612  ok(droptarget_refs == 0, "DropTarget refs should be zero not %d\n", droptarget_refs);
614  ok_ole_success(hr, "RegisterDragDrop");
615  ok(droptarget_refs >= 1, "DropTarget refs should be at least one\n");
616 
617  prop = GetPropA(hwnd, "OleDropTargetInterface");
618  ok(prop == &DropTarget, "expected IDropTarget pointer %p, got %p\n", &DropTarget, prop);
619 
621  ok(hr == DRAGDROP_E_ALREADYREGISTERED, "RegisterDragDrop with already registered hwnd should return DRAGDROP_E_ALREADYREGISTERED instead of 0x%08x\n", hr);
622 
623  ok(droptarget_refs >= 1, "DropTarget refs should be at least one\n");
624  OleUninitialize();
625 
626  /* Win 8 releases the ref in OleUninitialize() */
627  if (droptarget_refs >= 1)
628  {
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);
634  }
635 
637  ok(hr == DRAGDROP_E_INVALIDHWND, "RevokeDragDrop with NULL hwnd should return DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr);
638 
640 
641  /* try to revoke with already destroyed window */
643 
644  hwnd = CreateWindowA("WineOleTestClass", "Test", 0,
646  NULL, NULL, NULL);
647 
649  ok(hr == S_OK, "got 0x%08x\n", hr);
650 
652 
654  ok(hr == DRAGDROP_E_INVALIDHWND, "got 0x%08x\n", hr);
655 
656  OleUninitialize();
657 }
658 
659 static void test_DoDragDrop(void)
660 {
661  DWORD effect;
662  HRESULT hr;
663  HWND hwnd;
664  RECT rect;
665  int seq;
666 
667  hwnd = CreateWindowExA(WS_EX_TOPMOST, "WineOleTestClass", "Test", 0,
668  CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL,
669  NULL, NULL, NULL);
670  ok(IsWindow(hwnd), "failed to create window\n");
671 
672  hr = OleInitialize(NULL);
673  ok(hr == S_OK, "got 0x%08x\n", hr);
674 
676  ok(hr == S_OK, "got 0x%08x\n", hr);
677 
678  /* incomplete arguments set */
679  hr = DoDragDrop(NULL, NULL, 0, NULL);
680  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
681 
682  hr = DoDragDrop(NULL, &DropSource, 0, NULL);
683  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
684 
685  hr = DoDragDrop(&DataObject, NULL, 0, NULL);
686  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
687 
688  hr = DoDragDrop(NULL, NULL, 0, &effect);
689  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
690 
692  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
693 
694  hr = DoDragDrop(NULL, &DropSource, 0, &effect);
695  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
696 
697  hr = DoDragDrop(&DataObject, NULL, 0, &effect);
698  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
699 
702  ok(SetCursorPos(rect.left+50, rect.top+50), "SetCursorPos failed\n");
703 
704  for (seq = 0; seq < ARRAY_SIZE(call_lists); seq++)
705  {
706  DWORD effect_in;
707  trace("%d\n", seq);
708  call_ptr = call_lists[seq];
709  effect_in = call_ptr->set_param;
710  call_ptr++;
711 
712  hr = DoDragDrop(&DataObject, &DropSource, effect_in, &effect);
713  check_expect(DoDragDrop_ret, hr, NULL);
714  check_expect(DoDragDrop_effect_out, effect, NULL);
715  }
716 
717  OleUninitialize();
718 
720 }
721 
722 START_TEST(dragdrop)
723 {
725 
727 #ifdef __REACTOS__
728  if (!winetest_interactive &&
729  !strcmp(winetest_platform, "windows"))
730  {
731  skip("ROSTESTS-182: Skipping ole32_winetest:dragdrop test_DoDragDrop because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
732  return;
733  }
734 #endif
735  test_DoDragDrop();
736 }
static HRESULT WINAPI DropTarget_Drop(IDropTarget *iface, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
Definition: dragdrop.c:315
GLenum func
Definition: glext.h:6028
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define trace(...)
Definition: kmt_test.h:217
#define REFIID
Definition: guiddef.h:113
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI DataObject_GetData(IDataObject *iface, FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
Definition: dragdrop.c:469
static ULONG WINAPI DropTarget_Release(IDropTarget *iface)
Definition: dragdrop.c:288
static HRESULT WINAPI DataObject_EnumDAdvise(IDataObject *iface, IEnumSTATDATA **ppenumAdvise)
Definition: dragdrop.c:542
HRESULT hr
Definition: shlfolder.c:183
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define ok_(x1, x2)
WORD ATOM
Definition: dimm.idl:113
static ULONG WINAPI EnumFORMATETC_Release(IEnumFORMATETC *iface)
Definition: dragdrop.c:394
#define pt(x, y)
Definition: drawing.c:79
REFIID riid
Definition: precomp.h:44
static IDataObject DataObject
Definition: dragdrop.c:565
const char * wine_dbgstr_guid(const GUID *guid)
const GUID IID_IDataObject
HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
Definition: ole2.c:560
int winetest_interactive
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
static HRESULT WINAPI EnumFORMATETC_Clone(IEnumFORMATETC *iface, IEnumFORMATETC **ppenum)
Definition: dragdrop.c:423
char * LPSTR
Definition: xmlstorage.h:182
#define E_FAIL
Definition: ddrawi.h:102
BOOL WINAPI DestroyWindow(_In_ HWND)
static HRESULT WINAPI DataObject_DAdvise(IDataObject *iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
Definition: dragdrop.c:523
HRESULT WINAPI RevokeDragDrop(HWND hwnd)
Definition: ole2.c:642
static ULONG WINAPI EnumFORMATETC_AddRef(IEnumFORMATETC *iface)
Definition: dragdrop.c:389
& rect
Definition: startmenu.cpp:1413
#define DRAGDROP_S_CANCEL
Definition: winerror.h:2647
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define CO_E_NOTINITIALIZED
static HRESULT WINAPI EnumFORMATETC_Skip(IEnumFORMATETC *iface, ULONG celt)
Definition: dragdrop.c:413
static HRESULT WINAPI DataObject_QueryGetData(IDataObject *iface, FORMATETC *pformatetc)
Definition: dragdrop.c:487
static HRESULT WINAPI EnumFORMATETC_Reset(IEnumFORMATETC *iface)
Definition: dragdrop.c:418
static const IEnumFORMATETCVtbl enumformatetc_vtbl
Definition: dragdrop.c:430
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static ULONG WINAPI DataObject_AddRef(IDataObject *iface)
Definition: dragdrop.c:459
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4184
#define CW_USEDEFAULT
Definition: winuser.h:225
#define S_FALSE
Definition: winerror.h:2357
static void test_Register_Revoke(void)
Definition: dragdrop.c:586
#define E_INVALIDARG
Definition: ddrawi.h:101
static HRESULT WINAPI DropSource_QueryInterface(IDropSource *iface, REFIID riid, void **ppObj)
Definition: dragdrop.c:335
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
static HRESULT WINAPI DropTarget_QueryInterface(IDropTarget *iface, REFIID riid, void **ppvObject)
Definition: dragdrop.c:267
const char * winetest_platform
#define SW_SHOW
Definition: winuser.h:769
static ULONG WINAPI DropSource_Release(IDropSource *iface)
Definition: dragdrop.c:352
static HRESULT WINAPI DataObject_GetDataHere(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
Definition: dragdrop.c:478
#define DRAGDROP_E_INVALIDHWND
Definition: winerror.h:2654
#define CF_TEXT
Definition: constants.h:396
static HRESULT WINAPI DropSource_GiveFeedback(IDropSource *iface, DWORD dwEffect)
Definition: dragdrop.c:365
static const IDropSourceVtbl dropsource_vtbl
Definition: dragdrop.c:372
static HRESULT WINAPI DropTarget_DragLeave(IDropTarget *iface)
Definition: dragdrop.c:310
#define todo_wine_if(is_todo)
Definition: test.h:155
static HRESULT WINAPI DataObject_EnumFormatEtc(IDataObject *iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
Definition: dragdrop.c:513
DWORD set_param
Definition: dragdrop.c:73
static const IDropTargetVtbl DropTarget_VTbl
Definition: dragdrop.c:322
LONG HRESULT
Definition: typedefs.h:77
static HRESULT WINAPI DataObject_DUnadvise(IDataObject *iface, DWORD dwConnection)
Definition: dragdrop.c:534
static IDropTarget DropTarget
Definition: dragdrop.c:333
const GUID IID_IUnknown
static int droptarget_refs
Definition: dragdrop.c:262
const struct method_call * call_ptr
Definition: dragdrop.c:78
#define WINAPI
Definition: msvc.h:8
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:2627
#define check_expect(func, expect_param, set_param)
Definition: dragdrop.c:100
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI EnumFORMATETC_QueryInterface(IEnumFORMATETC *iface, REFIID riid, void **ppvObj)
Definition: dragdrop.c:382
int called_todo
Definition: dragdrop.c:75
#define DRAGDROP_S_USEDEFAULTCURSORS
Definition: winerror.h:2648
#define ok_ole_success(hr, func)
Definition: dragdrop.c:265
static const char * method_names[]
Definition: dragdrop.c:60
method
Definition: dragdrop.c:53
enum method method
Definition: dragdrop.c:69
static HRESULT WINAPI DataObject_QueryInterface(IDataObject *iface, REFIID riid, void **pObj)
Definition: dragdrop.c:442
static IDropSource DropSource
Definition: dragdrop.c:380
DWORD expect_param
Definition: dragdrop.c:70
#define DRAGDROP_E_ALREADYREGISTERED
Definition: winerror.h:2653
static HRESULT check_expect_(enum method func, DWORD expect_param, DWORD *set_param, const char *file, int line)
Definition: dragdrop.c:80
#define COLOR_BTNFACE
Definition: winuser.h:918
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
#define WS_EX_TOPMOST
Definition: pedump.c:647
REFIID LPVOID * ppvObject
Definition: precomp.h:44
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
#define broken(x)
Definition: _sntprintf.h:21
static HRESULT WINAPI EnumFORMATETC_Next(IEnumFORMATETC *iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
Definition: dragdrop.c:399
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:172
#define S_OK
Definition: intsafe.h:59
static HRESULT WINAPI DropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
Definition: dragdrop.c:294
HANDLE WINAPI GetPropA(_In_ HWND, _In_ LPCSTR)
static HRESULT WINAPI DropSource_QueryContinueDrag(IDropSource *iface, BOOL fEscapePressed, DWORD grfKeyState)
Definition: dragdrop.c:357
#define ARRAY_SIZE(a)
Definition: main.h:24
START_TEST(dragdrop)
Definition: dragdrop.c:722
static const IDataObjectVtbl dataobject_vtbl
Definition: dragdrop.c:550
#define DRAGDROP_S_DROP
Definition: winerror.h:2646
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT WINAPI DoDragDrop(IDataObject *pDataObject, IDropSource *pDropSource, DWORD dwOKEffect, DWORD *pdwEffect)
Definition: ole2.c:756
static ATOM register_dummy_class(void)
Definition: dragdrop.c:567
#define METHOD_LIST
Definition: dragdrop.c:35
static void test_DoDragDrop(void)
Definition: dragdrop.c:659
HRESULT set_ret
Definition: dragdrop.c:72
#define skip(...)
static HRESULT WINAPI DropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
Definition: dragdrop.c:302
#define IDC_ARROW
Definition: winuser.h:682
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
static ULONG WINAPI DataObject_Release(IDataObject *iface)
Definition: dragdrop.c:464
unsigned int ULONG
Definition: retypes.h:1
static ULONG WINAPI DropSource_AddRef(IDropSource *iface)
Definition: dragdrop.c:347
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:233
static IEnumFORMATETC EnumFORMATETC
Definition: dragdrop.c:440
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
static ULONG WINAPI DropTarget_AddRef(IDropTarget *iface)
Definition: dragdrop.c:282
struct method_call call_lists[][30]
Definition: dragdrop.c:104
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
static HRESULT WINAPI DataObject_SetData(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
Definition: dragdrop.c:503
static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(IDataObject *iface, FORMATETC *pformatectIn, FORMATETC *pformatetcOut)
Definition: dragdrop.c:494
Definition: fci.c:126