b06f5d4cc47aeaaa9d984ee7e570b31012a7f64d
[reactos.git] / rostests / winetests / oledlg / main.c
1 /*
2 * oledlg tests
3 *
4 * Copyright 2015 Nikolay Sivov for CodeWeavers
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
23 #include <wine/test.h>
24 #include <stdio.h>
25
26 #include <initguid.h>
27 #include <oledlg.h>
28
29 static const WCHAR *strstrW( const WCHAR *str, const WCHAR *sub )
30 {
31 while (*str)
32 {
33 const WCHAR *p1 = str, *p2 = sub;
34 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
35 if (!*p2) return str;
36 str++;
37 }
38 return NULL;
39 }
40
41 static HRESULT WINAPI enumverbs_QueryInterface(IEnumOLEVERB *iface, REFIID riid, void **ppv)
42 {
43 if (IsEqualIID(riid, &IID_IEnumOLEVERB) || IsEqualIID(riid, &IID_IUnknown)) {
44 *ppv = iface;
45 IEnumOLEVERB_AddRef(iface);
46 return S_OK;
47 }
48
49 *ppv = NULL;
50 return E_NOINTERFACE;
51 }
52
53 static ULONG WINAPI enumverbs_AddRef(IEnumOLEVERB *iface)
54 {
55 return 2;
56 }
57
58 static ULONG WINAPI enumverbs_Release(IEnumOLEVERB *iface)
59 {
60 return 1;
61 }
62
63 static int g_enumpos;
64 static const WCHAR verbW[] = {'v','e','r','b',0};
65 static HRESULT WINAPI enumverbs_Next(IEnumOLEVERB *iface, ULONG count, OLEVERB *verbs, ULONG *fetched)
66 {
67 ok(count == 1, "got %u\n", count);
68 ok(fetched == NULL, "got %p\n", fetched);
69 ok(g_enumpos == 0 || g_enumpos == 1, "got pos %d\n", g_enumpos);
70
71 if (g_enumpos++ == 0) {
72 verbs->lVerb = 123;
73 verbs->lpszVerbName = CoTaskMemAlloc(sizeof(verbW));
74 lstrcpyW(verbs->lpszVerbName, verbW);
75 verbs->fuFlags = MF_ENABLED;
76 verbs->grfAttribs = OLEVERBATTRIB_ONCONTAINERMENU;
77 if (fetched) *fetched = 1;
78 return S_OK;
79 }
80
81 return S_FALSE;
82 }
83
84 static HRESULT WINAPI enumverbs_Skip(IEnumOLEVERB *iface, ULONG count)
85 {
86 ok(0, "unexpected call\n");
87 return E_NOTIMPL;
88 }
89
90 static HRESULT WINAPI enumverbs_Reset(IEnumOLEVERB *iface)
91 {
92 ok(0, "unexpected call\n");
93 return E_NOTIMPL;
94 }
95
96 static HRESULT WINAPI enumverbs_Clone(IEnumOLEVERB *iface, IEnumOLEVERB **ppenum)
97 {
98 ok(0, "unexpected call\n");
99 return E_NOTIMPL;
100 }
101
102 static IEnumOLEVERBVtbl enumverbsvtbl = {
103 enumverbs_QueryInterface,
104 enumverbs_AddRef,
105 enumverbs_Release,
106 enumverbs_Next,
107 enumverbs_Skip,
108 enumverbs_Reset,
109 enumverbs_Clone
110 };
111
112 static IEnumOLEVERB enumverbs = { &enumverbsvtbl };
113
114 static HRESULT WINAPI oleobject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
115 {
116 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject)) {
117 *ppv = iface;
118 IOleObject_AddRef(iface);
119 return S_OK;
120 }
121
122 *ppv = NULL;
123 return E_NOINTERFACE;
124 }
125
126 static ULONG WINAPI oleobject_AddRef(IOleObject *iface)
127 {
128 return 2;
129 }
130
131 static ULONG WINAPI oleobject_Release(IOleObject *iface)
132 {
133 return 1;
134 }
135
136 static HRESULT WINAPI oleobject_SetClientSite(IOleObject *iface, IOleClientSite *site)
137 {
138 ok(0, "unexpected call\n");
139 return E_NOTIMPL;
140 }
141
142 static HRESULT WINAPI oleobject_GetClientSite(IOleObject *iface, IOleClientSite **site)
143 {
144 ok(0, "unexpected call\n");
145 return E_NOTIMPL;
146 }
147
148 static HRESULT WINAPI oleobject_SetHostNames(IOleObject *iface, LPCOLESTR containerapp,
149 LPCOLESTR containerObj)
150 {
151 ok(0, "unexpected call\n");
152 return E_NOTIMPL;
153 }
154
155 static HRESULT WINAPI oleobject_Close(IOleObject *iface, DWORD saveopt)
156 {
157 ok(0, "unexpected call\n");
158 return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI oleobject_SetMoniker(IOleObject *iface, DWORD whichmoniker, IMoniker *mk)
162 {
163 ok(0, "unexpected call\n");
164 return E_NOTIMPL;
165 }
166
167 static HRESULT WINAPI oleobject_GetMoniker(IOleObject *iface, DWORD assign, DWORD whichmoniker,
168 IMoniker **mk)
169 {
170 ok(0, "unexpected call\n");
171 return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI oleobject_InitFromData(IOleObject *iface, IDataObject *dataobject,
175 BOOL creation, DWORD reserved)
176 {
177 ok(0, "unexpected call\n");
178 return E_NOTIMPL;
179 }
180
181 static HRESULT WINAPI oleobject_GetClipboardData(IOleObject *iface, DWORD reserved, IDataObject **dataobject)
182 {
183 ok(0, "unexpected call\n");
184 return E_NOTIMPL;
185 }
186
187 static HRESULT WINAPI oleobject_DoVerb(IOleObject *iface, LONG verb, MSG *msg, IOleClientSite *activesite,
188 LONG index, HWND hwndParent, LPCRECT rect)
189 {
190 ok(0, "unexpected call\n");
191 return E_NOTIMPL;
192 }
193
194 static BOOL g_enumverbsfail;
195 static HRESULT WINAPI oleobject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **enumverb)
196 {
197 if (g_enumverbsfail) {
198 *enumverb = NULL;
199 return E_FAIL;
200 }
201 *enumverb = &enumverbs;
202 return S_OK;
203 }
204
205 static HRESULT WINAPI oleobject_Update(IOleObject *iface)
206 {
207 ok(0, "unexpected call\n");
208 return E_NOTIMPL;
209 }
210
211 static HRESULT WINAPI oleobject_IsUpToDate(IOleObject *iface)
212 {
213 ok(0, "unexpected call\n");
214 return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI oleobject_GetUserClassID(IOleObject *iface, CLSID *clsid)
218 {
219 ok(0, "unexpected call\n");
220 return E_NOTIMPL;
221 }
222
223 static const WCHAR testW[] = {'t','e','s','t',0};
224 static HRESULT WINAPI oleobject_GetUserType(IOleObject *iface, DWORD formoftype,
225 LPOLESTR *usertype)
226 {
227 ok(formoftype == USERCLASSTYPE_SHORT, "got %d\n", formoftype);
228 *usertype = CoTaskMemAlloc(sizeof(testW));
229 lstrcpyW(*usertype, testW);
230 return S_OK;
231 }
232
233 static HRESULT WINAPI oleobject_SetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
234 {
235 ok(0, "unexpected call\n");
236 return E_NOTIMPL;
237 }
238
239 static HRESULT WINAPI oleobject_GetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
240 {
241 ok(0, "unexpected call\n");
242 return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI oleobject_Advise(IOleObject *iface, IAdviseSink *sink, DWORD *connection)
246 {
247 ok(0, "unexpected call\n");
248 return E_NOTIMPL;
249 }
250
251 static HRESULT WINAPI oleobject_Unadvise(IOleObject *iface, DWORD connection)
252 {
253 ok(0, "unexpected call\n");
254 return E_NOTIMPL;
255 }
256
257 static HRESULT WINAPI oleobject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **enumadvise)
258 {
259 ok(0, "unexpected call\n");
260 return E_NOTIMPL;
261 }
262
263 static HRESULT WINAPI oleobject_GetMiscStatus(IOleObject *iface, DWORD aspect, DWORD *status)
264 {
265 ok(0, "unexpected call\n");
266 return E_NOTIMPL;
267 }
268
269 static HRESULT WINAPI oleobject_SetColorScheme(IOleObject *iface, LOGPALETTE *pal)
270 {
271 ok(0, "unexpected call\n");
272 return E_NOTIMPL;
273 }
274
275 static IOleObjectVtbl oleobjectvtbl = {
276 oleobject_QueryInterface,
277 oleobject_AddRef,
278 oleobject_Release,
279 oleobject_SetClientSite,
280 oleobject_GetClientSite,
281 oleobject_SetHostNames,
282 oleobject_Close,
283 oleobject_SetMoniker,
284 oleobject_GetMoniker,
285 oleobject_InitFromData,
286 oleobject_GetClipboardData,
287 oleobject_DoVerb,
288 oleobject_EnumVerbs,
289 oleobject_Update,
290 oleobject_IsUpToDate,
291 oleobject_GetUserClassID,
292 oleobject_GetUserType,
293 oleobject_SetExtent,
294 oleobject_GetExtent,
295 oleobject_Advise,
296 oleobject_Unadvise,
297 oleobject_EnumAdvise,
298 oleobject_GetMiscStatus,
299 oleobject_SetColorScheme
300 };
301
302 static IOleObject oleobject = { &oleobjectvtbl };
303
304 static void test_OleUIAddVerbMenu(void)
305 {
306 HMENU hMenu, verbmenu;
307 MENUITEMINFOW info;
308 WCHAR buffW[50];
309 int count;
310 BOOL ret;
311
312 ret = OleUIAddVerbMenuW(NULL, NULL, NULL, 0, 0, 0, FALSE, 0, NULL);
313 ok(!ret, "got %d\n", ret);
314
315 verbmenu = (HMENU)0xdeadbeef;
316 ret = OleUIAddVerbMenuW(NULL, NULL, NULL, 0, 0, 0, FALSE, 0, &verbmenu);
317 ok(!ret, "got %d\n", ret);
318 ok(verbmenu == NULL, "got %p\n", verbmenu);
319
320 g_enumpos = 0;
321 ret = OleUIAddVerbMenuW(&oleobject, NULL, NULL, 0, 0, 0, FALSE, 0, NULL);
322 ok(!ret, "got %d\n", ret);
323
324 hMenu = CreatePopupMenu();
325
326 memset(&info, 0, sizeof(info));
327 info.cbSize = sizeof(info);
328 ret = InsertMenuItemW(hMenu, 0, TRUE, &info);
329 ok(ret, "got %d\n", ret);
330
331 count = GetMenuItemCount(hMenu);
332 ok(count == 1, "got %d\n", count);
333
334 g_enumpos = 0;
335 ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 0, 0, 0, FALSE, 0, NULL);
336 ok(!ret, "got %d\n", ret);
337
338 count = GetMenuItemCount(hMenu);
339 ok(count == 1, "got %d\n", count);
340
341 ret = InsertMenuItemW(hMenu, 0, TRUE, &info);
342 ok(ret, "got %d\n", ret);
343
344 count = GetMenuItemCount(hMenu);
345 ok(count == 2, "got %d\n", count);
346
347 verbmenu = (HMENU)0xdeadbeef;
348 g_enumpos = 0;
349 ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 1, 0, 0, FALSE, 0, &verbmenu);
350 ok(ret, "got %d\n", ret);
351 ok(verbmenu == NULL, "got %p\n", verbmenu);
352
353 count = GetMenuItemCount(hMenu);
354 ok(count == 2, "got %d\n", count);
355
356 /* object doesn't support EnumVerbs() */
357 g_enumverbsfail = TRUE;
358 g_enumpos = 0;
359 verbmenu = (HMENU)0xdeadbeef;
360 ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 2, 0, 0, FALSE, 0, &verbmenu);
361 ok(!ret, "got %d\n", ret);
362 ok(verbmenu == NULL, "got %p\n", verbmenu);
363 g_enumverbsfail = FALSE;
364
365 /* added disabled item */
366 memset(&info, 0, sizeof(info));
367 info.cbSize = sizeof(info);
368 info.fMask = MIIM_STATE|MIIM_SUBMENU;
369 ret = GetMenuItemInfoW(hMenu, 2, TRUE, &info);
370 ok(ret, "got %d\n", ret);
371 ok(info.fState & MFS_DISABLED, "got state 0x%08x\n", info.fState);
372 ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);
373
374 count = GetMenuItemCount(hMenu);
375 ok(count == 3, "got %d\n", count);
376
377 /* now without object */
378 verbmenu = (HMENU)0xdeadbeef;
379 ret = OleUIAddVerbMenuW(NULL, testW, hMenu, 3, 42, 0, FALSE, 0, &verbmenu);
380 ok(!ret, "got %d\n", ret);
381 ok(verbmenu == NULL, "got %p\n", verbmenu);
382
383 memset(&info, 0, sizeof(info));
384 info.cbSize = sizeof(info);
385 info.fMask = MIIM_STATE|MIIM_ID|MIIM_STRING|MIIM_SUBMENU;
386 info.dwTypeData = buffW;
387 info.cch = sizeof(buffW)/sizeof(WCHAR);
388 ret = GetMenuItemInfoW(hMenu, 3, TRUE, &info);
389 ok(ret, "got %d\n", ret);
390 ok(info.fState == MF_GRAYED, "got state 0x%08x\n", info.fState);
391 ok(info.wID == 42, "got id %d\n", info.wID);
392 ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);
393
394 count = GetMenuItemCount(hMenu);
395 ok(count == 4, "got %d\n", count);
396
397 verbmenu = (HMENU)0xdeadbeef;
398 g_enumpos = 0;
399 ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 4, 0, 0, FALSE, 0, &verbmenu);
400 ok(ret, "got %d\n", ret);
401 ok(verbmenu == NULL, "got %p\n", verbmenu);
402
403 /* check newly added item */
404 memset(&info, 0, sizeof(info));
405 info.cbSize = sizeof(info);
406 info.fMask = MIIM_STRING|MIIM_STATE|MIIM_SUBMENU;
407 info.dwTypeData = buffW;
408 info.cch = sizeof(buffW)/sizeof(WCHAR);
409 ret = GetMenuItemInfoW(hMenu, 4, TRUE, &info);
410 ok(ret, "got %d\n", ret);
411 /* Item string contains verb, usertype and localized string for 'Object' word,
412 exact format depends on localization. */
413 ok(strstrW(buffW, verbW) != NULL, "str %s\n", wine_dbgstr_w(buffW));
414 ok(info.fState == 0, "got state 0x%08x\n", info.fState);
415 ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);
416
417 count = GetMenuItemCount(hMenu);
418 ok(count == 5, "got %d\n", count);
419
420 DestroyMenu(hMenu);
421 }
422
423 START_TEST(main)
424 {
425 test_OleUIAddVerbMenu();
426 }