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 const WCHAR
*strstrW( const WCHAR
*str
, const WCHAR
*sub
)
33 const WCHAR
*p1
= str
, *p2
= sub
;
34 while (*p1
&& *p2
&& *p1
== *p2
) { p1
++; p2
++; }
41 static HRESULT WINAPI
enumverbs_QueryInterface(IEnumOLEVERB
*iface
, REFIID riid
, void **ppv
)
43 if (IsEqualIID(riid
, &IID_IEnumOLEVERB
) || IsEqualIID(riid
, &IID_IUnknown
)) {
45 IEnumOLEVERB_AddRef(iface
);
53 static ULONG WINAPI
enumverbs_AddRef(IEnumOLEVERB
*iface
)
58 static ULONG WINAPI
enumverbs_Release(IEnumOLEVERB
*iface
)
64 static const WCHAR verbW
[] = {'v','e','r','b',0};
65 static HRESULT WINAPI
enumverbs_Next(IEnumOLEVERB
*iface
, ULONG count
, OLEVERB
*verbs
, ULONG
*fetched
)
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
);
71 if (g_enumpos
++ == 0) {
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;
84 static HRESULT WINAPI
enumverbs_Skip(IEnumOLEVERB
*iface
, ULONG count
)
86 ok(0, "unexpected call\n");
90 static HRESULT WINAPI
enumverbs_Reset(IEnumOLEVERB
*iface
)
92 ok(0, "unexpected call\n");
96 static HRESULT WINAPI
enumverbs_Clone(IEnumOLEVERB
*iface
, IEnumOLEVERB
**ppenum
)
98 ok(0, "unexpected call\n");
102 static IEnumOLEVERBVtbl enumverbsvtbl
= {
103 enumverbs_QueryInterface
,
112 static IEnumOLEVERB enumverbs
= { &enumverbsvtbl
};
114 static HRESULT WINAPI
oleobject_QueryInterface(IOleObject
*iface
, REFIID riid
, void **ppv
)
116 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IOleObject
)) {
118 IOleObject_AddRef(iface
);
123 return E_NOINTERFACE
;
126 static ULONG WINAPI
oleobject_AddRef(IOleObject
*iface
)
131 static ULONG WINAPI
oleobject_Release(IOleObject
*iface
)
136 static HRESULT WINAPI
oleobject_SetClientSite(IOleObject
*iface
, IOleClientSite
*site
)
138 ok(0, "unexpected call\n");
142 static HRESULT WINAPI
oleobject_GetClientSite(IOleObject
*iface
, IOleClientSite
**site
)
144 ok(0, "unexpected call\n");
148 static HRESULT WINAPI
oleobject_SetHostNames(IOleObject
*iface
, LPCOLESTR containerapp
,
149 LPCOLESTR containerObj
)
151 ok(0, "unexpected call\n");
155 static HRESULT WINAPI
oleobject_Close(IOleObject
*iface
, DWORD saveopt
)
157 ok(0, "unexpected call\n");
161 static HRESULT WINAPI
oleobject_SetMoniker(IOleObject
*iface
, DWORD whichmoniker
, IMoniker
*mk
)
163 ok(0, "unexpected call\n");
167 static HRESULT WINAPI
oleobject_GetMoniker(IOleObject
*iface
, DWORD assign
, DWORD whichmoniker
,
170 ok(0, "unexpected call\n");
174 static HRESULT WINAPI
oleobject_InitFromData(IOleObject
*iface
, IDataObject
*dataobject
,
175 BOOL creation
, DWORD reserved
)
177 ok(0, "unexpected call\n");
181 static HRESULT WINAPI
oleobject_GetClipboardData(IOleObject
*iface
, DWORD reserved
, IDataObject
**dataobject
)
183 ok(0, "unexpected call\n");
187 static HRESULT WINAPI
oleobject_DoVerb(IOleObject
*iface
, LONG verb
, MSG
*msg
, IOleClientSite
*activesite
,
188 LONG index
, HWND hwndParent
, LPCRECT rect
)
190 ok(0, "unexpected call\n");
194 static BOOL g_enumverbsfail
;
195 static HRESULT WINAPI
oleobject_EnumVerbs(IOleObject
*iface
, IEnumOLEVERB
**enumverb
)
197 if (g_enumverbsfail
) {
201 *enumverb
= &enumverbs
;
205 static HRESULT WINAPI
oleobject_Update(IOleObject
*iface
)
207 ok(0, "unexpected call\n");
211 static HRESULT WINAPI
oleobject_IsUpToDate(IOleObject
*iface
)
213 ok(0, "unexpected call\n");
217 static HRESULT WINAPI
oleobject_GetUserClassID(IOleObject
*iface
, CLSID
*clsid
)
219 ok(0, "unexpected call\n");
223 static const WCHAR testW
[] = {'t','e','s','t',0};
224 static HRESULT WINAPI
oleobject_GetUserType(IOleObject
*iface
, DWORD formoftype
,
227 ok(formoftype
== USERCLASSTYPE_SHORT
, "got %d\n", formoftype
);
228 *usertype
= CoTaskMemAlloc(sizeof(testW
));
229 lstrcpyW(*usertype
, testW
);
233 static HRESULT WINAPI
oleobject_SetExtent(IOleObject
*iface
, DWORD aspect
, SIZEL
*size
)
235 ok(0, "unexpected call\n");
239 static HRESULT WINAPI
oleobject_GetExtent(IOleObject
*iface
, DWORD aspect
, SIZEL
*size
)
241 ok(0, "unexpected call\n");
245 static HRESULT WINAPI
oleobject_Advise(IOleObject
*iface
, IAdviseSink
*sink
, DWORD
*connection
)
247 ok(0, "unexpected call\n");
251 static HRESULT WINAPI
oleobject_Unadvise(IOleObject
*iface
, DWORD connection
)
253 ok(0, "unexpected call\n");
257 static HRESULT WINAPI
oleobject_EnumAdvise(IOleObject
*iface
, IEnumSTATDATA
**enumadvise
)
259 ok(0, "unexpected call\n");
263 static HRESULT WINAPI
oleobject_GetMiscStatus(IOleObject
*iface
, DWORD aspect
, DWORD
*status
)
265 ok(0, "unexpected call\n");
269 static HRESULT WINAPI
oleobject_SetColorScheme(IOleObject
*iface
, LOGPALETTE
*pal
)
271 ok(0, "unexpected call\n");
275 static IOleObjectVtbl oleobjectvtbl
= {
276 oleobject_QueryInterface
,
279 oleobject_SetClientSite
,
280 oleobject_GetClientSite
,
281 oleobject_SetHostNames
,
283 oleobject_SetMoniker
,
284 oleobject_GetMoniker
,
285 oleobject_InitFromData
,
286 oleobject_GetClipboardData
,
290 oleobject_IsUpToDate
,
291 oleobject_GetUserClassID
,
292 oleobject_GetUserType
,
297 oleobject_EnumAdvise
,
298 oleobject_GetMiscStatus
,
299 oleobject_SetColorScheme
302 static IOleObject oleobject
= { &oleobjectvtbl
};
304 static void test_OleUIAddVerbMenu(void)
306 static const WCHAR cadabraW
[] = {'c','a','d','a','b','r','a',0};
307 HMENU hMenu
, verbmenu
;
313 ret
= OleUIAddVerbMenuW(NULL
, NULL
, NULL
, 0, 0, 0, FALSE
, 0, NULL
);
314 ok(!ret
, "got %d\n", ret
);
316 verbmenu
= (HMENU
)0xdeadbeef;
317 ret
= OleUIAddVerbMenuW(NULL
, NULL
, NULL
, 0, 0, 0, FALSE
, 0, &verbmenu
);
318 ok(!ret
, "got %d\n", ret
);
319 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
322 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, NULL
, 0, 0, 0, FALSE
, 0, NULL
);
323 ok(!ret
, "got %d\n", ret
);
325 hMenu
= CreatePopupMenu();
327 memset(&info
, 0, sizeof(info
));
328 info
.cbSize
= sizeof(info
);
329 ret
= InsertMenuItemW(hMenu
, 0, TRUE
, &info
);
330 ok(ret
, "got %d\n", ret
);
332 count
= GetMenuItemCount(hMenu
);
333 ok(count
== 1, "got %d\n", count
);
336 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 0, 0, 0, FALSE
, 0, NULL
);
337 ok(!ret
, "got %d\n", ret
);
339 count
= GetMenuItemCount(hMenu
);
340 ok(count
== 1, "got %d\n", count
);
342 ret
= InsertMenuItemW(hMenu
, 0, TRUE
, &info
);
343 ok(ret
, "got %d\n", ret
);
345 count
= GetMenuItemCount(hMenu
);
346 ok(count
== 2, "got %d\n", count
);
348 verbmenu
= (HMENU
)0xdeadbeef;
350 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 1, 0, 0, FALSE
, 0, &verbmenu
);
351 ok(ret
, "got %d\n", ret
);
352 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
354 count
= GetMenuItemCount(hMenu
);
355 ok(count
== 2, "got %d\n", count
);
357 /* object doesn't support EnumVerbs() */
358 g_enumverbsfail
= TRUE
;
360 verbmenu
= (HMENU
)0xdeadbeef;
361 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 2, 0, 0, FALSE
, 0, &verbmenu
);
362 ok(!ret
, "got %d\n", ret
);
363 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
364 g_enumverbsfail
= FALSE
;
366 /* added disabled item */
367 memset(&info
, 0, sizeof(info
));
368 info
.cbSize
= sizeof(info
);
369 info
.fMask
= MIIM_STATE
|MIIM_SUBMENU
;
370 ret
= GetMenuItemInfoW(hMenu
, 2, TRUE
, &info
);
371 ok(ret
, "got %d\n", ret
);
372 ok(info
.fState
& MFS_DISABLED
, "got state 0x%08x\n", info
.fState
);
373 ok(info
.hSubMenu
== NULL
, "got submenu %p\n", info
.hSubMenu
);
375 count
= GetMenuItemCount(hMenu
);
376 ok(count
== 3, "got %d\n", count
);
378 /* now without object */
379 verbmenu
= (HMENU
)0xdeadbeef;
380 ret
= OleUIAddVerbMenuW(NULL
, testW
, hMenu
, 3, 42, 0, FALSE
, 0, &verbmenu
);
381 ok(!ret
, "got %d\n", ret
);
382 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
384 memset(&info
, 0, sizeof(info
));
385 info
.cbSize
= sizeof(info
);
386 info
.fMask
= MIIM_STATE
|MIIM_ID
|MIIM_STRING
|MIIM_SUBMENU
;
387 info
.dwTypeData
= buffW
;
388 info
.cch
= ARRAY_SIZE(buffW
);
389 ret
= GetMenuItemInfoW(hMenu
, 3, TRUE
, &info
);
390 ok(ret
, "got %d\n", ret
);
391 ok(info
.fState
== MF_GRAYED
, "got state 0x%08x\n", info
.fState
);
392 ok(info
.wID
== 42, "got id %d\n", info
.wID
);
393 ok(info
.hSubMenu
== NULL
, "got submenu %p\n", info
.hSubMenu
);
395 count
= GetMenuItemCount(hMenu
);
396 ok(count
== 4, "got %d\n", count
);
398 verbmenu
= (HMENU
)0xdeadbeef;
400 ret
= OleUIAddVerbMenuW(&oleobject
, NULL
, hMenu
, 4, 0, 0, FALSE
, 0, &verbmenu
);
401 ok(ret
, "got %d\n", ret
);
402 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
404 /* check newly added item */
405 memset(&info
, 0, sizeof(info
));
406 info
.cbSize
= sizeof(info
);
407 info
.fMask
= MIIM_STRING
|MIIM_STATE
|MIIM_SUBMENU
;
408 info
.dwTypeData
= buffW
;
409 info
.cch
= ARRAY_SIZE(buffW
);
410 ret
= GetMenuItemInfoW(hMenu
, 4, TRUE
, &info
);
411 ok(ret
, "got %d\n", ret
);
412 /* Item string contains verb, usertype and localized string for 'Object' word,
413 exact format depends on localization. */
414 ok(strstrW(buffW
, verbW
) != NULL
, "str %s\n", wine_dbgstr_w(buffW
));
415 ok(info
.fState
== 0, "got state 0x%08x\n", info
.fState
);
416 ok(info
.hSubMenu
== NULL
, "got submenu %p\n", info
.hSubMenu
);
418 count
= GetMenuItemCount(hMenu
);
419 ok(count
== 5, "got %d\n", count
);
423 /* try to add verb menu repeatedly, with same id */
424 hMenu
= CreatePopupMenu();
426 count
= GetMenuItemCount(hMenu
);
427 ok(count
== 0, "got %d\n", count
);
430 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 5, 10, TRUE
, 3, &verbmenu
);
431 ok(!ret
, "got %d\n", ret
);
432 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
434 count
= GetMenuItemCount(hMenu
);
435 ok(count
== 1, "got %d\n", count
);
438 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 5, 10, TRUE
, 3, &verbmenu
);
439 ok(!ret
, "got %d\n", ret
);
440 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
442 count
= GetMenuItemCount(hMenu
);
443 ok(count
== 1, "got %d\n", count
);
445 /* same position, different id */
447 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 6, 10, TRUE
, 3, &verbmenu
);
448 ok(!ret
, "got %d\n", ret
);
449 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
451 count
= GetMenuItemCount(hMenu
);
452 ok(count
== 1, "got %d\n", count
);
454 /* change added item string and state */
455 memset(&info
, 0, sizeof(info
));
456 info
.cbSize
= sizeof(info
);
457 info
.fMask
= MIIM_STRING
|MIIM_STATE
;
458 info
.fState
= MFS_ENABLED
;
459 info
.dwTypeData
= buffW
;
460 lstrcpyW(buffW
, cadabraW
);
461 ret
= SetMenuItemInfoW(hMenu
, 0, TRUE
, &info
);
462 ok(ret
, "got %d\n", ret
);
465 GetMenuStringW(hMenu
, 0, buffW
, ARRAY_SIZE(buffW
), MF_BYPOSITION
);
466 ok(!lstrcmpW(buffW
, cadabraW
), "got %s\n", wine_dbgstr_w(buffW
));
469 ret
= OleUIAddVerbMenuW(NULL
, NULL
, hMenu
, 0, 5, 10, TRUE
, 3, &verbmenu
);
470 ok(!ret
, "got %d\n", ret
);
471 ok(verbmenu
== NULL
, "got %p\n", verbmenu
);
473 memset(&info
, 0, sizeof(info
));
474 info
.cbSize
= sizeof(info
);
475 info
.fMask
= MIIM_STRING
|MIIM_STATE
;
477 info
.dwTypeData
= buffW
;
478 info
.cch
= ARRAY_SIZE(buffW
);
479 ret
= GetMenuItemInfoW(hMenu
, 0, TRUE
, &info
);
480 ok(ret
, "got %d\n", ret
);
481 ok(lstrcmpW(buffW
, cadabraW
), "got %s\n", wine_dbgstr_w(buffW
));
482 ok(info
.fState
== MF_GRAYED
, "got state 0x%08x\n", info
.fState
);
484 count
= GetMenuItemCount(hMenu
);
485 ok(count
== 1, "got %d\n", count
);
492 test_OleUIAddVerbMenu();