4 * Copyright 2015 Nikolay Sivov for CodeWeavers
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
23 #include "wine/test.h"
29 static HRESULT WINAPI
enumverbs_QueryInterface(IEnumOLEVERB
*iface
, REFIID riid
, void **ppv
)
31 if (IsEqualIID(riid
, &IID_IEnumOLEVERB
) || IsEqualIID(riid
, &IID_IUnknown
)) {
33 IEnumOLEVERB_AddRef(iface
);
41 static ULONG WINAPI
enumverbs_AddRef(IEnumOLEVERB
*iface
)
46 static ULONG WINAPI
enumverbs_Release(IEnumOLEVERB
*iface
)
52 static const WCHAR verbW
[] = {'v','e','r','b',0};
53 static HRESULT WINAPI
enumverbs_Next(IEnumOLEVERB
*iface
, ULONG count
, OLEVERB
*verbs
, ULONG
*fetched
)
55 ok(count
== 1, "got %u\n", count
);
56 ok(fetched
== NULL
, "got %p\n", fetched
);
57 ok(g_enumpos
== 0 || g_enumpos
== 1, "got pos %d\n", g_enumpos
);
59 if (g_enumpos
++ == 0) {
61 verbs
->lpszVerbName
= CoTaskMemAlloc(sizeof(verbW
));
62 lstrcpyW(verbs
->lpszVerbName
, verbW
);
63 verbs
->fuFlags
= MF_ENABLED
;
64 verbs
->grfAttribs
= OLEVERBATTRIB_ONCONTAINERMENU
;
65 if (fetched
) *fetched
= 1;
72 static HRESULT WINAPI
enumverbs_Skip(IEnumOLEVERB
*iface
, ULONG count
)
74 ok(0, "unexpected call\n");
78 static HRESULT WINAPI
enumverbs_Reset(IEnumOLEVERB
*iface
)
80 ok(0, "unexpected call\n");
84 static HRESULT WINAPI
enumverbs_Clone(IEnumOLEVERB
*iface
, IEnumOLEVERB
**ppenum
)
86 ok(0, "unexpected call\n");
90 static IEnumOLEVERBVtbl enumverbsvtbl
= {
91 enumverbs_QueryInterface
,
100 static IEnumOLEVERB enumverbs
= { &enumverbsvtbl
};
102 static HRESULT WINAPI
oleobject_QueryInterface(IOleObject
*iface
, REFIID riid
, void **ppv
)
104 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IOleObject
)) {
106 IOleObject_AddRef(iface
);
111 return E_NOINTERFACE
;
114 static ULONG WINAPI
oleobject_AddRef(IOleObject
*iface
)
119 static ULONG WINAPI
oleobject_Release(IOleObject
*iface
)
124 static HRESULT WINAPI
oleobject_SetClientSite(IOleObject
*iface
, IOleClientSite
*site
)
126 ok(0, "unexpected call\n");
130 static HRESULT WINAPI
oleobject_GetClientSite(IOleObject
*iface
, IOleClientSite
**site
)
132 ok(0, "unexpected call\n");
136 static HRESULT WINAPI
oleobject_SetHostNames(IOleObject
*iface
, LPCOLESTR containerapp
,
137 LPCOLESTR containerObj
)
139 ok(0, "unexpected call\n");
143 static HRESULT WINAPI
oleobject_Close(IOleObject
*iface
, DWORD saveopt
)
145 ok(0, "unexpected call\n");
149 static HRESULT WINAPI
oleobject_SetMoniker(IOleObject
*iface
, DWORD whichmoniker
, IMoniker
*mk
)
151 ok(0, "unexpected call\n");
155 static HRESULT WINAPI
oleobject_GetMoniker(IOleObject
*iface
, DWORD assign
, DWORD whichmoniker
,
158 ok(0, "unexpected call\n");
162 static HRESULT WINAPI
oleobject_InitFromData(IOleObject
*iface
, IDataObject
*dataobject
,
163 BOOL creation
, DWORD reserved
)
165 ok(0, "unexpected call\n");
169 static HRESULT WINAPI
oleobject_GetClipboardData(IOleObject
*iface
, DWORD reserved
, IDataObject
**dataobject
)
171 ok(0, "unexpected call\n");
175 static HRESULT WINAPI
oleobject_DoVerb(IOleObject
*iface
, LONG verb
, MSG
*msg
, IOleClientSite
*activesite
,
176 LONG index
, HWND hwndParent
, LPCRECT rect
)
178 ok(0, "unexpected call\n");
182 static BOOL g_enumverbsfail
;
183 static HRESULT WINAPI
oleobject_EnumVerbs(IOleObject
*iface
, IEnumOLEVERB
**enumverb
)
185 if (g_enumverbsfail
) {
189 *enumverb
= &enumverbs
;
193 static HRESULT WINAPI
oleobject_Update(IOleObject
*iface
)
195 ok(0, "unexpected call\n");
199 static HRESULT WINAPI
oleobject_IsUpToDate(IOleObject
*iface
)
201 ok(0, "unexpected call\n");
205 static HRESULT WINAPI
oleobject_GetUserClassID(IOleObject
*iface
, CLSID
*clsid
)
207 ok(0, "unexpected call\n");
211 static const WCHAR testW
[] = {'t','e','s','t',0};
212 static HRESULT WINAPI
oleobject_GetUserType(IOleObject
*iface
, DWORD formoftype
,
215 ok(formoftype
== USERCLASSTYPE_SHORT
, "got %d\n", formoftype
);
216 *usertype
= CoTaskMemAlloc(sizeof(testW
));
217 lstrcpyW(*usertype
, testW
);
221 static HRESULT WINAPI
oleobject_SetExtent(IOleObject
*iface
, DWORD aspect
, SIZEL
*size
)
223 ok(0, "unexpected call\n");
227 static HRESULT WINAPI
oleobject_GetExtent(IOleObject
*iface
, DWORD aspect
, SIZEL
*size
)
229 ok(0, "unexpected call\n");
233 static HRESULT WINAPI
oleobject_Advise(IOleObject
*iface
, IAdviseSink
*sink
, DWORD
*connection
)
235 ok(0, "unexpected call\n");
239 static HRESULT WINAPI
oleobject_Unadvise(IOleObject
*iface
, DWORD connection
)
241 ok(0, "unexpected call\n");
245 static HRESULT WINAPI
oleobject_EnumAdvise(IOleObject
*iface
, IEnumSTATDATA
**enumadvise
)
247 ok(0, "unexpected call\n");
251 static HRESULT WINAPI
oleobject_GetMiscStatus(IOleObject
*iface
, DWORD aspect
, DWORD
*status
)
253 ok(0, "unexpected call\n");
257 static HRESULT WINAPI
oleobject_SetColorScheme(IOleObject
*iface
, LOGPALETTE
*pal
)
259 ok(0, "unexpected call\n");
263 static IOleObjectVtbl oleobjectvtbl
= {
264 oleobject_QueryInterface
,
267 oleobject_SetClientSite
,
268 oleobject_GetClientSite
,
269 oleobject_SetHostNames
,
271 oleobject_SetMoniker
,
272 oleobject_GetMoniker
,
273 oleobject_InitFromData
,
274 oleobject_GetClipboardData
,
278 oleobject_IsUpToDate
,
279 oleobject_GetUserClassID
,
280 oleobject_GetUserType
,
285 oleobject_EnumAdvise
,
286 oleobject_GetMiscStatus
,
287 oleobject_SetColorScheme
290 static IOleObject oleobject
= { &oleobjectvtbl
};
292 static void test_OleUIAddVerbMenu(void)
294 static const WCHAR cadabraW
[] = {'c','a','d','a','b','r','a',0};
295 HMENU hMenu
, verbmenu
;
301 ret
= OleUIAddVerbMenuW(NULL
, NULL
, NULL
, 0, 0, 0, FALSE
, 0, NULL
);
302 ok(!ret
, "got %d\n", ret
);
304 verbmenu
= (HMENU
)0xdeadbeef;
305 ret
= OleUIAddVerbMenuW(NULL
, NULL
, NULL
, 0, 0, 0, FALSE
, 0, &verbmenu
);
306 ok(!ret
, "got %d\n", ret
);
307 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
310 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, NULL
, 0, 0, 0, FALSE
, 0, NULL
);
311 ok(!ret
, "got %d\n", ret
);
313 hMenu
= CreatePopupMenu();
315 memset(&info
, 0, sizeof(info
));
316 info
.cbSize
= sizeof(info
);
317 ret
= InsertMenuItemW(hMenu
, 0, TRUE
, &info
);
318 ok(ret
, "got %d\n", ret
);
320 count
= GetMenuItemCount(hMenu
);
321 ok(count
== 1, "got %d\n", count
);
324 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 0, 0, 0, FALSE
, 0, NULL
);
325 ok(!ret
, "got %d\n", ret
);
327 count
= GetMenuItemCount(hMenu
);
328 ok(count
== 1, "got %d\n", count
);
330 ret
= InsertMenuItemW(hMenu
, 0, TRUE
, &info
);
331 ok(ret
, "got %d\n", ret
);
333 count
= GetMenuItemCount(hMenu
);
334 ok(count
== 2, "got %d\n", count
);
336 verbmenu
= (HMENU
)0xdeadbeef;
338 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 1, 0, 0, FALSE
, 0, &verbmenu
);
339 ok(ret
, "got %d\n", ret
);
340 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
342 count
= GetMenuItemCount(hMenu
);
343 ok(count
== 2, "got %d\n", count
);
345 /* object doesn't support EnumVerbs() */
346 g_enumverbsfail
= TRUE
;
348 verbmenu
= (HMENU
)0xdeadbeef;
349 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 2, 0, 0, FALSE
, 0, &verbmenu
);
350 ok(!ret
, "got %d\n", ret
);
351 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
352 g_enumverbsfail
= FALSE
;
354 /* added disabled item */
355 memset(&info
, 0, sizeof(info
));
356 info
.cbSize
= sizeof(info
);
357 info
.fMask
= MIIM_STATE
|MIIM_SUBMENU
;
358 ret
= GetMenuItemInfoW(hMenu
, 2, TRUE
, &info
);
359 ok(ret
, "got %d\n", ret
);
360 ok(info
.fState
& MFS_DISABLED
, "got state 0x%08x\n", info
.fState
);
361 ok(info
.hSubMenu
== NULL
, "got submenu %p\n", info
.hSubMenu
);
363 count
= GetMenuItemCount(hMenu
);
364 ok(count
== 3, "got %d\n", count
);
366 /* now without object */
367 verbmenu
= (HMENU
)0xdeadbeef;
368 ret
= OleUIAddVerbMenuW(NULL
, testW
, hMenu
, 3, 42, 0, FALSE
, 0, &verbmenu
);
369 ok(!ret
, "got %d\n", ret
);
370 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
372 memset(&info
, 0, sizeof(info
));
373 info
.cbSize
= sizeof(info
);
374 info
.fMask
= MIIM_STATE
|MIIM_ID
|MIIM_STRING
|MIIM_SUBMENU
;
375 info
.dwTypeData
= buffW
;
376 info
.cch
= ARRAY_SIZE(buffW
);
377 ret
= GetMenuItemInfoW(hMenu
, 3, TRUE
, &info
);
378 ok(ret
, "got %d\n", ret
);
379 ok(info
.fState
== MF_GRAYED
, "got state 0x%08x\n", info
.fState
);
380 ok(info
.wID
== 42, "got id %d\n", info
.wID
);
381 ok(info
.hSubMenu
== NULL
, "got submenu %p\n", info
.hSubMenu
);
383 count
= GetMenuItemCount(hMenu
);
384 ok(count
== 4, "got %d\n", count
);
386 verbmenu
= (HMENU
)0xdeadbeef;
388 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 4, 0, 0, FALSE
, 0, &verbmenu
);
389 ok(ret
, "got %d\n", ret
);
390 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
392 /* check newly added item */
393 memset(&info
, 0, sizeof(info
));
394 info
.cbSize
= sizeof(info
);
395 info
.fMask
= MIIM_STRING
|MIIM_STATE
|MIIM_SUBMENU
;
396 info
.dwTypeData
= buffW
;
397 info
.cch
= ARRAY_SIZE(buffW
);
398 ret
= GetMenuItemInfoW(hMenu
, 4, TRUE
, &info
);
399 ok(ret
, "got %d\n", ret
);
400 /* Item string contains verb, usertype and localized string for 'Object' word,
401 exact format depends on localization. */
402 ok(wcsstr(buffW
, verbW
) != NULL
, "str %s\n", wine_dbgstr_w(buffW
));
403 ok(info
.fState
== 0, "got state 0x%08x\n", info
.fState
);
404 ok(info
.hSubMenu
== NULL
, "got submenu %p\n", info
.hSubMenu
);
406 count
= GetMenuItemCount(hMenu
);
407 ok(count
== 5, "got %d\n", count
);
411 /* try to add verb menu repeatedly, with same id */
412 hMenu
= CreatePopupMenu();
414 count
= GetMenuItemCount(hMenu
);
415 ok(count
== 0, "got %d\n", count
);
418 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 5, 10, TRUE
, 3, &verbmenu
);
419 ok(!ret
, "got %d\n", ret
);
420 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
422 count
= GetMenuItemCount(hMenu
);
423 ok(count
== 1, "got %d\n", count
);
426 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 5, 10, TRUE
, 3, &verbmenu
);
427 ok(!ret
, "got %d\n", ret
);
428 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
430 count
= GetMenuItemCount(hMenu
);
431 ok(count
== 1, "got %d\n", count
);
433 /* same position, different id */
435 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 6, 10, TRUE
, 3, &verbmenu
);
436 ok(!ret
, "got %d\n", ret
);
437 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
439 count
= GetMenuItemCount(hMenu
);
440 ok(count
== 1, "got %d\n", count
);
442 /* change added item string and state */
443 memset(&info
, 0, sizeof(info
));
444 info
.cbSize
= sizeof(info
);
445 info
.fMask
= MIIM_STRING
|MIIM_STATE
;
446 info
.fState
= MFS_ENABLED
;
447 info
.dwTypeData
= buffW
;
448 lstrcpyW(buffW
, cadabraW
);
449 ret
= SetMenuItemInfoW(hMenu
, 0, TRUE
, &info
);
450 ok(ret
, "got %d\n", ret
);
453 GetMenuStringW(hMenu
, 0, buffW
, ARRAY_SIZE(buffW
), MF_BYPOSITION
);
454 ok(!lstrcmpW(buffW
, cadabraW
), "got %s\n", wine_dbgstr_w(buffW
));
457 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 5, 10, TRUE
, 3, &verbmenu
);
458 ok(!ret
, "got %d\n", ret
);
459 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
461 memset(&info
, 0, sizeof(info
));
462 info
.cbSize
= sizeof(info
);
463 info
.fMask
= MIIM_STRING
|MIIM_STATE
;
465 info
.dwTypeData
= buffW
;
466 info
.cch
= ARRAY_SIZE(buffW
);
467 ret
= GetMenuItemInfoW(hMenu
, 0, TRUE
, &info
);
468 ok(ret
, "got %d\n", ret
);
469 ok(lstrcmpW(buffW
, cadabraW
), "got %s\n", wine_dbgstr_w(buffW
));
470 ok(info
.fState
== MF_GRAYED
, "got state 0x%08x\n", info
.fState
);
472 count
= GetMenuItemCount(hMenu
);
473 ok(count
== 1, "got %d\n", count
);
480 test_OleUIAddVerbMenu();