ReactOS 0.4.16-dev-2491-g3dc6630
menu.c
Go to the documentation of this file.
1/*
2 * Unit tests for menus
3 *
4 * Copyright 2005 Robert Shearman
5 * Copyright 2007 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <stdio.h>
24#include <string.h>
25#include <assert.h>
26
27#define OEMRESOURCE /* For OBM_MNARROW */
28
29#include "windef.h"
30#include "winbase.h"
31#include "wingdi.h"
32#include "winuser.h"
33
34#include "wine/test.h"
35
37
39{
40 switch (msg)
41 {
43 /* mark window as having entered menu loop */
45 /* exit menu modal loop
46 * ( A SendMessage does not work on NT3.51 here ) */
47 return PostMessageA(hwnd, WM_CANCELMODE, 0, 0);
48 }
50}
51
52/* globals to communicate between test and wndproc */
53
55static INT popmenu;
57static HMENU hMenus[4];
58
59#define MOD_SIZE 10
60#define MOD_NRMENUS 8
61
62 /* menu texts with their sizes */
63static struct {
65 SIZE size; /* size of text up to any \t */
66 SIZE sc_size; /* size of the short-cut */
67} MOD_txtsizes[] = {
68 { "Pinot &Noir" },
69 { "&Merlot\bF4" },
70 { "Shira&z\tAlt+S" },
71 { "" },
72 { NULL }
73};
74
75static unsigned int MOD_maxid;
77static int MOD_avec, MOD_hic;
78static int MOD_odheight;
88
89/* wndproc used by test_menu_ownerdraw() */
92{
93 static HMENU hmenupopup;
94 switch (msg)
95 {
98 hmenupopup = (HMENU) wparam;
99 break;
100 case WM_ENTERMENULOOP:
102 break;
103 case WM_INITMENU:
105 break;
106 case WM_MEASUREITEM:
107 {
109 if (winetest_debug > 1)
110 trace("WM_MEASUREITEM received data %Ix size %dx%d\n",
111 pmis->itemData, pmis->itemWidth, pmis->itemHeight);
112 ok( !wparam, "wrong wparam %Ix\n", wparam );
113 ok( pmis->CtlType == ODT_MENU, "wrong type %x\n", pmis->CtlType );
114 MOD_odheight = pmis->itemHeight;
115 pmis->itemWidth = MODsizes[pmis->itemData].cx;
116 pmis->itemHeight = MODsizes[pmis->itemData].cy;
117 return TRUE;
118 }
119 case WM_DRAWITEM:
120 {
121 DRAWITEMSTRUCT * pdis;
123 HPEN oldpen;
124 char chrs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
125 SIZE sz;
126 int i;
127 pdis = (DRAWITEMSTRUCT *) lparam;
128 if (winetest_debug > 1) {
129 RECT rc;
130 GetMenuItemRect( hwnd, (HMENU)pdis->hwndItem, pdis->itemData ,&rc);
131 trace("WM_DRAWITEM received hwnd %p hmenu %p itemdata %Id item %d rc %s itemrc: %s\n",
132 hwnd, pdis->hwndItem, pdis->itemData, pdis->itemID,
134 oldpen=SelectObject( pdis->hDC, GetStockObject(
136 Rectangle( pdis->hDC, pdis->rcItem.left,pdis->rcItem.top,
137 pdis->rcItem.right,pdis->rcItem.bottom );
138 SelectObject( pdis->hDC, oldpen);
139 }
140 ok( !wparam, "wrong wparam %Ix\n", wparam );
141 ok( pdis->CtlType == ODT_MENU, "wrong type %x\n", pdis->CtlType );
142 /* calculate widths of some menu texts */
143 if( ! MOD_txtsizes[0].size.cx)
144 for(i = 0; MOD_txtsizes[i].text; i++) {
145 char buf[100], *p;
146 RECT rc={0,0,0,0};
148 if( ( p = strchr( buf, '\t'))) {
149 *p = '\0';
150 DrawTextA( pdis->hDC, p + 1, -1, &rc,
152 MOD_txtsizes[i].sc_size.cx= rc.right - rc.left;
153 MOD_txtsizes[i].sc_size.cy= rc.bottom - rc.top;
154 }
155 DrawTextA( pdis->hDC, buf, -1, &rc,
157 MOD_txtsizes[i].size.cx= rc.right - rc.left;
158 MOD_txtsizes[i].size.cy= rc.bottom - rc.top;
159 }
160
161 if( pdis->itemData > MOD_maxid) return TRUE;
162 /* store the rectangle */
163 MOD_rc[pdis->itemData] = pdis->rcItem;
164 /* calculate average character width */
165 GetTextExtentPointA( pdis->hDC, chrs, 52, &sz );
166 MOD_avec = (sz.cx + 26)/52;
167 GetTextMetricsA( pdis->hDC, &tm);
168 MOD_hic = tm.tmHeight;
170 return TRUE;
171 }
172 case WM_ENTERIDLE:
173 {
175 ok( lparam || broken(!lparam), /* win9x, nt4 */
176 "Menu window handle is NULL!\n");
177 if( lparam) {
179 ok( hmenupopup == hmenu, "MN_GETHMENU returns %p expected %p\n",
180 hmenu, hmenupopup);
181 }
183 return TRUE;
184 }
185 case WM_MENUSELECT:
188 break;
189 }
191}
192
194{
195 WNDCLASSA wc =
196 {
197 0,
199 0,
200 0,
202 NULL,
204 (HBRUSH)(COLOR_BTNFACE+1),
205 NULL,
206 "WineMenuCheck",
207 };
208
210}
211
212static void test_getmenubarinfo(void)
213{
214 BOOL ret;
215 HMENU hmenu;
216 MENUBARINFO mbi;
217 RECT rcw, rci;
218 HWND hwnd;
219 INT err;
220
221 mbi.cbSize = sizeof(MENUBARINFO);
222
225 NULL, NULL, NULL, NULL);
226 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
227
228 /* no menu: getmenubarinfo should fail */
229 SetLastError(0xdeadbeef);
230 ret = GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mbi);
231 err = GetLastError();
232 ok(ret == FALSE, "GetMenuBarInfo should not have been successful\n");
233 ok(err == 0xdeadbeef, "err = %d\n", err);
234
235 /* create menubar, no items yet */
236 hmenu = CreateMenu();
237 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
238
239 ret = SetMenu(hwnd, hmenu);
240 ok(ret, "SetMenu failed with error %ld\n", GetLastError());
241
242 SetLastError(0xdeadbeef);
243 ret = GetMenuBarInfo(NULL, OBJID_CLIENT, 0, &mbi);
244 err = GetLastError();
245 ok(!ret, "GetMenuBarInfo succeeded\n");
246 ok(err == ERROR_INVALID_WINDOW_HANDLE, "err = %d\n", err);
247
248 SetLastError(0xdeadbeef);
249 ret = GetMenuBarInfo(hwnd, OBJID_CLIENT, 0, &mbi);
250 err = GetLastError();
251 ok(!ret, "GetMenuBarInfo succeeded\n");
252 ok(err==ERROR_INVALID_MENU_HANDLE || broken(err==0xdeadbeef) /* NT, W2K, XP */, "err = %d\n", err);
253
254 SetLastError(0xdeadbeef);
255 ret = GetMenuBarInfo(hwnd, OBJID_MENU, -1, &mbi);
256 err = GetLastError();
257 ok(ret == FALSE, "GetMenuBarInfo should have failed\n");
258 ok(err == 0xdeadbeef, "err = %d\n", err);
259
260 mbi.cbSize = 1000;
261 SetLastError(0xdeadbeef);
262 ret = GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mbi);
263 err = GetLastError();
264 ok(ret == FALSE, "GetMenuBarInfo should have failed\n");
265 ok(err == ERROR_INVALID_PARAMETER, "err = %d\n", err);
266 mbi.cbSize = sizeof(MENUBARINFO);
267
268 SetLastError(0xdeadbeef);
269 ret = GetMenuBarInfo(hwnd, 123, 0, &mbi);
270 err = GetLastError();
271 ok(ret == FALSE, "GetMenuBarInfo should have failed\n");
272 ok(err == 0xdeadbeef, "err = %d\n", err);
273
274 ret = GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mbi);
275 ok(ret, "GetMenuBarInfo failed with error %ld\n", GetLastError());
276
277 ok(mbi.rcBar.left == 0 && mbi.rcBar.top == 0 && mbi.rcBar.bottom == 0 && mbi.rcBar.right == 0,
278 "rcBar: Expected (0,0)-(0,0), got: %s\n", wine_dbgstr_rect(&mbi.rcBar));
279 ok(mbi.hMenu == hmenu, "hMenu: Got %p instead of %p\n",
280 mbi.hMenu, hmenu);
281 ok(mbi.fBarFocused == 0, "fBarFocused: Got %d instead of 0.\n", mbi.fBarFocused);
282 ok(mbi.fFocused == 0, "fFocused: Got %d instead of 0.\n", mbi.fFocused);
283
284 /* add some items */
285 ret = AppendMenuA(hmenu, MF_STRING , 100, "item 1");
286 ok(ret, "AppendMenu failed.\n");
287 ret = AppendMenuA(hmenu, MF_STRING , 101, "item 2");
288 ok(ret, "AppendMenu failed.\n");
289 ret = SetMenu(hwnd, hmenu);
290 ok(ret, "SetMenu failed with error %ld\n", GetLastError());
291
292 SetLastError(0xdeadbeef);
293 ret = GetMenuBarInfo(hwnd, OBJID_MENU, 200, &mbi);
294 err = GetLastError();
295 ok(ret == FALSE, "GetMenuBarInfo should have failed\n");
296 ok(err == 0xdeadbeef, "err = %d\n", err);
297
298 /* get info for the whole menu */
299 ret = GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mbi);
300 ok(ret, "GetMenuBarInfo failed with error %ld\n", GetLastError());
301
302 /* calculate menu rectangle, from window rectangle and the position of the first item */
303 ret = GetWindowRect(hwnd, &rcw);
304 ok(ret, "GetWindowRect failed.\n");
305 ret = GetMenuItemRect(hwnd, hmenu, 0, &rci);
306 ok(ret, "GetMenuItemRect failed.\n");
307 todo_wine ok(mbi.rcBar.left == rci.left && mbi.rcBar.top == rci.top &&
308 mbi.rcBar.bottom == rci.bottom && mbi.rcBar.right == rcw.right - rci.left + rcw.left,
309 "rcBar: Got %s instead of (%ld,%ld)-(%ld,%ld)\n", wine_dbgstr_rect(&mbi.rcBar),
310 rci.left, rci.top, rcw.right - rci.left + rcw.left, rci.bottom);
311 ok(mbi.hMenu == hmenu, "hMenu: Got %p instead of %p\n", mbi.hMenu, hmenu);
312 ok(mbi.fBarFocused == 0, "fBarFocused: got %d instead of 0\n", mbi.fBarFocused);
313 ok(mbi.fFocused == 0, "fFocused: got %d instead of 0\n", mbi.fFocused);
314
315 /* get info for item nr.2 */
316 ret = GetMenuBarInfo(hwnd, OBJID_MENU, 2, &mbi);
317 ok(ret, "GetMenuBarInfo failed with error %ld\n", GetLastError());
318 ret = GetMenuItemRect(hwnd, hmenu, 1, &rci);
319 ok(ret, "GetMenuItemRect failed.\n");
320 ok(EqualRect(&mbi.rcBar, &rci), "rcBar: Got %s instead of %s\n", wine_dbgstr_rect(&mbi.rcBar),
321 wine_dbgstr_rect(&rci));
322 ok(mbi.hMenu == hmenu, "hMenu: Got %p instead of %p\n", mbi.hMenu, hmenu);
323 ok(mbi.fBarFocused == 0, "fBarFocused: got %d instead of 0\n", mbi.fBarFocused);
324 ok(mbi.fFocused == 0, "fFocused: got %d instead of 0\n", mbi.fFocused);
325
327}
328
329static void test_GetMenuItemRect(void)
330{
331 HWND hwnd;
332 HMENU hmenu;
333 HMENU popup_hmenu;
334 RECT window_rect;
335 RECT item_rect;
336 POINT client_top_left;
337 INT caption_height;
338 BOOL ret;
339
341 NULL, NULL, NULL);
342 ok(hwnd != NULL, "CreateWindow failed with error %ld\n", GetLastError());
343 hmenu = CreateMenu();
344 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
345 popup_hmenu = CreatePopupMenu();
346 ok(popup_hmenu != NULL, "CreatePopupMenu failed with error %ld\n", GetLastError());
347 ret = AppendMenuA(popup_hmenu, MF_STRING, 0, "Popup");
348 ok(ret, "AppendMenu failed with error %ld\n", GetLastError());
349 ret = AppendMenuA(hmenu, MF_STRING | MF_POPUP, (UINT_PTR)popup_hmenu, "Menu");
350 ok(ret, "AppendMenu failed with error %ld\n", GetLastError());
351 ret = SetMenu(hwnd, hmenu);
352 ok(ret, "SetMenu failed with error %ld\n", GetLastError());
353
354 /* Get the menu item rectangle of the displayed sysmenu item */
355 ret = GetMenuItemRect(hwnd, hmenu, 0, &item_rect);
356 ok(ret, "GetMenuItemRect failed with error %ld\n", GetLastError());
357 GetWindowRect(hwnd, &window_rect);
358 /* Get the screen coordinate of the left top corner of the client rectangle */
359 client_top_left.x = 0;
360 client_top_left.y = 0;
361 MapWindowPoints(hwnd, 0, &client_top_left, 1);
363
364 ok(item_rect.left == client_top_left.x, "Expect item_rect.left %ld == %ld\n", item_rect.left, client_top_left.x);
365 ok(item_rect.right <= window_rect.right, "Expect item_rect.right %ld <= %ld\n", item_rect.right, window_rect.right);
366 /* A gap of 1 pixel is added deliberately in commit 75f9e64, so using equal operator would fail on Wine.
367 * Check that top and bottom are correct with 1 pixel margin tolerance */
368 ok(item_rect.top - (window_rect.top + caption_height) <= 1, "Expect item_rect.top %ld - %ld <= 1\n", item_rect.top,
369 window_rect.top + caption_height);
370 ok(item_rect.bottom - (client_top_left.y - 1) <= 1, "Expect item_rect.bottom %ld - %ld <= 1\n", item_rect.bottom,
371 client_top_left.y - 1);
372
373 /* Get the item rectangle of the not yet displayed popup menu item. */
374 ret = GetMenuItemRect(hwnd, popup_hmenu, 0, &item_rect);
375 ok(ret, "GetMenuItemRect failed with error %ld\n", GetLastError());
376 ok(item_rect.left == client_top_left.x, "Expect item_rect.left %ld == %ld\n", item_rect.left, client_top_left.x);
377 ok(item_rect.right == client_top_left.x, "Expect item_rect.right %ld == %ld\n", item_rect.right, client_top_left.x);
378 ok(item_rect.top == client_top_left.y, "Expect item_rect.top %ld == %ld\n", item_rect.top, client_top_left.y);
379 ok(item_rect.bottom == client_top_left.y, "Expect item_rect.bottom %ld == %ld\n", item_rect.bottom,
380 client_top_left.y);
381
383}
384
385static void test_system_menu(void)
386{
387 WCHAR testW[] = {'t','e','s','t',0};
388 BOOL ret;
389 HMENU menu;
390 HWND hwnd;
393 char buffer[80];
394 char found[0x200];
395 int i, res;
396
399 NULL, NULL, NULL, NULL);
400 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
402 ok( menu != NULL, "no system menu\n" );
403
404 for (i = 0xf000; i < 0xf200; i++)
405 {
406 memset( &info, 0xcc, sizeof(info) );
407 info.cbSize = sizeof(info);
409 info.dwTypeData = buffer;
410 info.cch = sizeof( buffer );
412 if (ret) trace( "found %x: '%s'\n", i, buffer );
413 switch (i)
414 {
415 case SC_RESTORE:
416 case SC_SIZE:
417 case SC_MOVE:
418 case SC_MINIMIZE:
419 case SC_MAXIMIZE:
420 case SC_CLOSE:
421 ok( ret, "%x menu item not found\n", i );
422 break;
423 case SC_SCREENSAVE+1: /* used for the 'About Wine' entry, don't test */
424 break;
425 default:
426 ok( !ret, "%x menu item found\n", i );
427 break;
428 }
429 found[i - 0xf000] = ret;
430 }
431
432 for (i = 0xf000; i < 0xf200; i++)
433 {
434 res = CheckMenuItem( menu, i, 0 );
435 if (res == -1) ok( !found[i - 0xf000], "could not check existent item %x\n", i );
436 else ok( found[i - 0xf000], "could check non-existent item %x\n", i );
437
438 res = EnableMenuItem( menu, i, 0 );
439 if (res == -1) ok( !found[i - 0xf000], "could not enable existent item %x\n", i );
440 else ok( found[i - 0xf000], "could enable non-existent item %x\n", i );
441
442 res = GetMenuState( menu, i, 0 );
443 if (res == -1) ok( !found[i - 0xf000], "could not get state existent item %x\n", i );
444 else ok( found[i - 0xf000], "could get state of non-existent item %x\n", i );
445
446 if (!found[i - 0xf000]) /* don't remove the existing ones */
447 {
448 ret = RemoveMenu( menu, i, 0 );
449 ok( !ret, "could remove non-existent item %x\n", i );
450 }
451
452 ret = ModifyMenuA( menu, i, 0, i, "test" );
453 if (i == SC_TASKLIST) ok( ret, "failed to modify SC_TASKLIST\n" );
454 else if (!ret) ok( !found[i - 0xf000], "could not modify existent item %x\n", i );
455 else ok( found[i - 0xf000], "could modify non-existent item %x\n", i );
456
457 ret = ModifyMenuW( menu, i, 0, i, testW );
458 if (i == SC_TASKLIST) ok( ret, "failed to modify SC_TASKLIST\n" );
459 else if (!ret) ok( !found[i - 0xf000], "could not modify existent item %x\n", i );
460 else ok( found[i - 0xf000], "could modify non-existent item %x\n", i );
461
462 ret = ModifyMenuA( menu, i, MF_BYPOSITION, i, "test" );
463 ok( !ret, "could modify non-existent item %x\n", i );
464
465 strcpy( buffer, "test" );
466 memset( &info, 0xcc, sizeof(info) );
467 info.cbSize = sizeof(info);
468 info.fMask = MIIM_STRING | MIIM_ID;
469 info.wID = i;
470 info.dwTypeData = buffer;
471 info.cch = strlen( buffer );
473 if (i == SC_TASKLIST) ok( ret, "failed to set SC_TASKLIST\n" );
474 else if (!ret) ok( !found[i - 0xf000], "could not set existent item %x\n", i );
475 else ok( found[i - 0xf000], "could set non-existent item %x\n", i );
477 ok( !ret, "could modify non-existent item %x\n", i );
478
479 memset( &infoW, 0xcc, sizeof(infoW) );
480 infoW.cbSize = sizeof(infoW);
481 infoW.fMask = MIIM_STRING | MIIM_ID;
482 infoW.wID = i;
483 infoW.dwTypeData = testW;
484 infoW.cch = lstrlenW( testW );
486 if (i == SC_TASKLIST) ok( ret, "failed to set SC_TASKLIST\n" );
487 else if (!ret) ok( !found[i - 0xf000], "could not set existent item %x\n", i );
488 else ok( found[i - 0xf000], "could set non-existent item %x\n", i );
490 ok( !ret, "could modify non-existent item %x\n", i );
491 }
492
493 /* confirm that SC_TASKLIST still does not exist */
494 for (i = 0xf000; i < 0xf200; i++)
495 {
496 memset( &info, 0xcc, sizeof(info) );
497 info.cbSize = sizeof(info);
499 info.dwTypeData = buffer;
500 info.cch = sizeof( buffer );
502 switch (i)
503 {
504 case SC_RESTORE:
505 case SC_SIZE:
506 case SC_MOVE:
507 case SC_MINIMIZE:
508 case SC_MAXIMIZE:
509 case SC_CLOSE:
510 ok( ret, "%x menu item not found\n", i );
511 break;
512 case SC_SCREENSAVE+1: /* used for the 'About Wine' entry, don't test */
513 break;
514 default:
515 ok( !ret, "%x menu item found\n", i );
516 break;
517 }
518 }
519
520 /* now a normal (non-system) menu */
521
522 menu = CreateMenu();
523 ok( menu != NULL, "CreateMenu failed with error %ld\n", GetLastError() );
524
526 ok( res == -1, "CheckMenuItem succeeded\n" );
528 ok( res == -1, "EnableMenuItem succeeded\n" );
530 ok( res == -1, "GetMenuState succeeded\n" );
532 ok( !ret, "RemoveMenu succeeded\n" );
533 ret = ModifyMenuA( menu, SC_TASKLIST, 0, SC_TASKLIST, "test" );
534 ok( ret, "ModifyMenuA failed err %ld\n", GetLastError() );
536 ok( ret, "ModifyMenuW failed err %ld\n", GetLastError() );
537 ret = ModifyMenuA( menu, SC_TASKLIST-1, 0, SC_TASKLIST, "test" );
538 ok( !ret, "ModifyMenu succeeded on SC_TASKLIST-1\n" );
539 strcpy( buffer, "test" );
540 memset( &info, 0xcc, sizeof(info) );
541 info.cbSize = sizeof(info);
542 info.fMask = MIIM_STRING | MIIM_ID;
543 info.wID = SC_TASKLIST;
544 info.dwTypeData = buffer;
545 info.cch = strlen( buffer );
547 ok( ret, "failed to set SC_TASKLIST\n" );
549 ok( !ret, "succeeded setting SC_TASKLIST+1\n" );
551 ok( !ret, "succeeded setting by position\n" );
552
553 memset( &infoW, 0xcc, sizeof(infoW) );
554 infoW.cbSize = sizeof(infoW);
555 infoW.fMask = MIIM_STRING | MIIM_ID;
556 infoW.wID = SC_TASKLIST;
557 infoW.dwTypeData = testW;
558 infoW.cch = lstrlenW( testW );
560 ok( ret, "failed to set SC_TASKLIST\n" );
562 ok( !ret, "succeeded setting SC_TASKLIST+1\n" );
564 ok( !ret, "succeeded setting by position\n" );
565
566 DestroyMenu( menu );
568}
569
570/* demonstrates that windows locks the menu object so that it is still valid
571 * even after a client calls DestroyMenu on it */
573{
574 BOOL ret;
575 HMENU hmenu;
578 NULL, NULL, NULL, NULL);
579 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
580 hmenu = CreateMenu();
581 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
582 ret = InsertMenuA(hmenu, 0, MF_STRING, 0, "&Test");
583 ok(ret, "InsertMenu failed with error %ld\n", GetLastError());
584 ret = SetMenu(hwnd, hmenu);
585 ok(ret, "SetMenu failed with error %ld\n", GetLastError());
587 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
588
590 ok(ret, "DrawMenuBar failed with error %ld\n", GetLastError());
592 ok(!ret || broken(ret) /* nt4 */, "Menu handle should have been destroyed\n");
593
595 /* did we process the WM_INITMENU message? */
597 todo_wine {
598 ok(ret, "WM_INITMENU should have been sent\n");
599 }
600
602}
603
604/* demonstrates that subpopup's are locked
605 * even after a client calls DestroyMenu on it */
607{
608 HWND hwndmenu;
609 switch (msg)
610 {
611 case WM_ENTERIDLE:
612 hwndmenu = GetCapture();
613 if( hwndmenu) {
614 PostMessageA( hwndmenu, WM_KEYDOWN, VK_DOWN, 0);
615 PostMessageA( hwndmenu, WM_KEYDOWN, VK_RIGHT, 0);
616 PostMessageA( hwndmenu, WM_KEYDOWN, VK_RETURN, 0);
617 }
618 }
620}
621
623{
624 BOOL ret;
625 HMENU hmenu, hsubmenu;
626 MENUINFO mi = { sizeof( MENUINFO)};
627 MENUITEMINFOA mii = { sizeof( MENUITEMINFOA)};
628 HWND hwnd;
629 const int itemid = 0x1234567;
630
631 /* create window, popupmenu with one subpopup */
634 NULL, NULL, NULL, NULL);
635 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
638 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
639 hsubmenu = CreatePopupMenu();
640 ok(hsubmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
642 "PopUpLockTest");
643 ok(ret, "InsertMenu failed with error %ld\n", GetLastError());
644 ret = InsertMenuA(hsubmenu, 0, MF_BYPOSITION | MF_STRING, itemid, "PopUpMenu");
645 ok(ret, "InsertMenu failed with error %ld\n", GetLastError());
646 /* first some tests that all this functions properly */
647 mii.fMask = MIIM_SUBMENU;
648 ret = GetMenuItemInfoA( hmenu, 0, TRUE, &mii);
649 ok( ret, "GetMenuItemInfo failed error %ld\n", GetLastError());
650 ok( mii.hSubMenu == hsubmenu, "submenu is %p\n", mii.hSubMenu);
651 mi.fMask |= MIM_STYLE;
652 ret = GetMenuInfo( hsubmenu, &mi);
653 ok( ret , "GetMenuInfo returned 0 with error %ld\n", GetLastError());
654 ret = IsMenu( hsubmenu);
655 ok( ret , "Menu handle is not valid\n");
656
657 ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
658 ok( ret == itemid , "TrackPopupMenu returned %d error is %ld\n", ret, GetLastError());
659
660 /* then destroy the sub-popup */
661 ret = DestroyMenu( hsubmenu);
662 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
663 /* and repeat the tests */
664 mii.fMask = MIIM_SUBMENU;
665 ret = GetMenuItemInfoA( hmenu, 0, TRUE, &mii);
666 ok( ret, "GetMenuItemInfo failed error %ld\n", GetLastError());
667 /* GetMenuInfo fails now */
668 ok( mii.hSubMenu == hsubmenu, "submenu is %p\n", mii.hSubMenu);
669 mi.fMask |= MIM_STYLE;
670 ret = GetMenuInfo( hsubmenu, &mi);
671 ok( !ret , "GetMenuInfo should have failed\n");
672 /* IsMenu says it is not */
673 ret = IsMenu( hsubmenu);
674 ok( !ret , "Menu handle should be invalid\n");
675
676 /* but TrackPopupMenu still works! */
677 ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
678 todo_wine {
679 ok( ret == itemid , "TrackPopupMenu returned %d error is %ld\n", ret, GetLastError());
680 }
681
682 /* clean up */
685}
686
687static void test_menu_ownerdraw(void)
688{
689 int i,j,k;
690 BOOL ret;
691 HMENU hmenu;
692 MENUITEMINFOA mii;
693 LONG leftcol;
696 NULL, NULL, NULL, NULL);
697 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
698 if( !hwnd) return;
701 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
702 if( !hmenu) { DestroyWindow(hwnd);return;}
703 k=0;
704 for( j=0;j<2;j++) /* create columns */
705 for(i=0;i<2;i++) { /* create rows */
707 (i==0 ? MF_MENUBREAK : 0), k, (LPCSTR)MAKEINTRESOURCE(k));
708 k++;
709 ok( ret, "AppendMenu failed for %d\n", k-1);
710 }
711 MOD_maxid = k-1;
713 /* display the menu */
714 TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
715
716 /* columns have a 4 pixel gap between them */
717 ok( MOD_rc[0].right + 4 == MOD_rc[2].left,
718 "item rectangles are not separated by 4 pixels space\n");
719 /* height should be what the MEASUREITEM message has returned */
720 ok( MOD_rc[0].bottom - MOD_rc[0].top == MOD_SIZE,
721 "menu item has wrong height: %ld should be %d\n",
722 MOD_rc[0].bottom - MOD_rc[0].top, MOD_SIZE);
723 /* no gaps between the rows */
724 ok( MOD_rc[0].bottom - MOD_rc[1].top == 0,
725 "There should not be a space between the rows, gap is %ld\n",
726 MOD_rc[0].bottom - MOD_rc[1].top);
727 /* test the correct value of the item height that was sent
728 * by the WM_MEASUREITEM message */
729 ok( MOD_odheight == HIWORD( GetDialogBaseUnits()) || /* WinNT,2k,XP */
730 MOD_odheight == MOD_hic, /* Win95,98,ME */
731 "Wrong height field in MEASUREITEMSTRUCT, expected %d or %d actual %d\n",
733 /* test what MF_MENUBREAK did at the first position. Also show
734 * that an MF_SEPARATOR is ignored in the height calculation. */
735 leftcol= MOD_rc[0].left;
737 /* display the menu */
738 TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
739 /* left should be 4 pixels less now */
740 ok( leftcol == MOD_rc[0].left + 4,
741 "columns should be 4 pixels to the left (actual %ld).\n",
742 leftcol - MOD_rc[0].left);
743 /* test width */
744 ok( MOD_rc[0].right - MOD_rc[0].left == 2 * MOD_avec + MOD_SIZE,
745 "width of owner drawn menu item is wrong. Got %ld expected %d\n",
746 MOD_rc[0].right - MOD_rc[0].left , 2*MOD_avec + MOD_SIZE);
747 /* and height */
748 ok( MOD_rc[0].bottom - MOD_rc[0].top == MOD_SIZE,
749 "Height is incorrect. Got %ld expected %d\n",
750 MOD_rc[0].bottom - MOD_rc[0].top, MOD_SIZE);
751
752 /* test owner-drawn callback bitmap */
754 mii.cbSize = sizeof(mii);
756 if (GetMenuItemInfoA( hmenu, 1, TRUE, &mii ))
757 {
758 ok( mii.fType == MFT_BITMAP, "wrong type %x\n", mii.fType );
759 ok( mii.wID == 1, "wrong id %x\n", mii.wID );
760 ok( mii.hbmpItem == HBMMENU_CALLBACK, "wrong data %p\n", mii.hbmpItem );
761 }
762 TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
763
764 /* test width/height of an ownerdraw menu bar as well */
766 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
767 hmenu = CreateMenu();
768 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
769 if( !hmenu) { DestroyWindow(hwnd);return;}
770 MOD_maxid=1;
771 for(i=0;i<2;i++) {
773 ok( ret, "AppendMenu failed for %d\n", i);
774 }
775 ret = SetMenu( hwnd, hmenu);
776 UpdateWindow( hwnd); /* hack for wine to draw the window + menu */
777 ok(ret, "SetMenu failed with error %ld\n", GetLastError());
778 /* test width */
779 ok( MOD_rc[0].right - MOD_rc[0].left == 2 * MOD_avec + MOD_SIZE,
780 "width of owner drawn menu item is wrong. Got %ld expected %d\n",
781 MOD_rc[0].right - MOD_rc[0].left , 2*MOD_avec + MOD_SIZE);
782 /* test height */
784 "Height of owner drawn menu item is wrong. Got %ld expected %d\n",
786
787 /* clean up */
789 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
791}
792
793/* helper for test_menu_bmp_and_string() */
794static void test_mbs_help( int ispop, int hassub, int mnuopt,
795 HWND hwnd, int arrowwidth, int count, HBITMAP hbmp,
796 SIZE bmpsize, LPCSTR text, SIZE size, SIZE sc_size)
797{
798 BOOL ret;
799 HMENU hmenu, submenu;
800 MENUITEMINFOA mii={ sizeof( MENUITEMINFOA )};
801 MENUINFO mi;
802 RECT rc;
803 CHAR text_copy[16];
804 int hastab, expect;
805 BOOL failed = FALSE;
806
809 mii.fType = 0;
810 /* check the menu item unless MNS_CHECKORBMP is set */
811 mii.fState = (mnuopt != 2 ? MFS_CHECKED : MFS_UNCHECKED);
812 mii.dwItemData =0;
813 MODsizes[0] = bmpsize;
814 hastab = 0;
815 if( text ) {
816 char *p;
817 mii.fMask |= MIIM_STRING;
818 strcpy(text_copy, text);
819 mii.dwTypeData = text_copy; /* structure member declared non-const */
820 if( ( p = strchr( text, '\t'))) {
821 hastab = *(p + 1) ? 2 : 1;
822 }
823 }
824 /* tabs don't make sense in menubars */
825 if(hastab && !ispop) return;
826 if( hbmp) {
827 mii.fMask |= MIIM_BITMAP;
828 mii.hbmpItem = hbmp;
829 }
830 submenu = CreateMenu();
831 ok( submenu != 0, "CreateMenu failed with error %ld\n", GetLastError());
832 if( ispop)
834 else
835 hmenu = CreateMenu();
836 ok( hmenu != 0, "Create{Popup}Menu failed with error %ld\n", GetLastError());
837 if( hassub) {
838 mii.fMask |= MIIM_SUBMENU;
839 mii.hSubMenu = submenu;
840 }
841 if( mnuopt) {
842 mi.cbSize = sizeof(mi);
843 mi.fMask = MIM_STYLE;
844 GetMenuInfo( hmenu, &mi);
845 if( mnuopt) mi.dwStyle |= mnuopt == 1 ? MNS_NOCHECK : MNS_CHECKORBMP;
846 ret = SetMenuInfo( hmenu, &mi);
847 ok( ret, "SetMenuInfo failed with error %ld\n", GetLastError());
848 }
849 ret = InsertMenuItemA( hmenu, 0, FALSE, &mii);
850 ok( ret, "InsertMenuItem failed with error %ld\n", GetLastError());
851 failed = !ret;
852 if( winetest_debug) {
853 HDC hdc=GetDC(hwnd);
854 RECT rc = {100, 50, 400, 70};
855 char buf[100];
856
857 sprintf( buf,"%d text \"%s\" mnuopt %d", count, text ? text: "(nil)", mnuopt);
858 FillRect( hdc, &rc, (HBRUSH) COLOR_WINDOW);
859 TextOutA( hdc, 10, 50, buf, strlen( buf));
860 ReleaseDC( hwnd, hdc);
861 }
862 if(ispop)
863 TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
864 else {
865 ret = SetMenu( hwnd, hmenu);
866 ok(ret, "SetMenu failed with error %ld\n", GetLastError());
868 }
869 ret = GetMenuItemRect( hwnd, hmenu, 0, &rc);
870 ok(ret, "GetMenuItemRect failed with error %ld\n", GetLastError());
871
872 if (0) /* comment out menu size checks, behavior is different in almost every Windows version */
873 /* the tests should however succeed on win2000, XP and Wine (at least up to 1.1.15) */
874 /* with a variety of dpis and desktop font sizes */
875 {
876 /* check menu width */
877 if( ispop)
878 expect = ( text || hbmp ?
879 4 + (mnuopt != 1 ? GetSystemMetrics(SM_CXMENUCHECK) : 0)
880 : 0) +
881 arrowwidth + MOD_avec + (hbmp ?
882 ((INT_PTR)hbmp<0||(INT_PTR)hbmp>12 ? bmpsize.cx + 2 : GetSystemMetrics( SM_CXMENUSIZE) + 2)
883 : 0) +
884 (text && hastab ? /* TAB space */
885 MOD_avec + ( hastab==2 ? sc_size.cx : 0) : 0) +
886 (text ? 2 + (text[0] ? size.cx :0): 0) ;
887 else
888 expect = !(text || hbmp) ? 0 :
889 ( hbmp ? (text ? 2:0) + bmpsize.cx : 0 ) +
890 (text ? 2 * MOD_avec + (text[0] ? size.cx :0): 0) ;
891 ok( rc.right - rc.left == expect,
892 "menu width wrong, got %ld expected %d\n", rc.right - rc.left, expect);
893 failed = failed || !(rc.right - rc.left == expect);
894 /* check menu height */
895 if( ispop)
896 expect = max( ( !(text || hbmp) ? GetSystemMetrics( SM_CYMENUSIZE)/2 : 0),
897 max( (text ? max( 2 + size.cy, MOD_hic + 4) : 0),
898 (hbmp ?
899 ((INT_PTR)hbmp<0||(INT_PTR)hbmp>12 ?
900 bmpsize.cy + 2
902 : 0)));
903 else
905 max( GetSystemMetrics( SM_CYMENU) - 1, (hbmp ? bmpsize.cy : 0)));
906 ok( rc.bottom - rc.top == expect,
907 "menu height wrong, got %ld expected %d (%d)\n",
909 failed = failed || !(rc.bottom - rc.top == expect);
911 /* check the position of the bitmap */
912 /* horizontal */
913 if (!ispop)
914 expect = 3;
915 else if (mnuopt == 0)
917 else if (mnuopt == 1)
918 expect = 4;
919 else /* mnuopt == 2 */
920 expect = 2;
921 ok( expect == MOD_rc[0].left,
922 "bitmap left is %ld expected %d\n", MOD_rc[0].left, expect);
923 failed = failed || !(expect == MOD_rc[0].left);
924 /* vertical */
925 expect = (rc.bottom - rc.top - MOD_rc[0].bottom + MOD_rc[0].top) / 2;
926 ok( expect == MOD_rc[0].top,
927 "bitmap top is %ld expected %d\n", MOD_rc[0].top, expect);
928 failed = failed || !(expect == MOD_rc[0].top);
929 }
930 }
931 /* if there was a failure, report details */
932 if( failed) {
933 trace("*** count %d %s text \"%s\" bitmap %p bmsize %ld,%ld textsize %ld+%ld,%ld mnuopt %d hastab %d\n",
934 count, (ispop? "POPUP": "MENUBAR"),text ? text: "(nil)", hbmp, bmpsize.cx, bmpsize.cy,
935 size.cx, size.cy, sc_size.cx, mnuopt, hastab);
936 trace(" check %d,%d arrow %d avechar %d\n",
939 if( hbmp == HBMMENU_CALLBACK)
940 trace( " rc %s bmp.rc %s\n", wine_dbgstr_rect(&rc), wine_dbgstr_rect(&MOD_rc[0]));
941 }
942 /* clean up */
943 ret = DestroyMenu(submenu);
944 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
946 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
947}
948
949
951{
952 BYTE bmfill[300];
953 HBITMAP hbm_arrow;
954 BITMAP bm;
955 INT arrowwidth;
956 HWND hwnd;
957 HMENU hsysmenu;
958 MENUINFO mi= {sizeof(MENUINFO)};
959 MENUITEMINFOA mii= {sizeof(MENUITEMINFOA)};
960 int count, szidx, txtidx, bmpidx, hassub, mnuopt, ispop;
961 BOOL got;
962
963 memset( bmfill, 0xcc, sizeof( bmfill));
966 NULL, NULL, NULL, NULL);
967 hbm_arrow = LoadBitmapA( 0, (LPCSTR)OBM_MNARROW);
968 GetObjectA( hbm_arrow, sizeof(bm), &bm);
969 arrowwidth = bm.bmWidth;
970 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
971 if( !hwnd) return;
972 /* test system menu */
973 hsysmenu = GetSystemMenu( hwnd, FALSE);
974 ok( hsysmenu != NULL, "GetSystemMenu failed with error %ld\n", GetLastError());
975 mi.fMask = MIM_STYLE;
976 mi.dwStyle = 0;
977 got = GetMenuInfo( hsysmenu, &mi);
978 ok( got, "GetMenuInfo failed gle=%ld\n", GetLastError());
979 ok( MNS_CHECKORBMP == mi.dwStyle, "System Menu Style is %08lx, without the bit %08x\n",
980 mi.dwStyle, MNS_CHECKORBMP);
981 mii.fMask = MIIM_BITMAP;
982 mii.hbmpItem = NULL;
983 got = GetMenuItemInfoA( hsysmenu, SC_CLOSE, FALSE, &mii);
984 ok( got, "GetMenuItemInfoA failed gle=%ld\n", GetLastError());
985 ok( HBMMENU_POPUP_CLOSE == mii.hbmpItem, "Item info did not get the right hbitmap: got %p expected %p\n",
986 mii.hbmpItem, HBMMENU_POPUP_CLOSE);
987
988 memset(&mii, 0x81, sizeof(mii));
989 mii.cbSize = sizeof(mii);
991 mii.dwTypeData = (LPSTR)bmfill;
992 mii.cch = sizeof(bmfill);
993 mii.dwItemData = 0x81818181;
994 got = GetMenuItemInfoA(hsysmenu, SC_RESTORE, FALSE, &mii);
995 ok(got, "GetMenuItemInfo failed\n");
996 ok((mii.fType & ~(MFT_RIGHTJUSTIFY|MFT_RIGHTORDER)) == MFT_STRING, "expected MFT_STRING, got %#x\n", mii.fType);
997 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
998 ok(mii.wID == SC_RESTORE, "expected SC_RESTORE, got %#x\n", mii.wID);
999 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
1000 ok(mii.dwItemData == 0, "expected 0, got %#Ix\n", mii.dwItemData);
1001 ok(mii.dwTypeData == (LPSTR)bmfill, "expected %p, got %p\n", bmfill, mii.dwTypeData);
1002 ok(mii.cch != 0, "cch should not be 0\n");
1003 ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
1004
1005 mii.cbSize = sizeof(mii);
1006 mii.fMask = MIIM_TYPE;
1007 mii.hbmpItem = (HBITMAP)0x81818181;
1008 got = GetMenuItemInfoA(hsysmenu, SC_CLOSE, FALSE, &mii);
1009 ok(got, "GetMenuItemInfo failed\n");
1010 ok((mii.fType & ~(MFT_RIGHTJUSTIFY|MFT_RIGHTORDER)) == MFT_STRING, "expected MFT_STRING, got %#x\n", mii.fType);
1011 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
1012 ok(mii.wID == SC_RESTORE, "expected SC_RESTORE, got %#x\n", mii.wID);
1013 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
1014 ok(mii.dwItemData == 0, "expected 0, got %#Ix\n", mii.dwItemData);
1015 ok(mii.dwTypeData == (LPSTR)bmfill, "expected %p, got %p\n", bmfill, mii.dwTypeData);
1016 ok(mii.cch != 0, "cch should not be 0\n");
1017 ok(mii.hbmpItem == HBMMENU_POPUP_CLOSE, "expected HBMMENU_POPUP_CLOSE, got %p\n", mii.hbmpItem);
1018
1020
1021 if( winetest_debug)
1022 trace(" check %d,%d arrow %d avechar %d\n",
1025 count = 0;
1026 MOD_maxid = 0;
1027 for( ispop=1; ispop >= 0; ispop--){
1028 static SIZE bmsizes[]= {
1029 {10,10},{38,38},{1,30},{55,5}};
1030 for( szidx=0; szidx < ARRAY_SIZE(bmsizes); szidx++) {
1031 HBITMAP hbm = CreateBitmap( bmsizes[szidx].cx, bmsizes[szidx].cy,1,1,bmfill);
1033 ok( hbm != 0, "CreateBitmap failed err %ld\n", GetLastError());
1034 for( txtidx = 0; txtidx < ARRAY_SIZE(MOD_txtsizes); txtidx++) {
1035 for( hassub = 0; hassub < 2 ; hassub++) { /* add submenu item */
1036 for( mnuopt = 0; mnuopt < 3 ; mnuopt++){ /* test MNS_NOCHECK/MNS_CHECKORBMP */
1037 for( bmpidx = 0; bmpidx <ARRAY_SIZE(bitmaps); bmpidx++) {
1038 /* no need to test NULL bitmaps of several sizes */
1039 if( !bitmaps[bmpidx] && szidx > 0) continue;
1040 /* the HBMMENU_POPUP not to test for menu bars */
1041 if( !ispop &&
1042 bitmaps[bmpidx] >= HBMMENU_POPUP_CLOSE &&
1043 bitmaps[bmpidx] <= HBMMENU_POPUP_MINIMIZE) continue;
1044 if( !ispop && hassub) continue;
1045 test_mbs_help( ispop, hassub, mnuopt,
1046 hwnd, arrowwidth, ++count,
1047 bitmaps[bmpidx],
1048 bmsizes[szidx],
1049 MOD_txtsizes[txtidx].text,
1050 MOD_txtsizes[txtidx].size,
1051 MOD_txtsizes[txtidx].sc_size);
1052 }
1053 }
1054 }
1055 }
1056 DeleteObject( hbm);
1057 }
1058 }
1059 /* clean up */
1061}
1062
1063static void test_menu_add_string( void )
1064{
1065 HMENU hmenu;
1067 BOOL rc;
1068 int ret;
1069
1070 char string[0x80];
1071 char string2[0x80];
1072
1073 char strback[0x80];
1074 WCHAR strbackW[0x80];
1075 static CHAR blah[] = "blah";
1076 static const WCHAR expectedString[] = {'D','u','m','m','y',' ','s','t','r','i','n','g', 0};
1077
1078 hmenu = CreateMenu();
1079
1080 memset( &info, 0, sizeof info );
1081 info.cbSize = sizeof info;
1083 info.dwTypeData = blah;
1084 info.cch = 6;
1085 info.dwItemData = 0;
1086 info.wID = 1;
1087 info.fState = 0;
1089
1090 memset( &info, 0, sizeof info );
1091 info.cbSize = sizeof info;
1093 info.dwTypeData = string;
1094 info.cch = sizeof string;
1095 string[0] = 0;
1097
1098 ok( !strcmp( string, "blah" ), "menu item name differed\n");
1099
1100 /* Test combination of ownerdraw and strings with GetMenuItemString(A/W) */
1101 strcpy(string, "Dummy string");
1102 memset(&info, 0x00, sizeof(info));
1103 info.cbSize= sizeof(MENUITEMINFOA);
1104 info.fMask= MIIM_FTYPE | MIIM_STRING; /* Set OwnerDraw + typeData */
1105 info.fType= MFT_OWNERDRAW;
1106 info.dwTypeData= string;
1107 rc = InsertMenuItemA( hmenu, 0, TRUE, &info );
1108 ok (rc, "InsertMenuItem failed\n");
1109
1110 strcpy(string,"Garbage");
1111 ok (GetMenuStringA( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n");
1112 ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n");
1113
1114 ret = GetMenuStringW( hmenu, 0, strbackW, 99, MF_BYPOSITION );
1115 ok (ret, "GetMenuStringW on ownerdraw entry failed\n");
1116 ok (!lstrcmpW( strbackW, expectedString ), "Menu text from Unicode version incorrect\n");
1117
1118 /* Just try some invalid parameter tests */
1119 SetLastError(0xdeadbeef);
1120 rc = SetMenuItemInfoA( hmenu, 0, TRUE, NULL );
1121 ret = GetLastError();
1122 ok (!rc, "SetMenuItemInfoA succeeded unexpectedly\n");
1123 ok (ret == ERROR_INVALID_PARAMETER, "Expected 87, got %d\n", ret);
1124
1125 SetLastError(0xdeadbeef);
1126 rc = SetMenuItemInfoA( hmenu, 0, FALSE, NULL );
1127 ret = GetLastError();
1128 ok (!rc, "SetMenuItemInfoA succeeded unexpectedly\n");
1129 ok (ret == ERROR_INVALID_PARAMETER, "Expected 87, got %d\n", ret);
1130
1131 /* Just change ftype to string and see what text is stored */
1132 memset(&info, 0x00, sizeof(info));
1133 info.cbSize= sizeof(MENUITEMINFOA);
1134 info.fMask= MIIM_FTYPE; /* Set string type */
1135 info.fType= MFT_STRING;
1136 info.dwTypeData= (char *)0xdeadbeef;
1137 rc = SetMenuItemInfoA( hmenu, 0, TRUE, &info );
1138 ok (rc, "SetMenuItemInfo failed\n");
1139
1140 /* Did we keep the old dwTypeData? */
1141 ok (GetMenuStringA( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n");
1142 ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n");
1143
1144 /* Ensure change to bitmap type fails */
1145 memset(&info, 0x00, sizeof(info));
1146 info.cbSize= sizeof(MENUITEMINFOA);
1147 info.fMask= MIIM_FTYPE; /* Set as bitmap type */
1148 info.fType= MFT_BITMAP;
1149 info.dwTypeData= (char *)0xdeadbee2;
1150 rc = SetMenuItemInfoA( hmenu, 0, TRUE, &info );
1151 ok (!rc, "SetMenuItemInfo unexpectedly worked\n");
1152
1153 /* Just change ftype back and ensure data hasn't been freed */
1154 info.fType= MFT_OWNERDRAW; /* Set as ownerdraw type */
1155 info.dwTypeData= (char *)0xdeadbee3;
1156 rc = SetMenuItemInfoA( hmenu, 0, TRUE, &info );
1157 ok (rc, "SetMenuItemInfo failed\n");
1158
1159 /* Did we keep the old dwTypeData? */
1160 ok (GetMenuStringA( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n");
1161 ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n");
1162
1163 /* Just change string value (not type) */
1164 memset(&info, 0x00, sizeof(info));
1165 info.cbSize= sizeof(MENUITEMINFOA);
1166 info.fMask= MIIM_STRING; /* Set typeData */
1167 strcpy(string2, "string2");
1168 info.dwTypeData= string2;
1169 rc = SetMenuItemInfoA( hmenu, 0, TRUE, &info );
1170 ok (rc, "SetMenuItemInfo failed\n");
1171
1172 ok (GetMenuStringA( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n");
1173 ok (!strcmp( strback, "string2" ), "Menu text from Ansi version incorrect\n");
1174
1175 /* crashes with wine 0.9.5 */
1176 memset(&info, 0x00, sizeof(info));
1177 info.cbSize= sizeof(MENUITEMINFOA);
1178 info.fMask= MIIM_FTYPE | MIIM_STRING; /* Set OwnerDraw + typeData */
1179 info.fType= MFT_OWNERDRAW;
1180 rc = InsertMenuItemA( hmenu, 0, TRUE, &info );
1181 ok (rc, "InsertMenuItem failed\n");
1183 "GetMenuString on ownerdraw entry succeeded.\n");
1185 ok (!ret, "GetMenuStringW on ownerdraw entry succeeded.\n");
1186
1187 DestroyMenu( hmenu );
1188}
1189
1191 HMENU submenu, HBITMAP checked, HBITMAP unchecked, ULONG_PTR data,
1192 void *type_data, UINT len, HBITMAP item, BOOL expect )
1193{
1195 BOOL ret;
1196
1197 /* magic bitmap handle to test smaller cbSize */
1198 if (item == (HBITMAP)(ULONG_PTR)0xdeadbeef)
1199 info.cbSize = FIELD_OFFSET(MENUITEMINFOA,hbmpItem);
1200 else
1201 info.cbSize = sizeof(info);
1202 info.fMask = mask;
1203 info.fType = type;
1204 info.fState = state;
1205 info.wID = id;
1206 info.hSubMenu = submenu;
1207 info.hbmpChecked = checked;
1208 info.hbmpUnchecked = unchecked;
1209 info.dwItemData = data;
1210 info.dwTypeData = type_data;
1211 info.cch = len;
1212 info.hbmpItem = item;
1213 SetLastError( 0xdeadbeef );
1214 if (ansi) ret = InsertMenuItemA( hmenu, 0, TRUE, &info );
1215 else ret = InsertMenuItemW( hmenu, 0, TRUE, (MENUITEMINFOW*)&info );
1216 if (!expect) ok_(__FILE__, line)( !ret, "InsertMenuItem should have failed.\n" );
1217 else ok_(__FILE__, line)( ret, "InsertMenuItem failed, err %lu\n", GetLastError());
1218}
1219
1221 UINT id, HMENU submenu, HBITMAP checked, HBITMAP unchecked,
1222 ULONG_PTR data, void *type_data, UINT in_len, UINT out_len,
1223 HBITMAP item, LPCSTR expname, BOOL expect, BOOL expstring )
1224{
1226 BOOL ret;
1227 WCHAR buffer[80];
1228
1229 SetLastError( 0xdeadbeef );
1230 memset( &info, 0xcc, sizeof(info) );
1231 info.cbSize = sizeof(info);
1232 info.fMask = mask;
1233 info.dwTypeData = type_data;
1234 info.cch = in_len;
1235
1236 ret = ansi ? GetMenuItemInfoA( hmenu, 0, TRUE, &info ) :
1238 if (!expect)
1239 {
1240 ok_(__FILE__, line)( !ret, "GetMenuItemInfo should have failed.\n" );
1241 return;
1242 }
1243 ok_(__FILE__, line)( ret, "GetMenuItemInfo failed, err %lu\n", GetLastError());
1244 if (mask & MIIM_TYPE)
1245 ok_(__FILE__, line)( info.fType == type || info.fType == LOWORD(type),
1246 "wrong type %x/%x\n", info.fType, type );
1247 if (mask & MIIM_STATE)
1248 ok_(__FILE__, line)( info.fState == state || info.fState == LOWORD(state),
1249 "wrong state %x/%x\n", info.fState, state );
1250 if (mask & MIIM_ID)
1251 ok_(__FILE__, line)( info.wID == id || info.wID == LOWORD(id),
1252 "wrong id %x/%x\n", info.wID, id );
1253 if (mask & MIIM_SUBMENU)
1254 ok_(__FILE__, line)( info.hSubMenu == submenu || (ULONG_PTR)info.hSubMenu == LOWORD(submenu),
1255 "wrong submenu %p/%p\n", info.hSubMenu, submenu );
1256 if (mask & MIIM_CHECKMARKS)
1257 {
1258 ok_(__FILE__, line)( info.hbmpChecked == checked || (ULONG_PTR)info.hbmpChecked == LOWORD(checked),
1259 "wrong bmpchecked %p/%p\n", info.hbmpChecked, checked );
1260 ok_(__FILE__, line)( info.hbmpUnchecked == unchecked || (ULONG_PTR)info.hbmpUnchecked == LOWORD(unchecked),
1261 "wrong bmpunchecked %p/%p\n", info.hbmpUnchecked, unchecked );
1262 }
1263 if (mask & MIIM_DATA)
1264 ok_(__FILE__, line)( info.dwItemData == data || info.dwItemData == LOWORD(data),
1265 "wrong item data %Ix/%Ix\n", info.dwItemData, data );
1266 if (mask & MIIM_BITMAP)
1267 ok_(__FILE__, line)( info.hbmpItem == item || (ULONG_PTR)info.hbmpItem == LOWORD(item),
1268 "wrong bmpitem %p/%p\n", info.hbmpItem, item );
1269 ok_(__FILE__, line)( info.dwTypeData == type_data || (ULONG_PTR)info.dwTypeData == LOWORD(type_data),
1270 "wrong type data %p/%p\n", info.dwTypeData, type_data );
1271 ok_(__FILE__, line)( info.cch == out_len ||
1272 broken(! ansi && info.cch == 2 * out_len) /* East-Asian */,
1273 "wrong len %x/%x\n", info.cch, out_len );
1274 if (expname)
1275 {
1276 if(ansi)
1277 ok_(__FILE__, line)( !strncmp( expname, info.dwTypeData, out_len ),
1278 "menu item name differed from '%s' '%s'\n", expname, info.dwTypeData );
1279 else
1280 ok_(__FILE__, line)( !wcsncmp( (WCHAR *)expname, (WCHAR *)info.dwTypeData, out_len ),
1281 "menu item name wrong\n" );
1282
1283 SetLastError( 0xdeadbeef );
1284 ret = ansi ? GetMenuStringA( hmenu, 0, (char *)buffer, 80, MF_BYPOSITION ) :
1286 if (expstring)
1287 ok_(__FILE__, line)( ret, "GetMenuString failed, err %lu\n", GetLastError());
1288 else
1289 ok_(__FILE__, line)( !ret, "GetMenuString should have failed\n" );
1290 }
1291}
1292
1293static void modify_menu( int line, HMENU hmenu, BOOL ansi, UINT flags, UINT_PTR id, void *data )
1294{
1295 BOOL ret;
1296
1297 SetLastError( 0xdeadbeef );
1298 if (ansi) ret = ModifyMenuA( hmenu, 0, flags, id, data );
1299 else ret = ModifyMenuW( hmenu, 0, flags, id, data );
1300 ok_(__FILE__,line)( ret, "ModifyMenuA failed, err %lu\n", GetLastError());
1301}
1302
1304 UINT id, HMENU submenu, HBITMAP checked, HBITMAP unchecked, ULONG_PTR data,
1305 void *type_data, UINT len, HBITMAP item )
1306
1307{
1309 BOOL ret;
1310
1311 /* magic bitmap handle to test smaller cbSize */
1312 if (item == (HBITMAP)(ULONG_PTR)0xdeadbeef)
1313 info.cbSize = FIELD_OFFSET(MENUITEMINFOA,hbmpItem);
1314 else
1315 info.cbSize = sizeof(info);
1316 info.fMask = mask;
1317 info.fType = type;
1318 info.fState = state;
1319 info.wID = id;
1320 info.hSubMenu = submenu;
1321 info.hbmpChecked = checked;
1322 info.hbmpUnchecked = unchecked;
1323 info.dwItemData = data;
1324 info.dwTypeData = type_data;
1325 info.cch = len;
1326 info.hbmpItem = item;
1327 SetLastError( 0xdeadbeef );
1328 if (ansi) ret = SetMenuItemInfoA( hmenu, 0, TRUE, &info );
1329 else ret = SetMenuItemInfoW( hmenu, 0, TRUE, (MENUITEMINFOW*)&info );
1330 ok_(__FILE__, line)( ret, "SetMenuItemInfo failed, err %lu\n", GetLastError());
1331}
1332
1333#define TMII_INSMI( c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,eret1 )\
1334 hmenu = CreateMenu();\
1335 submenu = CreateMenu();\
1336 if(ansi)strcpy( string, init );\
1337 else wcscpy( string, init );\
1338 insert_menu_item( __LINE__, hmenu, ansi, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, eret1 )
1339
1340/* GetMenuItemInfo + GetMenuString */
1341#define TMII_GMII( c2,l2,\
1342 d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,\
1343 expname, eret2, eret3)\
1344 check_menu_item_info( __LINE__, hmenu, ansi, c2, d3, e3, f3, g3, h3, i3, j3, k3, l2, l3, m3, \
1345 expname, eret2, eret3 )
1346
1347#define TMII_DONE \
1348 RemoveMenu(hmenu, 0, TRUE );\
1349 DestroyMenu( hmenu );\
1350 DestroyMenu( submenu );
1351
1352/* modify menu */
1353#define TMII_MODM( flags, id, data ) \
1354 modify_menu( __LINE__, hmenu, ansi, flags, id, data )
1355
1356/* SetMenuItemInfo */
1357#define TMII_SMII( c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1 ) \
1358 set_menu_item_info( __LINE__, hmenu, ansi, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1 )
1359
1360
1361#define OK 1
1362#define ER 0
1363
1364
1365static void test_menu_iteminfo( void )
1366{
1367 BOOL ansi = TRUE;
1368 char txtA[]="wine";
1369 char initA[]="XYZ";
1370 char emptyA[]="";
1371 WCHAR txtW[]={'W','i','n','e',0};
1372 WCHAR initW[]={'X','Y','Z',0};
1373 WCHAR emptyW[]={0};
1374 void *txt, *init, *empty, *string;
1375 HBITMAP hbm = CreateBitmap(1,1,1,1,NULL);
1376 char stringA[0x80];
1377 HMENU hmenu, submenu;
1378 HBITMAP dummy_hbm = (HBITMAP)(ULONG_PTR)0xdeadbeef;
1379
1380 do {
1381 if( ansi) {txt=txtA;init=initA;empty=emptyA;string=stringA;}
1382 else {txt=txtW;init=initW;empty=emptyW;string=stringA;}
1383 trace( "%s string %p hbm %p txt %p\n", ansi ? "ANSI tests: " : "Unicode tests:", string, hbm, txt);
1384 /* test all combinations of MFT_STRING, MFT_OWNERDRAW and MFT_BITMAP */
1385 /* (since MFT_STRING is zero, there are four of them) */
1386 TMII_INSMI( MIIM_TYPE, MFT_STRING, 0, 0, 0, 0, 0, 0, txt, 0, 0, OK );
1387 TMII_GMII ( MIIM_TYPE, 80,
1388 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, 0,
1389 txt, OK, OK );
1390 TMII_DONE
1391 TMII_INSMI( MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1392 TMII_GMII ( MIIM_TYPE, 80,
1393 MFT_STRING|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1394 NULL, OK, ER );
1395 TMII_DONE
1396 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, 6, 0, OK );
1397 TMII_GMII ( MIIM_TYPE, 80,
1398 MFT_BITMAP, 0, 0, 0, 0, 0, 0, hbm, 0, hbm,
1399 NULL, OK, ER );
1400 TMII_DONE
1401 TMII_INSMI( MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, hbm, 6, 0, OK );
1402 TMII_GMII ( MIIM_TYPE, 80,
1403 MFT_BITMAP|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, hbm, 0, hbm,
1404 NULL, OK, ER );
1405 TMII_DONE
1406 /* not enough space for name*/
1407 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1408 TMII_GMII ( MIIM_TYPE, 0,
1409 MFT_STRING, 0, 0, 0, 0, 0, 0, NULL, 4, 0,
1410 NULL, OK, OK );
1411 TMII_DONE
1412 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1413 TMII_GMII ( MIIM_TYPE, 5,
1414 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, 0,
1415 txt, OK, OK );
1416 TMII_DONE
1417 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1418 TMII_GMII ( MIIM_TYPE, 4,
1419 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 3, 0,
1420 txt, OK, OK );
1421 TMII_DONE
1422 TMII_INSMI( MIIM_FTYPE|MIIM_STRING, MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1423 TMII_GMII ( MIIM_TYPE, 0,
1424 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 0, 0,
1425 NULL, OK, ER );
1426 TMII_DONE
1427 /* cannot combine MIIM_TYPE with some other flags */
1428 TMII_INSMI( MIIM_TYPE|MIIM_STRING, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, ER );
1429 TMII_DONE
1430 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1433 NULL, ER, OK );
1434 TMII_DONE
1435 TMII_INSMI( MIIM_TYPE|MIIM_FTYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, ER );
1436 TMII_DONE
1437 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1439 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1440 NULL, ER, OK );
1441 TMII_DONE
1442 TMII_INSMI( MIIM_TYPE|MIIM_BITMAP, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, 6, hbm, ER );
1443 TMII_DONE
1444 /* but succeeds with some others */
1445 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1447 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, 0,
1448 txt, OK, OK );
1449 TMII_DONE
1450 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1452 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, 0,
1453 txt, OK, OK );
1454 TMII_DONE
1455 TMII_INSMI( MIIM_TYPE|MIIM_ID, MFT_STRING, -1, 888, 0, 0, 0, -1, txt, 6, 0, OK );
1457 MFT_STRING, 0, 888, 0, 0, 0, 0, string, 4, 0,
1458 txt, OK, OK );
1459 TMII_DONE
1460 TMII_INSMI( MIIM_TYPE|MIIM_DATA, MFT_STRING, -1, -1, 0, 0, 0, 999, txt, 6, 0, OK );
1462 MFT_STRING, 0, 0, 0, 0, 0, 999, string, 4, 0,
1463 txt, OK, OK );
1464 TMII_DONE
1465 /* to be continued */
1466 /* set text with MIIM_TYPE and retrieve with MIIM_STRING */
1467 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1469 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, 0,
1470 txt, OK, OK );
1471 TMII_DONE
1472 /* set text with MIIM_TYPE and retrieve with MIIM_STRING; MFT_OWNERDRAW causes an empty string */
1473 TMII_INSMI( MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1475 MFT_STRING|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 0, 0,
1476 empty, OK, ER );
1477 TMII_DONE
1478 TMII_INSMI( MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1480 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 0, 0,
1481 empty, OK, ER );
1482 TMII_DONE
1483 TMII_INSMI( MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1484 TMII_GMII ( MIIM_FTYPE, 80,
1485 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 80, 0,
1486 init, OK, ER );
1487 TMII_DONE
1488 TMII_INSMI( MIIM_TYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1489 TMII_GMII ( 0, 80,
1490 0, 0, 0, 0, 0, 0, 0, string, 80, 0,
1491 init, OK, OK );
1492 TMII_DONE
1493 /* contrary to MIIM_TYPE,you can set the text for an owner draw menu */
1494 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1496 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 4, 0,
1497 txt, OK, OK );
1498 TMII_DONE
1499 /* same but retrieve with MIIM_TYPE */
1500 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1501 TMII_GMII ( MIIM_TYPE, 80,
1502 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1503 NULL, OK, OK );
1504 TMII_DONE
1505 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1507 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 0, 0,
1508 empty, OK, ER );
1509 TMII_DONE
1510 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1512 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, string, 0, 0,
1513 empty, OK, ER );
1514 TMII_DONE
1515 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1517 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, NULL, 0, 0,
1518 NULL, OK, ER );
1519 TMII_DONE
1520
1521 /* How is that with bitmaps? */
1522 TMII_INSMI( MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1523 TMII_GMII ( MIIM_TYPE, 80,
1524 MFT_BITMAP, 0, 0, 0, 0, 0, 0, hbm, 0, hbm,
1525 NULL, OK, ER );
1526 TMII_DONE
1527 TMII_INSMI( MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1529 0, 0, 0, 0, 0, 0, 0, string, 80, hbm,
1530 init, OK, ER );
1531 TMII_DONE
1532 /* MIIM_BITMAP does not like MFT_BITMAP */
1533 TMII_INSMI( MIIM_BITMAP|MIIM_FTYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, 0, -1, hbm, ER );
1534 TMII_DONE
1535 /* no problem with OWNERDRAWN */
1536 TMII_INSMI( MIIM_BITMAP|MIIM_FTYPE, MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1538 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 80, hbm,
1539 init, OK, ER );
1540 TMII_DONE
1541 /* setting MFT_BITMAP with MFT_FTYPE fails anyway */
1542 TMII_INSMI( MIIM_FTYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, 0, -1, 0, ER );
1543 TMII_DONE
1544
1545 /* menu with submenu */
1546 TMII_INSMI( MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, 0, 0, -1, txt, 0, 0, OK );
1547 TMII_GMII ( MIIM_SUBMENU, 80,
1548 0, 0, 0, submenu, 0, 0, 0, string, 80, 0,
1549 init, OK, ER );
1550 TMII_DONE
1551 TMII_INSMI( MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, 0, 0, -1, empty, 0, 0, OK );
1552 TMII_GMII ( MIIM_SUBMENU, 80,
1553 0, 0, 0, submenu, 0, 0, 0, string, 80, 0,
1554 init, OK, ER );
1555 TMII_DONE
1556 /* menu with submenu, without MIIM_SUBMENU the submenufield is cleared */
1557 TMII_INSMI( MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, 0, 0, -1, txt, 0, 0, OK );
1559 MFT_STRING|MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, string, 0, 0,
1560 empty, OK, ER );
1562 MFT_SEPARATOR, 0, 0, submenu, 0, 0, 0, string, 80, 0,
1563 empty, OK, ER );
1564 TMII_DONE
1565 /* menu with invalid submenu */
1566 TMII_INSMI( MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, (HMENU)999, 0, 0, -1, txt, 0, 0, ER );
1567 TMII_DONE
1568 /* Separator */
1569 TMII_INSMI( MIIM_TYPE, MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, txt, 0, 0, OK );
1570 TMII_GMII ( MIIM_TYPE, 80,
1571 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1572 NULL, OK, ER );
1573 TMII_DONE
1574 TMII_INSMI( MIIM_TYPE, MFT_BITMAP|MFT_SEPARATOR, -1, -1, 0, 0, 0, -1, hbm, 6, 0, OK );
1575 TMII_GMII ( MIIM_TYPE, 80,
1576 MFT_BITMAP|MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, hbm, 0, hbm,
1577 NULL, OK, ER );
1578 TMII_DONE
1579 /* SEPARATOR and STRING go well together */
1580 /* BITMAP and STRING go well together */
1581 TMII_INSMI( MIIM_STRING|MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1583 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, hbm,
1584 txt, OK, OK );
1585 TMII_DONE
1586 /* BITMAP, SEPARATOR and STRING go well together */
1587 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1589 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, string, 4, hbm,
1590 txt, OK, OK );
1591 TMII_DONE
1592 /* last two tests, but use MIIM_TYPE to retrieve info */
1593 TMII_INSMI( MIIM_FTYPE|MIIM_STRING, MFT_SEPARATOR, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1594 TMII_GMII ( MIIM_TYPE, 80,
1595 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1596 NULL, OK, OK );
1597 TMII_DONE
1598 TMII_INSMI( MIIM_STRING|MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1599 TMII_GMII ( MIIM_TYPE, 80,
1600 MFT_BITMAP, 0, 0, 0, 0, 0, 0, hbm, 4, hbm,
1601 NULL, OK, OK );
1602 TMII_DONE
1603 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1604 TMII_GMII ( MIIM_TYPE, 80,
1605 MFT_SEPARATOR|MFT_BITMAP, 0, 0, 0, 0, 0, 0, hbm, 4, hbm,
1606 NULL, OK, OK );
1607 TMII_DONE
1608 /* same three with MFT_OWNERDRAW */
1609 TMII_INSMI( MIIM_FTYPE|MIIM_STRING, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 6, 0, OK );
1610 TMII_GMII ( MIIM_TYPE, 80,
1611 MFT_SEPARATOR|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1612 NULL, OK, OK );
1613 TMII_DONE
1614 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1615 TMII_GMII ( MIIM_TYPE, 80,
1616 MFT_BITMAP|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, hbm, 4, hbm,
1617 NULL, OK, OK );
1618 TMII_DONE
1619 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1620 TMII_GMII ( MIIM_TYPE, 80,
1621 MFT_SEPARATOR|MFT_BITMAP|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, hbm, 4, hbm,
1622 NULL, OK, OK );
1623 TMII_DONE
1624
1625 TMII_INSMI( MIIM_STRING|MIIM_FTYPE|MIIM_ID, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1626 TMII_GMII ( MIIM_TYPE, 80,
1627 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1628 NULL, OK, OK );
1629 TMII_DONE
1630 /* test with modifymenu: string is preserved after setting OWNERDRAW */
1631 TMII_INSMI( MIIM_STRING, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1632 TMII_MODM( MFT_OWNERDRAW, -1, (void*)787 );
1634 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 787, string, 4, 0,
1635 txt, OK, OK );
1636 TMII_DONE
1637 /* same with bitmap: now the text is cleared */
1638 TMII_INSMI( MIIM_STRING, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1639 TMII_MODM( MFT_BITMAP, 545, hbm );
1641 MFT_BITMAP, 0, 545, 0, 0, 0, 0, string, 0, hbm,
1642 empty, OK, ER );
1643 TMII_DONE
1644 /* start with bitmap: now setting text clears it (though he flag is raised) */
1645 TMII_INSMI( MIIM_BITMAP, MFT_STRING, -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1647 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 0, hbm,
1648 empty, OK, ER );
1649 TMII_MODM( MFT_STRING, 545, txt );
1651 MFT_STRING, 0, 545, 0, 0, 0, 0, string, 4, 0,
1652 txt, OK, OK );
1653 TMII_DONE
1654 /*repeat with text NULL */
1655 TMII_INSMI( MIIM_BITMAP, MFT_STRING, -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1656 TMII_MODM( MFT_STRING, 545, NULL );
1658 MFT_SEPARATOR, 0, 545, 0, 0, 0, 0, string, 0, 0,
1659 empty, OK, ER );
1660 TMII_DONE
1661 /* repeat with text "" */
1662 TMII_INSMI( MIIM_BITMAP, -1 , -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1663 TMII_MODM( MFT_STRING, 545, empty );
1665 MFT_STRING, 0, 545, 0, 0, 0, 0, string, 0, 0,
1666 empty, OK, ER );
1667 TMII_DONE
1668 /* start with bitmap: set ownerdraw */
1669 TMII_INSMI( MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, 0, -1, hbm, OK );
1670 TMII_MODM( MFT_OWNERDRAW, -1, (void *)232 );
1672 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 232, string, 0, hbm,
1673 empty, OK, ER );
1674 TMII_DONE
1675 /* ask nothing */
1676 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, 0, 0, 0, -1, txt, 6, hbm, OK );
1677 TMII_GMII ( 0, 80,
1678 0, 0, 0, 0, 0, 0, 0, string, 80, 0,
1679 init, OK, OK );
1680 TMII_DONE
1681 /* some tests with small cbSize: the hbmpItem is to be ignored */
1682 TMII_INSMI( MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, 0, -1, dummy_hbm, OK );
1683 TMII_GMII ( MIIM_TYPE, 80,
1684 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, NULL, 0, NULL,
1685 NULL, OK, ER );
1686 TMII_DONE
1687 TMII_INSMI( MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, 0, -1, dummy_hbm, OK );
1689 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, string, 80, NULL,
1690 init, OK, ER );
1691 TMII_DONE
1692 TMII_INSMI( MIIM_STRING|MIIM_BITMAP, -1, -1, -1, 0, 0, 0, -1, txt, 6, dummy_hbm, OK );
1693 TMII_GMII ( MIIM_TYPE, 80,
1694 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, NULL,
1695 txt, OK, OK );
1696 TMII_DONE
1697 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, 0, 0, 0, -1, txt, 6, dummy_hbm, OK );
1698 TMII_GMII ( MIIM_TYPE, 80,
1699 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1700 NULL, OK, OK );
1701 TMII_DONE
1702 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 6, dummy_hbm, OK );
1703 TMII_GMII ( MIIM_TYPE, 80,
1704 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1705 NULL, OK, OK );
1706 TMII_DONE
1707 TMII_INSMI( MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, 0, 0, 0, -1, txt, 6, dummy_hbm, OK );
1708 TMII_GMII ( MIIM_TYPE, 80,
1709 MFT_SEPARATOR|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 4, NULL,
1710 NULL, OK, OK );
1711 TMII_DONE
1712 /* MIIM_TYPE by itself does not get/set the dwItemData for OwnerDrawn menus */
1713 TMII_INSMI( MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, 343, txt, 0, 0, OK );
1715 MFT_STRING|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 343, 0, 0, 0,
1716 NULL, OK, ER );
1717 TMII_DONE
1718 TMII_INSMI( MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, 343, txt, 0, 0, OK );
1719 TMII_GMII ( MIIM_TYPE, 80,
1720 MFT_STRING|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1721 NULL, OK, ER );
1722 TMII_DONE
1723 TMII_INSMI( MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, 0, 0, 0, 343, txt, 0, 0, OK );
1725 MFT_STRING|MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1726 NULL, OK, ER );
1727 TMII_DONE
1728 /* set a string menu to ownerdraw with MIIM_TYPE */
1729 TMII_INSMI( MIIM_TYPE, MFT_STRING, -2, -2, 0, 0, 0, -2, txt, -2, 0, OK );
1730 TMII_SMII ( MIIM_TYPE, MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
1732 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, string, 4, 0,
1733 txt, OK, OK );
1734 TMII_DONE
1735 /* test with modifymenu add submenu */
1736 TMII_INSMI( MIIM_STRING, MFT_STRING, -1, -1, 0, 0, 0, -1, txt, 0, 0, OK );
1737 TMII_MODM( MF_POPUP, (UINT_PTR)submenu, txt );
1739 MFT_STRING, 0, 0, submenu, 0, 0, 0, string, 4, 0,
1740 txt, OK, OK );
1741 TMII_GMII ( MIIM_TYPE, 80,
1742 MFT_STRING, 0, 0, 0, 0, 0, 0, string, 4, 0,
1743 txt, OK, OK );
1744 TMII_DONE
1745 /* MFT_SEPARATOR bit is kept when the text is added */
1746 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1747 TMII_SMII( MIIM_STRING, 0, 0, 0, 0, 0, 0, 0, txt, 0, 0 );
1749 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, string, 4, 0,
1750 txt, OK, OK );
1751 TMII_DONE
1752 /* MFT_SEPARATOR bit is kept when bitmap is added */
1753 TMII_INSMI( MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, 0, 0, 0, -1, NULL, 0, 0, OK );
1754 TMII_SMII( MIIM_BITMAP, 0, 0, 0, 0, 0, 0, 0, 0, 0, hbm );
1756 MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, string, 80, hbm,
1757 init, OK, ER );
1758 TMII_DONE
1759 /* Bitmaps inserted with MIIM_TYPE and MFT_BITMAP:
1760 Only the low word of the dwTypeData is used.
1761 Use a magic bitmap here (Word 95 uses this to create its MDI menu buttons) */
1762 TMII_INSMI( MIIM_TYPE, MFT_BITMAP | MFT_RIGHTJUSTIFY, -1, -1, 0, 0, 0, -1,
1763 (HMENU)MAKELPARAM(HBMMENU_MBAR_CLOSE, 0x1234), -1, 0, OK );
1764 TMII_GMII ( MIIM_TYPE, 80,
1766 NULL, OK, OK );
1767 TMII_DONE
1768 /* Type flags */
1770 TMII_GMII ( MIIM_TYPE, 80,
1772 NULL, OK, OK );
1773 TMII_DONE
1774 /* State flags */
1775 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, -1, 0, OK );
1776 TMII_SMII( MIIM_STATE, -1, MFS_CHECKED | MFS_DEFAULT | MFS_GRAYED | MFS_HILITE, 0, 0, 0, 0, 0, 0, 0, 0 );
1777 TMII_GMII ( MIIM_STATE, 80,
1778 0, MFS_CHECKED | MFS_DEFAULT | MFS_GRAYED | MFS_HILITE, 0, 0, 0, 0, 0, 0, 80, 0,
1779 NULL, OK, OK );
1780 TMII_DONE
1781 /* The style MFT_RADIOCHECK cannot be set with MIIM_CHECKMARKS only */
1782 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, -1, 0, OK );
1783 TMII_SMII( MIIM_CHECKMARKS, MFT_RADIOCHECK, 0, 0, 0, hbm, hbm, 0, 0, 0, 0 );
1785 MFT_BITMAP, 0, 0, 0, hbm, hbm, 0, hbm, 0, hbm,
1786 NULL, OK, OK );
1787 TMII_DONE
1788 /* MFT_BITMAP is added automatically by GetMenuItemInfo() for MIIM_TYPE */
1789 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, -1, 0, OK );
1790 TMII_SMII( MIIM_FTYPE, MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, (HBITMAP)0x1234, 0, 0 );
1791 TMII_GMII ( MIIM_FTYPE, 80,
1792 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 80, 0,
1793 NULL, OK, OK );
1794 TMII_GMII ( MIIM_TYPE, 80,
1795 MFT_BITMAP | MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, hbm, 0, hbm,
1796 NULL, OK, OK );
1797 TMII_GMII ( MIIM_FTYPE, 80,
1798 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 80, 0,
1799 NULL, OK, OK );
1800 TMII_SMII( MIIM_BITMAP, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL );
1801 TMII_GMII ( MIIM_TYPE, 80,
1802 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 0, NULL,
1803 NULL, OK, OK );
1804 TMII_DONE
1805 /* Bitmaps inserted with MIIM_TYPE and MFT_BITMAP:
1806 Only the low word of the dwTypeData is used.
1807 Use a magic bitmap here (Word 95 uses this to create its MDI menu buttons) */
1808 TMII_INSMI( MIIM_TYPE, MFT_BITMAP | MFT_RIGHTJUSTIFY, -1, -1, 0, 0, 0, -1,
1809 (HMENU)MAKELPARAM(HBMMENU_MBAR_CLOSE, 0x1234), -1, 0, OK );
1810 TMII_GMII ( MIIM_TYPE, 80,
1812 NULL, OK, OK );
1813 TMII_DONE
1814 /* Type flags */
1816 TMII_GMII ( MIIM_TYPE, 80,
1818 NULL, OK, OK );
1819 TMII_DONE
1820 /* State flags */
1821 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, -1, 0, OK );
1822 TMII_SMII( MIIM_STATE, -1, MFS_CHECKED | MFS_DEFAULT | MFS_GRAYED | MFS_HILITE, 0, 0, 0, 0, 0, 0, 0, 0 );
1823 TMII_GMII ( MIIM_STATE, 80,
1824 0, MFS_CHECKED | MFS_DEFAULT | MFS_GRAYED | MFS_HILITE, 0, 0, 0, 0, 0, 0, 80, 0,
1825 NULL, OK, OK );
1826 TMII_DONE
1827 /* The style MFT_RADIOCHECK cannot be set with MIIM_CHECKMARKS only */
1828 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, -1, 0, OK );
1829 TMII_SMII( MIIM_CHECKMARKS, MFT_RADIOCHECK, 0, 0, 0, hbm, hbm, 0, 0, 0, 0 );
1831 MFT_BITMAP, 0, 0, 0, hbm, hbm, 0, hbm, 0, hbm,
1832 NULL, OK, OK );
1833 TMII_DONE
1834 /* MFT_BITMAP is added automatically by GetMenuItemInfo() for MIIM_TYPE */
1835 TMII_INSMI( MIIM_TYPE, MFT_BITMAP, -1, -1, 0, 0, 0, -1, hbm, -1, 0, OK );
1836 TMII_SMII( MIIM_FTYPE, MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, (HBITMAP)0x1234, 0, 0 );
1837 TMII_GMII ( MIIM_FTYPE, 80,
1838 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 80, 0,
1839 NULL, OK, OK );
1840 TMII_GMII ( MIIM_TYPE, 80,
1841 MFT_BITMAP | MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, hbm, 0, hbm,
1842 NULL, OK, OK );
1843 TMII_GMII ( MIIM_FTYPE, 80,
1844 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, 0, 80, 0,
1845 NULL, OK, OK );
1846 TMII_SMII( MIIM_BITMAP, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL );
1847 TMII_GMII ( MIIM_TYPE, 80,
1848 MFT_OWNERDRAW, 0, 0, 0, 0, 0, 0, NULL, 0, NULL,
1849 NULL, OK, OK );
1850 TMII_DONE
1851 } while( !(ansi = !ansi) );
1852 DeleteObject( hbm);
1853}
1854
1855/*
1856 The following tests try to confirm the algorithm used to return the menu items
1857 when there is a collision between a menu item and a popup menu
1858 */
1860{
1861 HMENU hmenu, hmenuSub, hmenuSub2;
1863 BOOL rc;
1864 UINT id;
1865 char strback[0x80];
1866 char strIn[0x80];
1867 static CHAR menuitem[] = "MenuItem",
1868 menuitem2[] = "MenuItem 2";
1869
1870 /* Case 1: Menu containing a menu item */
1871 hmenu = CreateMenu();
1872
1873 memset( &info, 0, sizeof info );
1874 info.cbSize = sizeof info;
1875 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
1876 info.fType = MFT_STRING;
1877 strcpy(strIn, "Case 1 MenuItem");
1878 info.dwTypeData = strIn;
1879 info.wID = (UINT) 0x1234;
1880
1881 rc = InsertMenuItemA(hmenu, 0, TRUE, &info );
1882 ok (rc, "Inserting the menuitem failed\n");
1883
1884 id = GetMenuItemID(hmenu, 0);
1885 ok (id == 0x1234, "Getting the menuitem id failed(gave %x)\n", id);
1886
1887 /* Confirm the menuitem was given the id supplied (getting by position) */
1888 memset( &info, 0, sizeof info );
1889 strback[0] = 0x00;
1890 info.cbSize = sizeof(MENUITEMINFOA);
1891 info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
1892 info.dwTypeData = strback;
1893 info.cch = sizeof(strback);
1894
1895 rc = GetMenuItemInfoA(hmenu, 0, TRUE, &info); /* Get by position */
1896 ok (rc, "Getting the menu items info failed\n");
1897 ok (info.wID == 0x1234, "IDs differ for the menuitem\n");
1898 ok (!strcmp(info.dwTypeData, "Case 1 MenuItem"), "Returned item has wrong label\n");
1899
1900 /* Search by id - Should return the item */
1901 memset( &info, 0, sizeof info );
1902 strback[0] = 0x00;
1903 info.cbSize = sizeof(MENUITEMINFOA);
1904 info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
1905 info.dwTypeData = strback;
1906 info.cch = sizeof(strback);
1907 rc = GetMenuItemInfoA(hmenu, 0x1234, FALSE, &info); /* Get by ID */
1908
1909 ok (rc, "Getting the menu items info failed\n");
1910 ok (info.wID == 0x1234, "IDs differ for the menuitem\n");
1911 ok (!strcmp(info.dwTypeData, "Case 1 MenuItem"), "Returned item has wrong label\n");
1912
1913 DestroyMenu( hmenu );
1914
1915 /* Case 2: Menu containing a popup menu */
1916 hmenu = CreateMenu();
1917 hmenuSub = CreateMenu();
1918
1919 strcpy(strIn, "Case 2 SubMenu");
1920 rc = InsertMenuA(hmenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, strIn);
1921 ok (rc, "Inserting the popup menu into the main menu failed\n");
1922
1923 id = GetMenuItemID(hmenu, 0);
1924 ok (id == -1, "Getting the menuitem id unexpectedly worked (gave %x)\n", id);
1925
1926 /* Confirm the menuitem itself was given an id the same as the HMENU, (getting by position) */
1927 memset( &info, 0, sizeof info );
1928 strback[0] = 0x00;
1929 info.cbSize = sizeof(MENUITEMINFOA);
1930 info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
1931 info.dwTypeData = strback;
1932 info.cch = sizeof(strback);
1933 info.wID = 0xdeadbeef;
1934
1935 rc = GetMenuItemInfoA(hmenu, 0, TRUE, &info); /* Get by position */
1936 ok (rc, "Getting the menu items info failed\n");
1937 ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the menuitem\n");
1938 ok (!strcmp(info.dwTypeData, "Case 2 SubMenu"), "Returned item has wrong label\n");
1939
1940 /* Search by id - returns the popup menu itself */
1941 memset( &info, 0, sizeof info );
1942 strback[0] = 0x00;
1943 info.cbSize = sizeof(MENUITEMINFOA);
1944 info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
1945 info.dwTypeData = strback;
1946 info.cch = sizeof(strback);
1947 rc = GetMenuItemInfoA(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); /* Get by ID */
1948
1949 ok (rc, "Getting the menu items info failed\n");
1950 ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the popup menu\n");
1951 ok (!strcmp(info.dwTypeData, "Case 2 SubMenu"), "Returned item has wrong label\n");
1952
1953 /*
1954 Now add an item after it with the same id
1955 */
1956 memset( &info, 0, sizeof info );
1957 info.cbSize = sizeof info;
1958 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
1959 info.fType = MFT_STRING;
1960 strcpy(strIn, "Case 2 MenuItem 1");
1961 info.dwTypeData = strIn;
1962 info.wID = (UINT_PTR) hmenuSub;
1963 rc = InsertMenuItemA(hmenu, -1, TRUE, &info );
1964 ok (rc, "Inserting the menuitem failed\n");
1965
1966 /* Search by id - returns the item which follows the popup menu */
1967 memset( &info, 0, sizeof info );
1968 strback[0] = 0x00;
1969 info.cbSize = sizeof(MENUITEMINFOA);
1970 info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
1971 info.dwTypeData = strback;
1972 info.cch = sizeof(strback);
1973 rc = GetMenuItemInfoA(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); /* Get by ID */
1974
1975 ok (rc, "Getting the menu items info failed\n");
1976 ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the popup menu\n");
1977 ok (!strcmp(info.dwTypeData, "Case 2 MenuItem 1"), "Returned item has wrong label (%s)\n", info.dwTypeData);
1978
1979 /*
1980 Now add an item before the popup (with the same id)
1981 */
1982 memset( &info, 0, sizeof info );
1983 info.cbSize = sizeof info;
1984 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
1985 info.fType = MFT_STRING;
1986 strcpy(strIn, "Case 2 MenuItem 2");
1987 info.dwTypeData = strIn;
1988 info.wID = (UINT_PTR) hmenuSub;
1989 rc = InsertMenuItemA(hmenu, 0, TRUE, &info );
1990 ok (rc, "Inserting the menuitem failed\n");
1991
1992 /* Search by id - returns the item which precedes the popup menu */
1993 memset( &info, 0, sizeof info );
1994 strback[0] = 0x00;
1995 info.cbSize = sizeof(MENUITEMINFOA);
1996 info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
1997 info.dwTypeData = strback;
1998 info.cch = sizeof(strback);
1999 rc = GetMenuItemInfoA(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); /* Get by ID */
2000
2001 ok (rc, "Getting the menu items info failed\n");
2002 ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the popup menu\n");
2003 ok (!strcmp(info.dwTypeData, "Case 2 MenuItem 2"), "Returned item has wrong label (%s)\n", info.dwTypeData);
2004
2005 DestroyMenu( hmenu );
2006 DestroyMenu( hmenuSub );
2007
2008 /*
2009 Case 3: Menu containing a popup menu which in turn
2010 contains 2 items with the same id as the popup itself
2011 */
2012
2013 hmenu = CreateMenu();
2014 hmenuSub = CreateMenu();
2015
2016 memset( &info, 0, sizeof info );
2017 info.cbSize = sizeof info;
2018 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
2019 info.fType = MFT_STRING;
2020 info.dwTypeData = menuitem;
2021 info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/
2022
2023 rc = InsertMenuA(hmenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, "Submenu");
2024 ok (rc, "Inserting the popup menu into the main menu failed\n");
2025
2026 rc = InsertMenuItemA(hmenuSub, 0, TRUE, &info );
2027 ok (rc, "Inserting the sub menu menuitem failed\n");
2028
2029 memset( &info, 0, sizeof info );
2030 info.cbSize = sizeof info;
2031 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
2032 info.fType = MFT_STRING;
2033 info.dwTypeData = menuitem2;
2034 info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/
2035
2036 rc = InsertMenuItemA(hmenuSub, 1, TRUE, &info );
2037 ok (rc, "Inserting the sub menu menuitem 2 failed\n");
2038
2039 /* Prove that you can't query the id of a popup directly (By position) */
2040 id = GetMenuItemID(hmenu, 0);
2041 ok (id == -1, "Getting the sub menu id should have failed because it's a popup (gave %x)\n", id);
2042
2043 /* Prove getting the item info via ID returns the first item (not the popup or 2nd item)*/
2044 memset( &info, 0, sizeof info );
2045 strback[0] = 0x00;
2046 info.cbSize = sizeof(MENUITEMINFOA);
2047 info.fMask = MIIM_STRING | MIIM_ID;
2048 info.dwTypeData = strback;
2049 info.cch = sizeof(strback);
2050
2051 rc = GetMenuItemInfoA(hmenu, (UINT_PTR)hmenuSub, FALSE, &info);
2052 ok (rc, "Getting the menus info failed\n");
2053 ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for popup menu\n");
2054 ok (!strcmp(info.dwTypeData, "MenuItem"), "Returned item has wrong label (%s)\n", info.dwTypeData);
2055 DestroyMenu( hmenu );
2056 DestroyMenu( hmenuSub );
2057
2058 /*
2059 Case 4: Menu containing 2 popup menus, the second
2060 contains 2 items with the same id as the first popup menu
2061 */
2062 hmenu = CreateMenu();
2063 hmenuSub = CreateMenu();
2064 hmenuSub2 = CreateMenu();
2065
2066 rc = InsertMenuA(hmenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, "Submenu");
2067 ok (rc, "Inserting the popup menu into the main menu failed\n");
2068
2069 rc = InsertMenuA(hmenu, 1, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub2, "Submenu2");
2070 ok (rc, "Inserting the popup menu into the main menu failed\n");
2071
2072 memset( &info, 0, sizeof info );
2073 info.cbSize = sizeof info;
2074 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
2075 info.fType = MFT_STRING;
2076 info.dwTypeData = menuitem;
2077 info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/
2078
2079 rc = InsertMenuItemA(hmenuSub2, 0, TRUE, &info );
2080 ok (rc, "Inserting the sub menu menuitem failed\n");
2081
2082 memset( &info, 0, sizeof info );
2083 info.cbSize = sizeof info;
2084 info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
2085 info.fType = MFT_STRING;
2086 info.dwTypeData = menuitem2;
2087 info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/
2088
2089 rc = InsertMenuItemA(hmenuSub2, 1, TRUE, &info );
2090 ok (rc, "Inserting the sub menu menuitem 2 failed\n");
2091
2092 /* Prove getting the item info via ID returns the first item (not the popup or 2nd item)*/
2093 memset( &info, 0, sizeof info );
2094 strback[0] = 0x00;
2095 info.cbSize = sizeof(MENUITEMINFOA);
2096 info.fMask = MIIM_STRING | MIIM_ID;
2097 info.dwTypeData = strback;
2098 info.cch = sizeof(strback);
2099
2100 rc = GetMenuItemInfoA(hmenu, (UINT_PTR)hmenuSub, FALSE, &info);
2101 ok (rc, "Getting the menus info failed\n");
2102 ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for popup menu\n");
2103 ok (!strcmp(info.dwTypeData, "MenuItem"), "Returned item has wrong label (%s)\n", info.dwTypeData);
2104
2105 memset( &info, 0, sizeof info );
2106 strback[0] = 0x00;
2107 info.cbSize = sizeof(MENUITEMINFOA);
2108 info.fMask = MIIM_STRING | MIIM_ID;
2109 info.dwTypeData = strback;
2110 info.cch = sizeof(strback);
2111
2112 rc = GetMenuItemInfoA(hmenu, (UINT_PTR)hmenuSub2, FALSE, &info);
2113 ok (rc, "Getting the menus info failed\n");
2114 ok (info.wID == (UINT_PTR)hmenuSub2, "IDs differ for popup menu\n");
2115 ok (!strcmp(info.dwTypeData, "Submenu2"), "Returned item has wrong label (%s)\n", info.dwTypeData);
2116
2117 DestroyMenu( hmenu );
2118 DestroyMenu( hmenuSub );
2119 DestroyMenu( hmenuSub2 );
2120
2121
2122 /*
2123 Case 5: Menu containing a popup menu which in turn
2124 contains an item with a different id than the popup menu.
2125 This tests the fallback to a popup menu ID.
2126 */
2127
2128 hmenu = CreateMenu();
2129 hmenuSub = CreateMenu();
2130
2131 rc = AppendMenuA(hmenu, MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, "Submenu");
2132 ok (rc, "Appending the popup menu to the main menu failed\n");
2133
2134 rc = AppendMenuA(hmenuSub, MF_STRING, 102, "Item");
2135 ok (rc, "Appending the item to the popup menu failed\n");
2136
2137 /* Set the ID for hmenuSub */
2138 info.cbSize = sizeof(info);
2139 info.fMask = MIIM_ID;
2140 info.wID = 101;
2141
2142 rc = SetMenuItemInfoA(hmenu, 0, TRUE, &info);
2143 ok(rc, "Setting the ID for the popup menu failed\n");
2144
2145 /* Check if the ID has been set */
2146 info.wID = 0;
2147 rc = GetMenuItemInfoA(hmenu, 0, TRUE, &info);
2148 ok(rc, "Getting the ID for the popup menu failed\n");
2149 ok(info.wID == 101, "The ID for the popup menu has not been set\n");
2150
2151 /* Prove getting the item info via ID returns the popup menu */
2152 memset( &info, 0, sizeof(info));
2153 strback[0] = 0x00;
2154 info.cbSize = sizeof(MENUITEMINFOA);
2155 info.fMask = MIIM_STRING | MIIM_ID;
2156 info.dwTypeData = strback;
2157 info.cch = sizeof(strback);
2158
2159 rc = GetMenuItemInfoA(hmenu, 101, FALSE, &info);
2160 ok (rc, "Getting the menu info failed\n");
2161 ok (info.wID == 101, "IDs differ\n");
2162 ok (!strcmp(info.dwTypeData, "Submenu"), "Returned item has wrong label (%s)\n", info.dwTypeData);
2163
2164 /* Also look for the menu item */
2165 memset( &info, 0, sizeof(info));
2166 strback[0] = 0x00;
2167 info.cbSize = sizeof(MENUITEMINFOA);
2168 info.fMask = MIIM_STRING | MIIM_ID;
2169 info.dwTypeData = strback;
2170 info.cch = sizeof(strback);
2171
2172 rc = GetMenuItemInfoA(hmenu, 102, FALSE, &info);
2173 ok (rc, "Getting the menu info failed\n");
2174 ok (info.wID == 102, "IDs differ\n");
2175 ok (!strcmp(info.dwTypeData, "Item"), "Returned item has wrong label (%s)\n", info.dwTypeData);
2176
2178 DestroyMenu(hmenuSub);
2179}
2180
2182 UINT uMenu; /* 1 - top level menu, [0-Menu 1-Enabled 2-Disabled]
2183 * 2 - 2nd level menu, [0-Popup 1-Enabled 2-Disabled]
2184 * 3 - 3rd level menu, [0-Enabled 1-Disabled] */
2186};
2187
2188static struct menu_mouse_tests_s {
2190 struct menu_item_pair_s menu_item_pairs[5]; /* for mousing */
2191 WORD wVk[5]; /* keys */
2194} menu_tests[] = {
2195 /* for each test, send keys or clicks and check for menu visibility */
2196 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 0}, TRUE, FALSE }, /* test 0 */
2197 { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, 0}, FALSE, FALSE },
2198 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 0}, TRUE, FALSE },
2199 { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE },
2200 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 0}, TRUE, FALSE },
2201 { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE },
2202 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 0}, TRUE, FALSE },
2203 { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, VK_ESCAPE, 0}, FALSE, FALSE },
2204 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', VK_ESCAPE, 0}, TRUE, FALSE },
2205 { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, 0}, FALSE, FALSE },
2206 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 0}, TRUE, FALSE },
2207 { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE },
2208 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 0}, TRUE, FALSE },
2209 { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE },
2210 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 'P', 0}, TRUE, FALSE },
2211 { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE },
2212 { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 'P', 0}, TRUE, FALSE },
2213 { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE },
2214 { INPUT_KEYBOARD, {{0}}, {VK_F10, 0}, TRUE, FALSE },
2215 { INPUT_KEYBOARD, {{0}}, {VK_F10, 0}, FALSE, FALSE },
2216
2217 { INPUT_MOUSE, {{1, 2}, {0}}, {0}, TRUE, FALSE }, /* test 20 */
2218 { INPUT_MOUSE, {{1, 1}, {0}}, {0}, FALSE, FALSE },
2219 { INPUT_MOUSE, {{1, 0}, {0}}, {0}, TRUE, FALSE },
2220 { INPUT_MOUSE, {{1, 1}, {0}}, {0}, FALSE, FALSE },
2221 { INPUT_MOUSE, {{1, 0}, {2, 2}, {0}}, {0}, TRUE, FALSE },
2222 { INPUT_MOUSE, {{2, 1}, {0}}, {0}, FALSE, FALSE },
2223 { INPUT_MOUSE, {{1, 0}, {2, 0}, {0}}, {0}, TRUE, FALSE },
2224 { INPUT_MOUSE, {{3, 0}, {0}}, {0}, FALSE, FALSE },
2225 { INPUT_MOUSE, {{1, 0}, {2, 0}, {0}}, {0}, TRUE, FALSE },
2226 { INPUT_MOUSE, {{3, 1}, {0}}, {0}, TRUE, FALSE },
2227 { INPUT_MOUSE, {{1, 1}, {0}}, {0}, FALSE, FALSE },
2228 { -1 }
2230
2231static void send_key(WORD wVk)
2232{
2233 INPUT i[2];
2234 memset(i, 0, sizeof(i));
2235 i[0].type = i[1].type = INPUT_KEYBOARD;
2236 i[0].ki.wVk = i[1].ki.wVk = wVk;
2237 i[1].ki.dwFlags = KEYEVENTF_KEYUP;
2238 SendInput(2, i, sizeof(INPUT));
2239}
2240
2242{
2243 HMENU hMenu = hMenus[mi->uMenu];
2244 INPUT i[3];
2245 MSG msg;
2246 RECT r;
2247 int screen_w = GetSystemMetrics(SM_CXSCREEN);
2248 int screen_h = GetSystemMetrics(SM_CYSCREEN);
2249 BOOL ret = GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r);
2250 if(!ret) return FALSE;
2251
2252 memset(i, 0, sizeof(i));
2253 i[0].type = i[1].type = i[2].type = INPUT_MOUSE;
2254 i[0].mi.dx = i[1].mi.dx = i[2].mi.dx
2255 = ((r.left + 5) * 65535) / screen_w;
2256 i[0].mi.dy = i[1].mi.dy = i[2].mi.dy
2257 = ((r.top + 5) * 65535) / screen_h;
2258 i[0].mi.dwFlags = i[1].mi.dwFlags = i[2].mi.dwFlags
2260 i[0].mi.dwFlags |= MOUSEEVENTF_MOVE;
2261 i[1].mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
2262 i[2].mi.dwFlags |= MOUSEEVENTF_LEFTUP;
2263 ret = SendInput(3, i, sizeof(INPUT));
2264
2265 /* hack to prevent mouse message buildup in Wine */
2266 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
2267 return ret;
2268}
2269
2271{
2272 int i, j;
2273 HANDLE hWnd = lpParameter;
2274
2275 Sleep(500);
2276 /* mixed keyboard/mouse test */
2277 for (i = 0; menu_tests[i].type != -1; i++)
2278 {
2279 BOOL ret = TRUE;
2280 int elapsed;
2281
2282 got_input = i && menu_tests[i-1].bMenuVisible;
2283
2285 for (j = 0; menu_tests[i].wVk[j] != 0; j++)
2286 send_key(menu_tests[i].wVk[j]);
2287 else
2288 for (j = 0; menu_tests[i].menu_item_pairs[j].uMenu != 0; j++)
2289 {
2290 /* Maybe clicking too fast before menu is initialized. Sleep 100 ms and retry */
2291 elapsed = 0;
2292 while (!(ret = click_menu(hWnd, &menu_tests[i].menu_item_pairs[j])))
2293 {
2294 if (elapsed > 1000) break;
2295 elapsed += 100;
2296 Sleep(100);
2297 }
2298 }
2299
2300 if (!ret)
2301 {
2302 skip( "test %u: failed to send input\n", i );
2304 return 0;
2305 }
2306
2307 elapsed = 0;
2309 {
2310 if (elapsed > 200)
2311 break;
2312 elapsed += 20;
2313 Sleep(20);
2314 }
2315
2316 if (!got_input)
2317 {
2318 skip( "test %u: didn't receive input\n", i );
2320 return 0;
2321 }
2322
2323 todo_wine_if (menu_tests[i]._todo_wine)
2324 ok(menu_tests[i].bMenuVisible == bMenuVisible, "test %d\n", i);
2325 }
2326 return 0;
2327}
2328
2330 LPARAM lParam)
2331{
2332 MENUBARINFO mbi;
2333 HMENU hmenu;
2334 UINT state;
2335 BOOL br;
2336
2337 switch (msg) {
2338 case WM_ENTERMENULOOP:
2340 break;
2341 case WM_INITMENUPOPUP:
2342 case WM_UNINITMENUPOPUP:
2343 case WM_EXITMENULOOP:
2344 case WM_MENUSELECT:
2345 break;
2346
2347 case WM_KEYDOWN:
2348 case WM_SYSKEYDOWN:
2349 case WM_MOUSEMOVE:
2350 case WM_LBUTTONDOWN:
2351 case WM_LBUTTONUP:
2352 case WM_NCMOUSEMOVE:
2353 case WM_NCLBUTTONDOWN:
2354 case WM_NCLBUTTONUP:
2355 got_input = TRUE;
2356 /* fall through */
2357 default:
2358 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
2359 }
2360
2361 mbi.cbSize = sizeof(MENUBARINFO);
2362
2363 /* get info for the menu */
2364 br = GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi);
2365 ok(br, "msg %x: GetMenuBarInfo failed\n", msg);
2366 hmenu = GetMenu(hWnd);
2367 ok(!mbi.hwndMenu, "msg %x: GetMenuBarInfo.hwndMenu wrong: %p expected NULL\n",
2368 msg, mbi.hwndMenu);
2369 ok(mbi.hMenu == hmenu, "msg %x: GetMenuBarInfo got wrong menu: %p expected %p\n",
2370 msg, mbi.hMenu, hmenu);
2371 ok(!bMenuVisible == !mbi.fBarFocused, "msg %x: GetMenuBarInfo.fBarFocused (%d) is wrong\n",
2372 msg, mbi.fBarFocused != 0);
2373 ok(!bMenuVisible == !mbi.fFocused, "msg %x: GetMenuBarInfo.fFocused (%d) is wrong\n",
2374 msg, mbi.fFocused != 0);
2375
2376 /* get info for the menu's first item */
2377 br = GetMenuBarInfo(hWnd, OBJID_MENU, 1, &mbi);
2378 ok(br, "msg %x: GetMenuBarInfo failed\n", msg);
2380 /* Native returns handle to destroyed window */
2381 todo_wine_if (msg==WM_UNINITMENUPOPUP && popmenu==1)
2382 ok(!mbi.hwndMenu == !popmenu,
2383 "msg %x: GetMenuBarInfo.hwndMenu wrong: %p expected %sNULL\n",
2384 msg, mbi.hwndMenu, popmenu ? "not " : "");
2385 ok(mbi.hMenu == hmenu, "msg %x: GetMenuBarInfo got wrong menu: %p expected %p\n",
2386 msg, mbi.hMenu, hmenu);
2387 ok(!bMenuVisible == !mbi.fBarFocused, "nsg %x: GetMenuBarInfo.fBarFocused (%d) is wrong\n",
2388 msg, mbi.fBarFocused != 0);
2389 ok(!(bMenuVisible && (state & MF_HILITE)) == !mbi.fFocused,
2390 "msg %x: GetMenuBarInfo.fFocused (%d) is wrong\n", msg, mbi.fFocused != 0);
2391
2392 if (msg == WM_EXITMENULOOP)
2394 else if (msg == WM_INITMENUPOPUP)
2395 popmenu++;
2396 else if (msg == WM_UNINITMENUPOPUP)
2397 popmenu--;
2398 return 0;
2399}
2400
2401static void test_menu_input(void) {
2402 MSG msg;
2403 WNDCLASSA wclass;
2406 DWORD tid;
2407 ATOM aclass;
2408 POINT orig_pos;
2409
2410 wclass.lpszClassName = "MenuTestClass";
2411 wclass.style = CS_HREDRAW | CS_VREDRAW;
2412 wclass.lpfnWndProc = WndProc;
2413 wclass.hInstance = hInstance;
2414 wclass.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
2415 wclass.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
2416 wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
2417 wclass.lpszMenuName = 0;
2418 wclass.cbClsExtra = 0;
2419 wclass.cbWndExtra = 0;
2420 aclass = RegisterClassA( &wclass );
2421 ok (aclass, "MenuTest class not created\n");
2422 if (!aclass) return;
2423 hWnd = CreateWindowA( wclass.lpszClassName, "MenuTest",
2425 400, 200, NULL, NULL, hInstance, NULL);
2426 ok (hWnd != NULL, "MenuTest window not created\n");
2427 if (!hWnd) return;
2428 /* fixed menus */
2429 hMenus[3] = CreatePopupMenu();
2430 AppendMenuA(hMenus[3], MF_STRING, 0, "&Enabled");
2431 AppendMenuA(hMenus[3], MF_STRING|MF_DISABLED, 0, "&Disabled");
2432
2433 hMenus[2] = CreatePopupMenu();
2434 AppendMenuA(hMenus[2], MF_STRING|MF_POPUP, (UINT_PTR) hMenus[3], "&Popup");
2435 AppendMenuA(hMenus[2], MF_STRING, 0, "&Enabled");
2436 AppendMenuA(hMenus[2], MF_STRING|MF_DISABLED, 0, "&Disabled");
2437
2438 hMenus[1] = CreateMenu();
2439 AppendMenuA(hMenus[1], MF_STRING|MF_POPUP, (UINT_PTR) hMenus[2], "&Menu");
2440 AppendMenuA(hMenus[1], MF_STRING, 0, "&Enabled");
2441 AppendMenuA(hMenus[1], MF_STRING|MF_DISABLED, 0, "&Disabled");
2442
2443 SetMenu(hWnd, hMenus[1]);
2446
2447 GetCursorPos(&orig_pos);
2448
2450 while(1)
2451 {
2453 break;
2454 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
2455 }
2456 SetCursorPos(orig_pos.x, orig_pos.y);
2458}
2459
2460static void test_menu_flags( void )
2461{
2462 HMENU hMenu, hPopupMenu;
2463
2464 hMenu = CreateMenu();
2465 hPopupMenu = CreatePopupMenu();
2466
2467 AppendMenuA(hMenu, MF_POPUP | MF_STRING, (UINT_PTR)hPopupMenu, "Popup");
2468
2469 AppendMenuA(hPopupMenu, MF_STRING | MF_HILITE | MF_DEFAULT, 101, "Item 1");
2470 InsertMenuA(hPopupMenu, 1, MF_BYPOSITION | MF_STRING | MF_HILITE | MF_DEFAULT, 102, "Item 2");
2471 AppendMenuA(hPopupMenu, MF_STRING, 103, "Item 3");
2472 ModifyMenuA(hPopupMenu, 2, MF_BYPOSITION | MF_STRING | MF_HILITE | MF_DEFAULT, 103, "Item 3");
2473
2474 ok(GetMenuState(hPopupMenu, 0, MF_BYPOSITION) & MF_HILITE,
2475 "AppendMenu should accept MF_HILITE\n");
2476 ok(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE,
2477 "InsertMenu should accept MF_HILITE\n");
2478 ok(GetMenuState(hPopupMenu, 2, MF_BYPOSITION) & MF_HILITE,
2479 "ModifyMenu should accept MF_HILITE\n");
2480
2481 ok(!(GetMenuState(hPopupMenu, 0, MF_BYPOSITION) & MF_DEFAULT),
2482 "AppendMenu must not accept MF_DEFAULT\n");
2483 ok(!(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_DEFAULT),
2484 "InsertMenu must not accept MF_DEFAULT\n");
2485 ok(!(GetMenuState(hPopupMenu, 2, MF_BYPOSITION) & MF_DEFAULT),
2486 "ModifyMenu must not accept MF_DEFAULT\n");
2487
2488 DestroyMenu(hMenu);
2489}
2490
2491static void test_menu_hilitemenuitem( void )
2492{
2493 HMENU hMenu, hPopupMenu;
2494 WNDCLASSA wclass;
2495 HWND hWnd;
2496 ATOM aclass;
2497
2498 wclass.lpszClassName = "HiliteMenuTestClass";
2499 wclass.style = CS_HREDRAW | CS_VREDRAW;
2500 wclass.lpfnWndProc = WndProc;
2501 wclass.hInstance = GetModuleHandleA( NULL );
2502 wclass.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
2503 wclass.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
2504 wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
2505 wclass.lpszMenuName = 0;
2506 wclass.cbClsExtra = 0;
2507 wclass.cbWndExtra = 0;
2508 aclass = RegisterClassA( &wclass );
2509 ok (aclass, "HiliteMenuTest class could not be created\n");
2510 if (!aclass) return;
2511 hWnd = CreateWindowA( wclass.lpszClassName, "HiliteMenuTest",
2513 400, 200, NULL, NULL, wclass.hInstance, NULL);
2514 ok (hWnd != NULL, "HiliteMenuTest window could not be created\n");
2515 if (!hWnd) return;
2516
2517 hMenu = CreateMenu();
2518 hPopupMenu = CreatePopupMenu();
2519
2520 AppendMenuA(hMenu, MF_POPUP | MF_STRING, (UINT_PTR)hPopupMenu, "Popup");
2521
2522 AppendMenuA(hPopupMenu, MF_STRING, 101, "Item 1");
2523 AppendMenuA(hPopupMenu, MF_STRING, 102, "Item 2");
2524 AppendMenuA(hPopupMenu, MF_STRING, 103, "Item 3");
2525
2526 SetMenu(hWnd, hMenu);
2527
2528 /* test invalid arguments */
2529
2530 ok(!(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE),
2531 "HiliteMenuItem: Item 2 is hilited\n");
2532
2533 SetLastError(0xdeadbeef);
2534 todo_wine
2535 {
2536 ok(!HiliteMenuItem(NULL, hPopupMenu, 1, MF_HILITE | MF_BYPOSITION),
2537 "HiliteMenuItem: call should have failed.\n");
2538 }
2539 ok(GetLastError() == 0xdeadbeef || /* 9x */
2541 "HiliteMenuItem: expected error ERROR_INVALID_WINDOW_HANDLE, got: %ld\n", GetLastError());
2542
2543 SetLastError(0xdeadbeef);
2545 "HiliteMenuItem: call should have failed.\n");
2546 ok(GetLastError() == 0xdeadbeef || /* 9x */
2548 "HiliteMenuItem: expected error ERROR_INVALID_MENU_HANDLE, got: %ld\n", GetLastError());
2549
2550 ok(!(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE),
2551 "HiliteMenuItem: Item 2 is hilited\n");
2552
2553 /* either MF_HILITE or MF_UNHILITE *and* MF_BYCOMMAND or MF_BYPOSITION need to be set */
2554
2555 SetLastError(0xdeadbeef);
2556 ok(HiliteMenuItem(hWnd, hPopupMenu, 1, MF_BYPOSITION),
2557 "HiliteMenuItem: call should have succeeded.\n");
2558 ok(GetLastError() == 0xdeadbeef,
2559 "HiliteMenuItem: expected error 0xdeadbeef, got: %ld\n", GetLastError());
2560
2561 ok(!(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE),
2562 "HiliteMenuItem: Item 2 is hilited\n");
2563
2564 SetLastError(0xdeadbeef);
2565 todo_wine
2566 {
2567 ok(HiliteMenuItem(hWnd, hPopupMenu, 1, MF_HILITE),
2568 "HiliteMenuItem: call should have succeeded.\n");
2569 }
2570 ok(GetLastError() == 0xdeadbeef,
2571 "HiliteMenuItem: expected error 0xdeadbeef, got: %ld\n", GetLastError());
2572
2573 ok(!(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE),
2574 "HiliteMenuItem: Item 2 is hilited\n");
2575
2576 /* hilite a menu item (by position) */
2577
2578 SetLastError(0xdeadbeef);
2579 ok(HiliteMenuItem(hWnd, hPopupMenu, 1, MF_HILITE | MF_BYPOSITION),
2580 "HiliteMenuItem: call should not have failed.\n");
2581 ok(GetLastError() == 0xdeadbeef,
2582 "HiliteMenuItem: expected error 0xdeadbeef, got: %ld\n", GetLastError());
2583
2584 todo_wine
2585 {
2586 ok(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE,
2587 "HiliteMenuItem: Item 2 is not hilited\n");
2588 }
2589
2590 /* unhilite a menu item (by position) */
2591
2592 SetLastError(0xdeadbeef);
2593 ok(HiliteMenuItem(hWnd, hPopupMenu, 1, MF_UNHILITE | MF_BYPOSITION),
2594 "HiliteMenuItem: call should not have failed.\n");
2595 ok(GetLastError() == 0xdeadbeef,
2596 "HiliteMenuItem: expected error 0xdeadbeef, got: %ld\n", GetLastError());
2597
2598 ok(!(GetMenuState(hPopupMenu, 1, MF_BYPOSITION) & MF_HILITE),
2599 "HiliteMenuItem: Item 2 is hilited\n");
2600
2601 /* hilite a menu item (by command) */
2602
2603 SetLastError(0xdeadbeef);
2604 ok(HiliteMenuItem(hWnd, hPopupMenu, 103, MF_HILITE | MF_BYCOMMAND),
2605 "HiliteMenuItem: call should not have failed.\n");
2606 ok(GetLastError() == 0xdeadbeef,
2607 "HiliteMenuItem: expected error 0xdeadbeef, got: %ld\n", GetLastError());
2608
2609 todo_wine
2610 {
2611 ok(GetMenuState(hPopupMenu, 2, MF_BYPOSITION) & MF_HILITE,
2612 "HiliteMenuItem: Item 3 is not hilited\n");
2613 }
2614
2615 /* unhilite a menu item (by command) */
2616
2617 SetLastError(0xdeadbeef);
2618 ok(HiliteMenuItem(hWnd, hPopupMenu, 103, MF_UNHILITE | MF_BYCOMMAND),
2619 "HiliteMenuItem: call should not have failed.\n");
2620 ok(GetLastError() == 0xdeadbeef,
2621 "HiliteMenuItem: expected error 0xdeadbeef, got: %ld\n", GetLastError());
2622
2623 ok(!(GetMenuState(hPopupMenu, 2, MF_BYPOSITION) & MF_HILITE),
2624 "HiliteMenuItem: Item 3 is hilited\n");
2625
2627}
2628
2629static void check_menu_items(HMENU hmenu, UINT checked_cmd, UINT checked_type,
2630 UINT checked_state)
2631{
2632 INT i, count;
2633
2635 ok (count != -1, "GetMenuItemCount returned -1\n");
2636
2637 for (i = 0; i < count; i++)
2638 {
2639 BOOL ret;
2640 MENUITEMINFOA mii;
2641
2642 memset(&mii, 0, sizeof(mii));
2643 mii.cbSize = sizeof(mii);
2645 ret = GetMenuItemInfoA(hmenu, i, TRUE, &mii);
2646 ok(ret, "GetMenuItemInfo(%u) failed\n", i);
2647
2648 if (winetest_debug > 1)
2649 trace("item #%u: fType %04x, fState %04x, wID %u, hSubMenu %p\n",
2650 i, mii.fType, mii.fState, mii.wID, mii.hSubMenu);
2651
2652 if (mii.hSubMenu)
2653 {
2654 ok(mii.wID == (UINT_PTR)mii.hSubMenu, "id %u: wID %x should be equal to hSubMenu %p\n",
2655 checked_cmd, mii.wID, mii.hSubMenu);
2656 if (!GetMenuItemCount(mii.hSubMenu))
2657 {
2658 ok(mii.fType == checked_type, "id %u: expected fType %04x, got %04x\n", checked_cmd, checked_type, mii.fType);
2659 ok(mii.fState == checked_state, "id %u: expected fState %04x, got %04x\n", checked_cmd, checked_state, mii.fState);
2660 }
2661 check_menu_items(mii.hSubMenu, checked_cmd, checked_type, checked_state);
2662 }
2663 else
2664 {
2665 if (mii.wID == checked_cmd)
2666 {
2667 ok(mii.fType == checked_type, "id %u: expected fType %04x, got %04x\n", checked_cmd, checked_type, mii.fType);
2668 ok(mii.fState == checked_state, "id %u: expected fState %04x, got %04x\n", checked_cmd, checked_state, mii.fState);
2669 ok(mii.wID != 0, "id %u: not expected wID 0\n", checked_cmd);
2670 }
2671 else
2672 {
2673 ok(mii.fType != MFT_RADIOCHECK, "id %u: not expected fType MFT_RADIOCHECK on cmd %u\n", checked_cmd, mii.wID);
2674
2675 if (mii.fType == MFT_SEPARATOR)
2676 {
2677 ok(mii.fState == MFS_GRAYED, "id %u: expected fState MFS_GRAYED, got %04x\n", checked_cmd, mii.fState);
2678 ok(mii.wID == 0, "id %u: expected wID 0, got %u\n", checked_cmd, mii.wID);
2679 }
2680 else
2681 {
2682 ok(mii.fState == 0, "id %u: expected fState 0, got %04x\n", checked_cmd, mii.fState);
2683 ok(mii.wID != 0, "id %u: not expected wID 0\n", checked_cmd);
2684 }
2685 }
2686 }
2687 }
2688}
2689
2691{
2692 BOOL ret;
2693 MENUITEMINFOA mii;
2694
2695 memset(&mii, 0, sizeof(mii));
2696 mii.cbSize = sizeof(mii);
2697 mii.fMask = MIIM_FTYPE | MIIM_STATE;
2698 ret = SetMenuItemInfoA(hmenu, id, (flags & MF_BYPOSITION) != 0, &mii);
2699 ok(ret, "SetMenuItemInfo(%u) failed\n", id);
2700}
2701
2703{
2704 BOOL ret;
2705 HMENU hmenu;
2706
2708 assert(hmenu != 0);
2709
2710 check_menu_items(hmenu, -1, 0, 0);
2711
2712 ret = CheckMenuRadioItem(hmenu, 100, 100, 100, MF_BYCOMMAND);
2713 ok(ret, "CheckMenuRadioItem failed\n");
2715
2716 /* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
2717 ret = CheckMenuRadioItem(hmenu, 100, 100, -1, MF_BYCOMMAND);
2718 ok(!ret, "CheckMenuRadioItem should return FALSE\n");
2720
2721 /* clear check */
2723 check_menu_items(hmenu, -1, 0, 0);
2724
2725 /* first and checked items are on different menus */
2726 ret = CheckMenuRadioItem(hmenu, 0, 300, 202, MF_BYCOMMAND);
2727 ok(!ret, "CheckMenuRadioItem should return FALSE\n");
2728 check_menu_items(hmenu, -1, 0, 0);
2729
2730 ret = CheckMenuRadioItem(hmenu, 200, 300, 202, MF_BYCOMMAND);
2731 ok(ret, "CheckMenuRadioItem failed\n");
2733
2734 /* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
2735 ret = CheckMenuRadioItem(hmenu, 202, 202, -1, MF_BYCOMMAND);
2736 ok(!ret, "CheckMenuRadioItem should return FALSE\n");
2738
2739 /* clear check */
2741 check_menu_items(hmenu, -1, 0, 0);
2742
2743 /* just for fun, try to check separator */
2745 ok(!ret, "CheckMenuRadioItem should return FALSE\n");
2746 check_menu_items(hmenu, -1, 0, 0);
2747}
2748
2750{
2751 static const struct
2752 {
2754 WORD data[14];
2755 } menu_template =
2756 {
2757 { 0, 0 }, /* versionNumber, offset */
2758 {
2759 /* mtOption, mtID, mtString[] '\0' terminated */
2760 MF_STRING, 1, 'F', 0,
2761 MF_STRING, 2, 0,
2762 MF_SEPARATOR, 3, 0,
2763 /* MF_SEPARATOR, 4, 'S', 0, FIXME: Wine ignores 'S' */
2764 MF_STRING|MF_GRAYED|MF_END, 5, 'E', 0
2765 }
2766 };
2767 static const struct
2768 {
2769 UINT type, state, id;
2770 const char *str;
2771 } menu_data[] =
2772 {
2773 { MF_STRING, MF_ENABLED, 1, "F" },
2776 /*{ MF_SEPARATOR, MF_GRAYED|MF_DISABLED, 4, "S" }, FIXME: Wine ignores 'S'*/
2777 { MF_STRING, MF_GRAYED, 5, "E" },
2779 { MF_STRING, MF_ENABLED, 7, "" },
2781 };
2782 HMENU hmenu;
2783 INT count, i;
2784 BOOL ret;
2785
2786 hmenu = LoadMenuIndirectA(&menu_template);
2787 ok(hmenu != 0, "LoadMenuIndirect error %lu\n", GetLastError());
2788
2790 ok(ret, "AppendMenu failed\n");
2791 ret = AppendMenuA(hmenu, MF_STRING, 7, "\0");
2792 ok(ret, "AppendMenu failed\n");
2793 ret = AppendMenuA(hmenu, MF_SEPARATOR, 8, "separator");
2794 ok(ret, "AppendMenu failed\n");
2795
2797 ok(count == ARRAY_SIZE(menu_data), "expected %u menu items, got %u\n",
2799
2800 for (i = 0; i < count; i++)
2801 {
2802 char buf[20];
2803 MENUITEMINFOA mii;
2804
2805 memset(&mii, 0, sizeof(mii));
2806 mii.cbSize = sizeof(mii);
2807 mii.dwTypeData = buf;
2808 mii.cch = sizeof(buf);
2810 ret = GetMenuItemInfoA(hmenu, i, TRUE, &mii);
2811 ok(ret, "GetMenuItemInfo(%u) failed\n", i);
2812 if (winetest_debug > 1)
2813 trace("item #%u: fType %04x, fState %04x, wID %u, dwTypeData %s\n",
2814 i, mii.fType, mii.fState, mii.wID, (LPCSTR)mii.dwTypeData);
2815
2816 ok(mii.fType == menu_data[i].type,
2817 "%u: expected fType %04x, got %04x\n", i, menu_data[i].type, mii.fType);
2818 ok(mii.fState == menu_data[i].state,
2819 "%u: expected fState %04x, got %04x\n", i, menu_data[i].state, mii.fState);
2820 ok(mii.wID == menu_data[i].id,
2821 "%u: expected wID %04x, got %04x\n", i, menu_data[i].id, mii.wID);
2822 ok(mii.cch == strlen(menu_data[i].str),
2823 "%u: expected cch %u, got %u\n", i, (UINT)strlen(menu_data[i].str), mii.cch);
2825 "%u: expected dwTypeData %s, got %s\n", i, menu_data[i].str, (LPCSTR)mii.dwTypeData);
2826 }
2827
2829}
2830
2832{
2834 const char *str;
2835};
2836
2837static HMENU create_menu_from_data(const struct menu_data *item, INT item_count)
2838{
2839 HMENU hmenu;
2840 INT i;
2841 BOOL ret;
2842
2843 hmenu = CreateMenu();
2844 assert(hmenu != 0);
2845
2846 for (i = 0; i < item_count; i++)
2847 {
2848 SetLastError(0xdeadbeef);
2849 ret = AppendMenuA(hmenu, item[i].type, item[i].id, item[i].str);
2850 ok(ret, "%d: AppendMenu(%04x, %04x, %p) error %lu\n",
2851 i, item[i].type, item[i].id, item[i].str, GetLastError());
2852 }
2853 return hmenu;
2854}
2855
2856/* use InsertMenuItem: does not set the MFT_BITMAP flag,
2857 * and does not accept non-magic bitmaps with invalid
2858 * bitmap handles */
2859static HMENU create_menuitem_from_data(const struct menu_data *item, INT item_count)
2860{
2861 HMENU hmenu;
2862 INT i;
2863 BOOL ret;
2864 MENUITEMINFOA mii = { sizeof( MENUITEMINFOA) };
2865
2866 hmenu = CreateMenu();
2867 assert(hmenu != 0);
2868
2869 for (i = 0; i < item_count; i++)
2870 {
2871 SetLastError(0xdeadbeef);
2872
2874 mii.fType = 0;
2875 if( item[i].type & MFT_BITMAP)
2876 {
2877 mii.fMask |= MIIM_BITMAP;
2878 mii.hbmpItem = (HBITMAP)item[i].str;
2879 }
2880 else if( item[i].type & MFT_SEPARATOR)
2881 mii.fType = MFT_SEPARATOR;
2882 else
2883 {
2884 mii.fMask |= MIIM_STRING;
2885 mii.dwTypeData = (LPSTR)item[i].str;
2886 mii.cch = strlen( item[i].str);
2887 }
2888 mii.fState = 0;
2889 if( item[i].type & MF_HELP) mii.fType |= MF_HELP;
2890 mii.wID = item[i].id;
2891 ret = InsertMenuItemA( hmenu, -1, TRUE, &mii);
2892 ok(ret, "%d: InsertMenuItem(%04x, %04x, %p) error %lu\n",
2893 i, item[i].type, item[i].id, item[i].str, GetLastError());
2894 }
2895 return hmenu;
2896}
2897
2898static void compare_menu_data(HMENU hmenu, const struct menu_data *item, INT item_count)
2899{
2900 INT count, i;
2901 BOOL ret;
2902
2904 ok(count == item_count, "expected %d, got %d menu items\n", count, item_count);
2905
2906 for (i = 0; i < count; i++)
2907 {
2908 char buf[20];
2909 MENUITEMINFOA mii;
2910
2911 memset(&mii, 0, sizeof(mii));
2912 mii.cbSize = sizeof(mii);
2913 mii.dwTypeData = buf;
2914 mii.cch = sizeof(buf);
2916 ret = GetMenuItemInfoA(hmenu, i, TRUE, &mii);
2917 ok(ret, "GetMenuItemInfo(%u) failed\n", i);
2918
2919 if (winetest_debug > 1)
2920 trace("item #%u: fType %04x, fState %04x, wID %04x, hbmp %p\n",
2921 i, mii.fType, mii.fState, mii.wID, mii.hbmpItem);
2922
2923 ok(mii.fType == item[i].type,
2924 "%u: expected fType %04x, got %04x\n", i, item[i].type, mii.fType);
2925 ok(mii.wID == item[i].id,
2926 "%u: expected wID %04x, got %04x\n", i, item[i].id, mii.wID);
2927 if (mii.hbmpItem || !item[i].str)
2928 /* For some reason Windows sets high word to not 0 for
2929 * not "magic" ids.
2930 */
2931 ok(LOWORD(mii.hbmpItem) == LOWORD(item[i].str),
2932 "%u: expected hbmpItem %p, got %p\n", i, item[i].str, mii.hbmpItem);
2933 else
2934 {
2935 ok(mii.cch == strlen(item[i].str),
2936 "%u: expected cch %u, got %u\n", i, (UINT)strlen(item[i].str), mii.cch);
2937 ok(!strcmp(mii.dwTypeData, item[i].str),
2938 "%u: expected dwTypeData %s, got %s\n", i, item[i].str, (LPCSTR)mii.dwTypeData);
2939 }
2940 }
2941}
2942
2943static void test_InsertMenu(void)
2944{
2945 HBITMAP hbm = CreateBitmap(1,1,1,1,NULL);
2946 /* Note: XP treats only bitmap handles 1 - 6 as "magic" ones
2947 * regardless of their id.
2948 */
2949 static const struct menu_data in1[] =
2950 {
2951 { MF_STRING, 1, "File" },
2953 { MF_STRING|MF_HELP, 2, "Help" }
2954 };
2955 static const struct menu_data out1[] =
2956 {
2957 { MF_STRING, 1, "File" },
2958 { MF_STRING|MF_HELP, 2, "Help" },
2960 };
2961 static const struct menu_data out1a[] =
2962 {
2963 { MF_STRING, 1, "File" },
2964 { MF_STRING|MF_HELP, 2, "Help" },
2966 };
2967 const struct menu_data in2[] =
2968 {
2969 { MF_STRING, 1, "File" },
2970 { MF_BITMAP|MF_HELP, SC_CLOSE, (char*)hbm },
2971 { MF_STRING|MF_HELP, 2, "Help" }
2972 };
2973 const struct menu_data out2[] =
2974 {
2975 { MF_STRING, 1, "File" },
2976 { MF_BITMAP|MF_HELP, SC_CLOSE, (char*)hbm },
2977 { MF_STRING|MF_HELP, 2, "Help" }
2978 };
2979 const struct menu_data out2a[] =
2980 {
2981 { MF_STRING, 1, "File" },
2982 { MF_HELP, SC_CLOSE, (char*)hbm },
2983 { MF_STRING|MF_HELP, 2, "Help" }
2984 };
2985 static const struct menu_data in3[] =
2986 {
2987 { MF_STRING, 1, "File" },
2989 { MF_STRING|MF_HELP, 2, "Help" }
2990 };
2991 static const struct menu_data out3[] =
2992 {
2993 { MF_STRING, 1, "File" },
2995 { MF_STRING|MF_HELP, 2, "Help" },
2996 };
2997 static const struct menu_data in4[] =
2998 {
2999 { MF_STRING, 1, "File" },
3001 { MF_STRING|MF_HELP, 2, "Help" }
3002 };
3003 static const struct menu_data out4[] =
3004 {
3005 { MF_STRING, 1, "File" },
3006 { MF_STRING|MF_HELP, 2, "Help" },
3008 };
3009 static const struct menu_data out4a[] =
3010 {
3011 { MF_STRING, 1, "File" },
3012 { MF_STRING|MF_HELP, 2, "Help" },
3013 { MF_HELP, 1, MAKEINTRESOURCEA(1) }
3014 };
3015 HMENU hmenu;
3016 BOOL ret;
3017
3018#define create_menu(a) create_menu_from_data((a), ARRAY_SIZE(a))
3019#define create_menuitem(a) create_menuitem_from_data((a), ARRAY_SIZE(a))
3020#define compare_menu(h, a) compare_menu_data((h), (a), ARRAY_SIZE(a))
3021
3022 hmenu = create_menu(in1);
3023 compare_menu(hmenu, out1);
3025
3026 hmenu = create_menu(in2);
3027 compare_menu(hmenu, out2);
3029
3030 hmenu = create_menu(in3);
3031 compare_menu(hmenu, out3);
3033
3034 hmenu = create_menu(in4);
3035 compare_menu(hmenu, out4);
3037
3038 /* now using InsertMenuItemInfo */
3039 hmenu = create_menuitem(in1);
3040 compare_menu(hmenu, out1a);
3042
3043 hmenu = create_menuitem(in2);
3044 compare_menu(hmenu, out2a);
3046
3047 hmenu = create_menuitem(in3);
3048 compare_menu(hmenu, out3);
3050
3051 hmenu = create_menuitem(in4);
3052 compare_menu(hmenu, out4a);
3054
3055#undef create_menu
3056#undef create_menuitem
3057#undef compare_menu
3058
3059 hmenu = CreateMenu();
3060
3061 SetLastError(0xdeadbeef);
3062 ret = InsertMenuW(hmenu, -1, MF_BYPOSITION | MF_POPUP, 0xdeadbeef, L"test");
3064 "InsertMenuW returned %x %lu\n", ret, GetLastError());
3065 ok(GetMenuItemCount(hmenu) == 1, "GetMenuItemCount() = %d\n", GetMenuItemCount(hmenu));
3066
3068}
3069
3070static void test_menu_getmenuinfo(void)
3071{
3072 HMENU hmenu;
3073 MENUINFO mi = {0};
3074 BOOL ret;
3075 DWORD gle;
3076
3077 /* create a menu */
3078 hmenu = CreateMenu();
3079 assert( hmenu);
3080 /* test some parameter errors */
3081 SetLastError(0xdeadbeef);
3083 gle= GetLastError();
3084 ok( !ret, "GetMenuInfo() should have failed\n");
3085 ok( gle == ERROR_INVALID_PARAMETER ||
3086 broken(gle == 0xdeadbeef), /* Win98, WinME */
3087 "GetMenuInfo() error got %lu expected %u\n", gle, ERROR_INVALID_PARAMETER);
3088 SetLastError(0xdeadbeef);
3089 mi.cbSize = 0;
3090 ret = GetMenuInfo( hmenu, &mi);
3091 gle= GetLastError();
3092 ok( !ret, "GetMenuInfo() should have failed\n");
3093 ok( gle == ERROR_INVALID_PARAMETER ||
3094 broken(gle == 0xdeadbeef), /* Win98, WinME */
3095 "GetMenuInfo() error got %lu expected %u\n", gle, ERROR_INVALID_PARAMETER);
3096 SetLastError(0xdeadbeef);
3097 mi.cbSize = sizeof( MENUINFO);
3098 ret = GetMenuInfo( hmenu, &mi);
3099 gle= GetLastError();
3100 ok( ret, "GetMenuInfo() should have succeeded\n");
3101 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3102 SetLastError(0xdeadbeef);
3103 mi.cbSize = 0;
3104 ret = GetMenuInfo( NULL, &mi);
3105 gle= GetLastError();
3106 ok( !ret, "GetMenuInfo() should have failed\n");
3107 ok( gle == ERROR_INVALID_PARAMETER ||
3108 broken(gle == 0xdeadbeef), /* Win98, WinME */
3109 "GetMenuInfo() error got %lu expected %u\n", gle, ERROR_INVALID_PARAMETER);
3110 /* clean up */
3112 return;
3113}
3114
3115static void test_menu_setmenuinfo(void)
3116{
3117 HMENU hmenu, hsubmenu;
3118 MENUINFO mi = {0};
3119 MENUITEMINFOA mii = { sizeof(MENUITEMINFOA) };
3120 BOOL ret;
3121 DWORD gle;
3122 HBRUSH brush;
3123
3124 /* create a menu with a submenu */
3125 hmenu = CreateMenu();
3126 hsubmenu = CreateMenu();
3127 assert( hmenu && hsubmenu);
3128 mii.fMask = MIIM_SUBMENU;
3129 mii.hSubMenu = hsubmenu;
3130 ret = InsertMenuItemA( hmenu, 0, FALSE, &mii);
3131 ok( ret, "InsertMenuItem failed with error %ld\n", GetLastError());
3132 /* test some parameter errors */
3133 SetLastError(0xdeadbeef);
3135 gle= GetLastError();
3136 ok( !ret, "SetMenuInfo() should have failed\n");
3137 ok( gle == ERROR_INVALID_PARAMETER ||
3138 broken(gle == 0xdeadbeef), /* Win98, WinME */
3139 "SetMenuInfo() error got %lu expected %u\n", gle, ERROR_INVALID_PARAMETER);
3140 SetLastError(0xdeadbeef);
3141 mi.cbSize = 0;
3142 ret = SetMenuInfo( hmenu, &mi);
3143 gle= GetLastError();
3144 ok( !ret, "SetMenuInfo() should have failed\n");
3145 ok( gle == ERROR_INVALID_PARAMETER ||
3146 broken(gle == 0xdeadbeef), /* Win98, WinME */
3147 "SetMenuInfo() error got %lu expected %u\n", gle, ERROR_INVALID_PARAMETER);
3148 SetLastError(0xdeadbeef);
3149 mi.cbSize = sizeof( MENUINFO);
3150 ret = SetMenuInfo( hmenu, &mi);
3151 gle= GetLastError();
3152 ok( ret, "SetMenuInfo() should have succeeded\n");
3153 ok( gle == 0xdeadbeef, "SetMenuInfo() error got %lu\n", gle);
3154 SetLastError(0xdeadbeef);
3155 mi.cbSize = 0;
3156 ret = SetMenuInfo( NULL, &mi);
3157 gle= GetLastError();
3158 ok( !ret, "SetMenuInfo() should have failed\n");
3159 ok( gle == ERROR_INVALID_PARAMETER ||
3160 broken(gle == 0xdeadbeef), /* Win98, WinME */
3161 "SetMenuInfo() error got %lu expected %u\n", gle, ERROR_INVALID_PARAMETER);
3162 /* functional tests */
3163 /* menu and submenu should have the CHECKORBMP style bit cleared */
3164 SetLastError(0xdeadbeef);
3165 mi.cbSize = sizeof( MENUINFO);
3166 mi.fMask = MIM_STYLE;
3167 ret = GetMenuInfo( hmenu, &mi);
3168 gle= GetLastError();
3169 ok( ret, "GetMenuInfo() should have succeeded\n");
3170 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3171 ok( !(mi.dwStyle & MNS_CHECKORBMP), "menustyle was not expected to have the MNS_CHECKORBMP flag\n");
3172 SetLastError(0xdeadbeef);
3173 mi.cbSize = sizeof( MENUINFO);
3174 mi.fMask = MIM_STYLE;
3175 ret = GetMenuInfo( hsubmenu, &mi);
3176 gle= GetLastError();
3177 ok( ret, "GetMenuInfo() should have succeeded\n");
3178 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3179 ok( !(mi.dwStyle & MNS_CHECKORBMP), "menustyle was not expected to have the MNS_CHECKORBMP flag\n");
3180 /* SetMenuInfo() */
3181 SetLastError(0xdeadbeef);
3182 mi.cbSize = sizeof( MENUINFO);
3183 mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
3184 mi.dwStyle = MNS_CHECKORBMP;
3185 ret = SetMenuInfo( hmenu, &mi);
3186 gle= GetLastError();
3187 ok( ret, "SetMenuInfo() should have succeeded\n");
3188 ok( gle == 0xdeadbeef, "SetMenuInfo() error got %lu\n", gle);
3189 /* Now both menus should have the MNS_CHECKORBMP style bit set */
3190 SetLastError(0xdeadbeef);
3191 mi.cbSize = sizeof( MENUINFO);
3192 mi.fMask = MIM_STYLE;
3193 ret = GetMenuInfo( hmenu, &mi);
3194 gle= GetLastError();
3195 ok( ret, "GetMenuInfo() should have succeeded\n");
3196 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3197 ok( mi.dwStyle & MNS_CHECKORBMP, "menustyle was expected to have the MNS_CHECKORBMP flag\n");
3198 SetLastError(0xdeadbeef);
3199 mi.cbSize = sizeof( MENUINFO);
3200 mi.fMask = MIM_STYLE;
3201 ret = GetMenuInfo( hsubmenu, &mi);
3202 gle= GetLastError();
3203 ok( ret, "GetMenuInfo() should have succeeded\n");
3204 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3205 ok( mi.dwStyle & MNS_CHECKORBMP, "menustyle was expected to have the MNS_CHECKORBMP flag\n");
3206 /* now repeat that without the APPLYTOSUBMENUS flag and another style bit */
3207 SetLastError(0xdeadbeef);
3208 mi.cbSize = sizeof( MENUINFO);
3209 mi.fMask = MIM_STYLE ;
3210 mi.dwStyle = MNS_NOCHECK;
3211 ret = SetMenuInfo( hmenu, &mi);
3212 gle= GetLastError();
3213 ok( ret, "SetMenuInfo() should have succeeded\n");
3214 ok( gle == 0xdeadbeef, "SetMenuInfo() error got %lu\n", gle);
3215 /* Now only the top menu should have the MNS_NOCHECK style bit set */
3216 SetLastError(0xdeadbeef);
3217 mi.cbSize = sizeof( MENUINFO);
3218 mi.fMask = MIM_STYLE;
3219 ret = GetMenuInfo( hmenu, &mi);
3220 gle= GetLastError();
3221 ok( ret, "GetMenuInfo() should have succeeded\n");
3222 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3223 ok( mi.dwStyle & MNS_NOCHECK, "menustyle was expected to have the MNS_NOCHECK flag\n");
3224 SetLastError(0xdeadbeef);
3225 mi.cbSize = sizeof( MENUINFO);
3226 mi.fMask = MIM_STYLE;
3227 ret = GetMenuInfo( hsubmenu, &mi);
3228 gle= GetLastError();
3229 ok( ret, "GetMenuInfo() should have succeeded\n");
3230 ok( gle == 0xdeadbeef, "GetMenuInfo() error got %lu\n", gle);
3231 ok( !(mi.dwStyle & MNS_NOCHECK), "menustyle was not expected to have the MNS_NOCHECK flag\n");
3232
3233 /* test background brush */
3234 mi.cbSize = sizeof(mi);
3235 mi.fMask = MIM_BACKGROUND;
3236 ret = GetMenuInfo( hmenu, &mi );
3237 ok( ret, "GetMenuInfo() should have succeeded\n" );
3238 ok( mi.hbrBack == NULL, "got %p\n", mi.hbrBack );
3239
3240 brush = CreateSolidBrush( RGB(0xff, 0, 0) );
3241 mi.hbrBack = brush;
3242 ret = SetMenuInfo( hmenu, &mi );
3243 ok( ret, "SetMenuInfo() should have succeeded\n" );
3244 mi.hbrBack = NULL;
3245 ret = GetMenuInfo( hmenu, &mi );
3246 ok( ret, "GetMenuInfo() should have succeeded\n" );
3247 ok( mi.hbrBack == brush, "got %p original %p\n", mi.hbrBack, brush );
3248
3249 mi.hbrBack = NULL;
3250 ret = SetMenuInfo( hmenu, &mi );
3251 ok( ret, "SetMenuInfo() should have succeeded\n" );
3252 ret = GetMenuInfo( hmenu, &mi );
3253 ok( ret, "GetMenuInfo() should have succeeded\n" );
3254 ok( mi.hbrBack == NULL, "got %p\n", mi.hbrBack );
3255 DeleteObject( brush );
3256
3257 /* clean up */
3258 DestroyMenu( hsubmenu);
3260 return;
3261}
3262
3263/* little func to easy switch either TrackPopupMenu() or TrackPopupMenuEx() */
3265{
3266 return ex
3267 ? TrackPopupMenuEx( hmenu, flags, x, y, hwnd, ptpm)
3268 : TrackPopupMenu( hmenu, flags, x, y, 0, hwnd, NULL);
3269}
3270
3271/* some TrackPopupMenu and TrackPopupMenuEx tests */
3272/* the LastError values differ between NO_ERROR and invalid handle */
3273/* between all windows versions tested. The first value is that valid on XP */
3274/* Vista was the only that made returned different error values */
3275/* between the TrackPopupMenu and TrackPopupMenuEx functions */
3277{
3278 BOOL ret;
3279 HMENU hmenu;
3280 DWORD gle;
3281 int Ex;
3284 NULL, NULL, NULL, NULL);
3285 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
3286 if (!hwnd) return;
3288 for( Ex = 0; Ex < 2; Ex++)
3289 {
3291 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
3292 if (!hmenu)
3293 {
3295 return;
3296 }
3297 /* display the menu */
3298 /* start with an invalid menu handle */
3299 SetLastError(0xdeadbeef);
3300
3302 ret = MyTrackPopupMenu( Ex, NULL, TPM_RETURNCMD, 100,100, hwnd, NULL);
3303 gle = GetLastError();
3304 ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
3306 || broken (gle == 0xdeadbeef) /* win95 */
3307 || broken (gle == NO_ERROR) /* win98/ME */
3308 ,"TrackPopupMenu%s error got %lu expected %u\n",
3309 Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE);
3311 "got unexpected message(s)%s%s%s\n",
3312 gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
3313 gflag_entermenuloop ? "WM_INITMENULOOP ": "",
3314 gflag_initmenu ? "WM_INITMENU": "");
3315 /* another one but not NULL */
3316 SetLastError(0xdeadbeef);
3318 ret = MyTrackPopupMenu( Ex, (HMENU)hwnd, TPM_RETURNCMD, 100,100, hwnd, NULL);
3319 gle = GetLastError();
3320 ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
3322 || broken (gle == 0xdeadbeef) /* win95 */
3323 || broken (gle == NO_ERROR) /* win98/ME */
3324 ,"TrackPopupMenu%s error got %lu expected %u\n",
3325 Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE);
3327 "got unexpected message(s)%s%s%s\n",
3328 gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
3329 gflag_entermenuloop ? "WM_INITMENULOOP ": "",
3330 gflag_initmenu ? "WM_INITMENU": "");
3331
3332 /* invalid window */
3333 SetLastError(0xdeadbeef);
3335 ret = MyTrackPopupMenu( Ex, hmenu, TPM_RETURNCMD, 100,100, 0, NULL);
3336 gle = GetLastError();
3337 ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
3338 ok( gle == ERROR_INVALID_WINDOW_HANDLE, "TrackPopupMenu%s error got %lu\n", Ex ? "Ex" : "", gle );
3340 "got unexpected message(s)%s%s%s\n",
3341 gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
3342 gflag_entermenuloop ? "WM_INITMENULOOP ": "",
3343 gflag_initmenu ? "WM_INITMENU": "");
3344
3345 /* now a somewhat successful call */
3346 SetLastError(0xdeadbeef);
3348 ret = MyTrackPopupMenu( Ex, hmenu, TPM_RETURNCMD, 100,100, hwnd, NULL);
3349 gle = GetLastError();
3350 ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret);
3351 ok( gle == NO_ERROR
3352 || gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k */
3353 || broken (gle == 0xdeadbeef) /* win95 */
3354 ,"TrackPopupMenu%s error got %lu expected %u or %u\n",
3355 Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE);
3357 "missed expected message(s)%s%s%s\n",
3358 !gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
3359 !gflag_entermenuloop ? "WM_INITMENULOOP ": "",
3360 !gflag_initmenu ? "WM_INITMENU": "");
3361 /* and another */
3362 ret = AppendMenuA( hmenu, MF_STRING, 1, "winetest");
3363 ok( ret, "AppendMenA has failed!\n");
3364 SetLastError(0xdeadbeef);
3366 ret = MyTrackPopupMenu( Ex, hmenu, TPM_RETURNCMD, 100,100, hwnd, NULL);
3367 gle = GetLastError();
3368 ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret);
3369 ok( gle == NO_ERROR
3370 || gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k and Vista in the TrackPopupMenuEx case */
3371 || broken (gle == 0xdeadbeef) /* win95 */
3372 ,"TrackPopupMenu%s error got %lu expected %u or %u\n",
3373 Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE);
3375 "missed expected message(s)%s%s%s\n",
3376 !gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
3377 !gflag_entermenuloop ? "WM_INITMENULOOP ": "",
3378 !gflag_initmenu ? "WM_INITMENU": "");
3380 }
3381 /* clean up */
3383}
3384
3386
3388{
3389 switch (msg)
3390 {
3391 case WM_ENTERMENULOOP:
3392 {
3393 BOOL ret;
3394
3395 /* try a recursive call */
3396 SetLastError(0xdeadbeef);
3397 ret = TrackPopupMenu(g_hmenu, 0, 100, 100, 0, hwnd, NULL);
3398 ok(ret == FALSE, "got %d\n", ret);
3400 broken(GetLastError() == 0xdeadbeef) /* W9x */, "got %ld\n", GetLastError());
3401
3402 /* exit menu modal loop
3403 * ( A SendMessage does not work on NT3.51 here ) */
3404 return PostMessageA(hwnd, WM_CANCELMODE, 0, 0);
3405 }
3406 }
3407 return DefWindowProcA(hwnd, msg, wparam, lparam);
3408}
3409
3410static void test_menu_trackagain(void)
3411{
3412 HWND hwnd;
3413 BOOL ret;
3414
3417 NULL, NULL, NULL, NULL);
3418 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
3419 if (!hwnd) return;
3421
3423 ok(g_hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
3424
3425 ret = AppendMenuA(g_hmenu, MF_STRING , 100, "item 1");
3426 ok(ret, "AppendMenu failed.\n");
3427 ret = AppendMenuA(g_hmenu, MF_STRING , 101, "item 2");
3428 ok(ret, "AppendMenu failed.\n");
3429
3430 ret = TrackPopupMenu( g_hmenu, 0, 100, 100, 0, hwnd, NULL);
3431 ok(ret == TRUE, "got %d\n", ret);
3432
3435}
3436
3437/* test handling of WM_CANCELMODE messages */
3442{
3443 switch (msg)
3444 {
3445 case WM_ENTERMENULOOP:
3446 g_got_enteridle = 0;
3447 return SendMessageA( g_hwndtosend, WM_CANCELMODE, 0, 0);
3448 case WM_ENTERIDLE:
3449 {
3450 if( g_got_enteridle++ == 0) {
3451 /* little hack to get another WM_ENTERIDLE message */
3453 return SendMessageA( g_hwndtosend, WM_CANCELMODE, 0, 0);
3454 }
3455 EndMenu();
3456 return TRUE;
3457 }
3458 }
3459 return DefWindowProcA( hwnd, msg, wparam, lparam);
3460}
3461
3462static void test_menu_cancelmode(void)
3463{
3464 DWORD ret;
3465 HWND hwnd, hwndchild;
3466 HMENU menu, menubar;
3467 MSG msg;
3468
3471 NULL, NULL, NULL, NULL);
3473 WS_VISIBLE | WS_CHILD, 10, 10, 20, 20,
3474 hwnd, NULL, NULL, NULL);
3475 ok( hwnd != NULL && hwndchild != NULL,
3476 "CreateWindowEx failed with error %ld\n", GetLastError());
3481 ok( menu != NULL, "CreatePopupMenu failed with error %ld\n", GetLastError());
3482 ret = AppendMenuA( menu, MF_STRING, 1, "winetest");
3483 ok( ret, "Functie failed lasterror is %lu\n", GetLastError());
3484 /* seems to be needed only on wine :( */
3485 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
3487 /* test the effect of sending a WM_CANCELMODE message in the WM_INITMENULOOP
3488 * handler of the menu owner */
3489 /* test results is extracted from variable g_got_enteridle. Possible values:
3490 * 0 : complete conformance. Sending WM_CANCELMODE cancels a menu initializing tracking
3491 * 1 : Sending WM_CANCELMODE cancels a menu that is in tracking state
3492 * 2 : Sending WM_CANCELMODE does not work
3493 */
3494 /* menu owner is top level window */
3496 TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
3497 ok( g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle);
3498 /* menu owner is child window */
3499 g_hwndtosend = hwndchild;
3500 TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL);
3501 ok(g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle);
3502 /* now send the WM_CANCELMODE messages to the WRONG window */
3503 /* those should fail ( to have any effect) */
3505 TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL);
3506 ok( g_got_enteridle == 2, "received %d WM_ENTERIDLE messages, should be 2\n", g_got_enteridle);
3507
3508 /* test canceling tracking in a window's menu bar */
3509 menubar = CreateMenu();
3510 ok( menubar != NULL, "CreateMenu failed with error %ld\n", GetLastError());
3511 ret = AppendMenuA( menubar, MF_POPUP|MF_STRING, (UINT_PTR)menu, "winetest");
3512 ok( ret, "AppendMenuA failed lasterror is %lu\n", GetLastError());
3513 ret = SetMenu( hwnd, menubar );
3514 ok( ret, "SetMenu failed lasterror is %lu\n", GetLastError());
3515 /* initiate tracking */
3518 ok( ret == 0, "Sending WM_SYSCOMMAND/SC_KEYMENU failed lasterror is %lu\n", GetLastError());
3519 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
3521 ok(g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle);
3522
3523 /* cleanup */
3524 DestroyMenu( menubar );
3525 DestroyMenu( menu);
3526 DestroyWindow( hwndchild);
3528}
3529
3530/* show menu trees have a maximum depth */
3531static void test_menu_maxdepth(void)
3532{
3533#define NR_MENUS 100
3534 HMENU hmenus[ NR_MENUS];
3535 int i;
3536 DWORD ret;
3537
3538 SetLastError(12345678);
3539 for( i = 0; i < NR_MENUS; i++) {
3540 hmenus[i] = CreatePopupMenu();
3541 if( !hmenus[i]) break;
3542 }
3543 ok( i == NR_MENUS, "could not create more than %d menu's\n", i);
3544 for( i = 1; i < NR_MENUS; i++) {
3545 ret = AppendMenuA( hmenus[i], MF_POPUP, (UINT_PTR)hmenus[i-1],"test");
3546 if( !ret) break;
3547 }
3548 trace("Maximum depth is %d\n", i);
3549 ok( GetLastError() == 12345678, "unexpected error %ld\n", GetLastError());
3550 ok( i < NR_MENUS ||
3551 broken( i == NR_MENUS), /* win98, NT */
3552 "no ( or very large) limit on menu depth!\n");
3553
3554 for( i = 0; i < NR_MENUS; i++)
3555 DestroyMenu( hmenus[i]);
3556}
3557
3558/* bug #12171 */
3559static void test_menu_circref(void)
3560{
3561 HMENU menu1, menu2;
3562 DWORD ret;
3563
3564 menu1 = CreatePopupMenu();
3565 menu2 = CreatePopupMenu();
3566 ok( menu1 && menu2, "error creating menus.\n");
3567 ret = AppendMenuA( menu1, MF_POPUP, (UINT_PTR)menu2, "winetest");
3568 ok( ret, "AppendMenu failed, error is %ld\n", GetLastError());
3569 ret = AppendMenuA( menu1, MF_STRING | MF_HILITE, 123, "winetest");
3570 ok( ret, "AppendMenu failed, error is %ld\n", GetLastError());
3571 /* app chooses an id that happens to clash with its own hmenu */
3572 ret = AppendMenuA( menu2, MF_STRING, (UINT_PTR)menu2, "winetest");
3573 ok( ret, "AppendMenu failed, error is %ld\n", GetLastError());
3574 /* now attempt to change the string of the first item of menu1 */
3575 ret = ModifyMenuA( menu1, (UINT_PTR)menu2, MF_POPUP, (UINT_PTR)menu2, "menu 2");
3576 ok( !ret ||
3577 broken( ret), /* win98, NT */
3578 "ModifyMenu should have failed.\n");
3579 if( !ret) { /* will probably stack fault if the ModifyMenu succeeded */
3580 ret = GetMenuState( menu1, 123, 0);
3581 ok( ret == MF_HILITE, "GetMenuState returned %lx\n",ret);
3582 }
3583 DestroyMenu( menu2);
3584 DestroyMenu( menu1);
3585}
3586
3587/* test how the menu texts are aligned when the menu items have
3588 * different combinations of text and bitmaps (bug #13350) */
3589static void test_menualign(void)
3590{
3591 BYTE bmfill[300];
3592 HMENU menu;
3593 HBITMAP hbm1, hbm2, hbm3;
3594 MENUITEMINFOA mii = { sizeof(MENUITEMINFOA) };
3595 DWORD ret;
3596 HWND hwnd;
3597 MENUINFO mi = { sizeof( MENUINFO)};
3598
3599 if( !winetest_interactive) {
3600 skip( "interactive alignment tests.\n");
3601 return;
3602 }
3604 "STATIC",
3605 "Menu text alignment Test\nPlease make a selection.",
3607 100, 100,
3608 300, 300,
3609 NULL, NULL, 0, NULL);
3611 /* create bitmaps */
3612 memset( bmfill, 0xcc, sizeof( bmfill));
3613 hbm1 = CreateBitmap( 10,10,1,1,bmfill);
3614 hbm2 = CreateBitmap( 20,20,1,1,bmfill);
3615 hbm3 = CreateBitmap( 50,6,1,1,bmfill);
3616 ok( hbm1 && hbm2 && hbm3, "Creating bitmaps failed\n");
3618 ok( menu != NULL, "CreatePopupMenu() failed\n");
3619
3620 mi.fMask = MIM_STYLE;
3621 ret = GetMenuInfo( menu, &mi);
3622 ok( ret, "GetMenuInfo failed: %ld\n", GetLastError());
3623 ok( menu != NULL, "GetMenuInfo() failed\n");
3624 ok( 0 == mi.dwStyle, "menuinfo style is %lx\n", mi.dwStyle);
3625
3626 /* test 1 */
3628 mii.wID = 1;
3629 mii.hbmpItem = hbm1;
3630 mii.dwTypeData = (LPSTR) " OK: menu texts are correctly left-aligned.";
3631 ret = InsertMenuItemA( menu, -1, TRUE, &mii);
3632 ok( ret, "InsertMenuItem() failed\n");
3634 mii.wID = 2;
3635 mii.hbmpItem = hbm2;
3636 mii.dwTypeData = (LPSTR) " FAIL: menu texts are NOT left-aligned.";
3637 ret = InsertMenuItemA( menu, -1, TRUE, &mii);
3638 ok( ret, "InsertMenuItem() failed\n");
3639 ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL);
3640 ok( ret != 2, "User indicated that menu text alignment test 1 failed %ld\n", ret);
3641 /* test 2*/
3643 mii.wID = 3;
3644 mii.hbmpItem = hbm3;
3645 mii.dwTypeData = NULL;
3646 ret = InsertMenuItemA( menu, 0, TRUE, &mii);
3647 ok( ret, "InsertMenuItem() failed\n");
3649 mii.wID = 1;
3650 mii.hbmpItem = hbm1;
3651 /* make the text a bit longer, to keep it readable */
3652 /* this bug is on winXP and reproduced on wine */
3653 mii.dwTypeData = (LPSTR) " OK: menu texts are to the right of the bitmaps........";
3654 ret = SetMenuItemInfoA( menu, 1, TRUE, &mii);
3655 ok( ret, "SetMenuItemInfo() failed\n");
3656 mii.wID = 2;
3657 mii.hbmpItem = hbm2;
3658 mii.dwTypeData = (LPSTR) " FAIL: menu texts are below the first bitmap. ";
3659 ret = SetMenuItemInfoA( menu, 2, TRUE, &mii);
3660 ok( ret, "SetMenuItemInfo() failed\n");
3661 ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL);
3662 ok( ret != 2, "User indicated that menu text alignment test 2 failed %ld\n", ret);
3663 /* test 3 */
3664 mii.fMask = MIIM_TYPE | MIIM_ID;
3665 mii.wID = 3;
3666 mii.fType = MFT_BITMAP;
3667 mii.dwTypeData = (LPSTR) hbm3;
3668 ret = SetMenuItemInfoA( menu, 0, TRUE, &mii);
3669 ok( ret, "SetMenuItemInfo() failed\n");
3671 mii.wID = 1;
3672 mii.hbmpItem = NULL;
3673 mii.dwTypeData = (LPSTR) " OK: menu texts are below the bitmap.";
3674 ret = SetMenuItemInfoA( menu, 1, TRUE, &mii);
3675 ok( ret, "SetMenuItemInfo() failed\n");
3676 mii.wID = 2;
3677 mii.hbmpItem = NULL;
3678 mii.dwTypeData = (LPSTR) " FAIL: menu texts are NOT below the bitmap.";
3679 ret = SetMenuItemInfoA( menu, 2, TRUE, &mii);
3680 ok( ret, "SetMenuItemInfo() failed\n");
3681 ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL);
3682 ok( ret != 2, "User indicated that menu text alignment test 3 failed %ld\n", ret);
3683 /* cleanup */
3684 DeleteObject( hbm1);
3685 DeleteObject( hbm2);
3686 DeleteObject( hbm3);
3687 DestroyMenu( menu);
3689}
3690
3693{
3694 HMENU hmenupopup;
3695 BOOL ret;
3696 switch (msg)
3697 {
3698 case WM_INITMENUPOPUP:
3700 hmenupopup = (HMENU) wparam;
3701 ret = AppendMenuA(hmenupopup, MF_STRING , 100, "item 1");
3702 ok(ret, "AppendMenu failed.\n");
3703 ret = AppendMenuA(hmenupopup, MF_STRING , 101, "item 2");
3704 ok(ret, "AppendMenu failed.\n");
3705 break;
3706 case WM_ENTERMENULOOP:
3708 break;
3709 case WM_INITMENU:
3711 break;
3712 case WM_ENTERIDLE:
3715 return TRUE;
3716 case WM_MENUSELECT:
3719 break;
3720 }
3721 return DefWindowProcA(hwnd, msg, wparam, lparam);
3722}
3723
3724static void test_emptypopup(void)
3725{
3726 BOOL ret;
3727 HMENU hmenu;
3728
3731 NULL, NULL, NULL, NULL);
3732 ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError());
3734
3736 ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError());
3737
3739 selectitem_wp = 0xdeadbeef;
3740 selectitem_lp = 0xdeadbeef;
3741
3742 ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
3743 ok(ret == 0, "got %i\n", ret);
3744
3745 ok(gflag_initmenupopup == 1, "got %i\n", gflag_initmenupopup);
3746 ok(gflag_entermenuloop == 1, "got %i\n", gflag_entermenuloop);
3747 ok(gflag_initmenu == 1, "got %i\n", gflag_initmenu);
3748 ok(gflag_enteridle == 0, "got %i\n", gflag_initmenu);
3749
3750 ok(selectitem_wp == 0xdeadbeef, "got %Ix\n", selectitem_wp);
3751 ok(selectitem_lp == 0xdeadbeef, "got %Ix\n", selectitem_lp);
3752
3754 selectitem_wp = 0xdeadbeef;
3755 selectitem_lp = 0xdeadbeef;
3756
3757 ret = TrackPopupMenu( hmenu, 0, 100,100, 0, hwnd, NULL);
3758 ok(ret == 0, "got %i\n", ret);
3759
3760 ok(gflag_initmenupopup == 1, "got %i\n", gflag_initmenupopup);
3761 ok(gflag_entermenuloop == 1, "got %i\n", gflag_entermenuloop);
3762 ok(gflag_initmenu == 1, "got %i\n", gflag_initmenu);
3763 ok(gflag_enteridle == 0, "got %i\n", gflag_initmenu);
3764
3765 ok(selectitem_wp == 0xdeadbeef, "got %Ix\n", selectitem_wp);
3766 ok(selectitem_lp == 0xdeadbeef, "got %Ix\n", selectitem_lp);
3767
3769
3771 selectitem_wp = 0xdeadbeef;
3772 selectitem_lp = 0xdeadbeef;
3773
3774 ret = TrackPopupMenu( hmenu, 0, 100,100, 0, hwnd, NULL);
3775 ok(ret == 1, "got %i\n", ret);
3776
3777 ok(gflag_initmenupopup == 1, "got %i\n", gflag_initmenupopup);
3778 ok(gflag_entermenuloop == 1, "got %i\n", gflag_entermenuloop);
3779 ok(gflag_initmenu == 1, "got %i\n", gflag_initmenu);
3780 ok(gflag_enteridle == 1, "got %i\n", gflag_initmenu);
3781
3782 ok(selectitem_wp == 0xffff0000, "got %Ix\n", selectitem_wp);
3783 ok(selectitem_lp == 0, "got %Ix\n", selectitem_lp);
3784
3786
3788 ok(ret, "DestroyMenu failed with error %ld\n", GetLastError());
3789}
3790
3792{
3793 while (IsMenu( (HMENU)id )) id++;
3794 return (HMENU)id;
3795}
3796
3797static void test_AppendMenu(void)
3798{
3799 static char string[] = "string";
3800 MENUITEMINFOA mii;
3801 HMENU hmenu, hsubmenu;
3802 HBITMAP hbmp;
3803 char buf[16];
3804 BOOL ret;
3805
3806 hmenu = CreateMenu();
3807 ok(hmenu != 0, "CreateMenu failed\n");
3808 ret = AppendMenuA(hmenu, MF_OWNERDRAW, 201, "item 1");
3809 ok(ret, "AppendMenu failed\n");
3812
3813 hmenu = CreateMenu();
3814 ok(hmenu != 0, "CreateMenu failed\n");
3815 hsubmenu = get_bad_hmenu( 202 );
3816 ret = AppendMenuA(hmenu, MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
3817 ok(ret, "AppendMenu failed\n");
3818 check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_STRING, 0);
3820
3821 hmenu = CreateMenu();
3822 ok(hmenu != 0, "CreateMenu failed\n");
3823 hsubmenu = get_bad_hmenu( 203 );
3824 ret = AppendMenuA(hmenu, MF_OWNERDRAW | MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
3825 ok(ret, "AppendMenu failed\n");
3828
3829 hmenu = CreateMenu();
3830 ok(hmenu != 0, "CreateMenu failed\n");
3831 hsubmenu = CreateMenu();
3832 ok(hsubmenu != 0, "CreateMenu failed\n");
3833 ret = AppendMenuA(hmenu, MF_OWNERDRAW, (UINT_PTR)hsubmenu, "item 1");
3834 ok(ret, "AppendMenu failed\n");
3837 DestroyMenu(hsubmenu);
3838
3839 hmenu = CreateMenu();
3840 ok(hmenu != 0, "CreateMenu failed\n");
3841 hsubmenu = CreateMenu();
3842 ok(hsubmenu != 0, "CreateMenu failed\n");
3843 ret = AppendMenuA(hmenu, MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
3844 ok(ret, "AppendMenu failed\n");
3845 check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_STRING, 0);
3847 DestroyMenu(hsubmenu);
3848
3849 hmenu = CreateMenu();
3850 ok(hmenu != 0, "CreateMenu failed\n");
3851 hsubmenu = CreateMenu();
3852 ok(hsubmenu != 0, "CreateMenu failed\n");
3853 ret = AppendMenuA(hmenu, MF_OWNERDRAW | MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
3854 ok(ret, "AppendMenu failed\n");
3857 DestroyMenu(hsubmenu);
3858
3859 hmenu = CreateMenu();
3860 ok(hmenu != 0, "CreateMenu failed\n");
3861 hsubmenu = CreatePopupMenu();
3862 ok(hsubmenu != 0, "CreatePopupMenu failed\n");
3863 ret = AppendMenuA(hmenu, MF_OWNERDRAW, (UINT_PTR)hsubmenu, "item 1");
3864 ok(ret, "AppendMenu failed\n");
3867 DestroyMenu(hsubmenu);
3868
3869 hmenu = CreateMenu();
3870 ok(hmenu != 0, "CreateMenu failed\n");
3871 hsubmenu = CreatePopupMenu();
3872 ok(hsubmenu != 0, "CreatePopupMenu failed\n");
3873 ret = AppendMenuA(hmenu, MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
3874 ok(ret, "AppendMenu failed\n");
3875 check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_STRING, 0);
3877 DestroyMenu(hsubmenu);
3878
3879 hmenu = CreateMenu();
3880 ok(hmenu != 0, "CreateMenu failed\n");
3881 hsubmenu = CreatePopupMenu();
3882 ok(hsubmenu != 0, "CreatePopupMenu failed\n");
3883 ret = AppendMenuA(hmenu, MF_OWNERDRAW | MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
3884 ok(ret, "AppendMenu failed\n");
3887 DestroyMenu(hsubmenu);
3888
3889 hmenu = CreateMenu();
3890 ok(hmenu != 0, "CreateMenu failed\n");
3891 ret = AppendMenuA(hmenu, MF_STRING, 204, "item 1");
3892 ok(ret, "AppendMenu failed\n");
3894 hsubmenu = get_bad_hmenu( 205 );
3895 ret = ModifyMenuA(hmenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR)hsubmenu, "item 2");
3896 ok(ret, "ModifyMenu failed\n");
3897 check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_STRING, 0);
3898 memset(&mii, 0, sizeof(mii));
3899 mii.cbSize = sizeof(mii);
3900 mii.fMask = MIIM_SUBMENU;
3901 mii.hSubMenu = get_bad_hmenu( 204 );
3902 ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
3903 ok(!ret, "InsertMenuItem should fail\n");
3904 ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
3905 ok(!ret, "SetMenuItemInfo should fail\n");
3906 mii.fMask = MIIM_ID;
3907 mii.wID = 206;
3908 ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
3909 ok(ret, "InsertMenuItem failed\n");
3910if (0) /* FIXME: uncomment once Wine is fixed */ {
3912}
3913 mii.wID = 207;
3914 ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
3915 ok(ret, "SetMenuItemInfo failed\n");
3916if (0) /* FIXME: uncomment once Wine is fixed */ {
3918}
3920
3921 hbmp = CreateBitmap(1, 1, 1, 1, NULL);
3922 hmenu = CreateMenu();
3923 ok(hmenu != 0, "CreateMenu failed\n");
3924
3925 /* menu item with a string and a bitmap */
3926 memset(&mii, 0, sizeof(mii));
3927 mii.cbSize = sizeof(mii);
3929 mii.dwTypeData = string;
3930 mii.cch = strlen(string);
3931 mii.hbmpItem = hbmp;
3932 ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
3933 ok(ret, "InsertMenuItem failed\n");
3934 memset(&mii, 0x81, sizeof(mii));
3935 memset(buf, 0x81, sizeof(buf));
3936 mii.cbSize = sizeof(mii);
3938 mii.dwTypeData = buf;
3939 mii.cch = sizeof(buf);
3940 mii.dwItemData = 0x81818181;
3941 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
3942 ok(ret, "GetMenuItemInfo failed\n");
3943 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
3944 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
3945 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
3946 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
3947 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
3948 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
3949 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
3950 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
3951 ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
3952
3953 memset(&mii, 0x81, sizeof(mii));
3954 mii.cbSize = sizeof(mii);
3955 mii.fMask = MIIM_TYPE;
3956 mii.dwItemData = 0x81818181;
3957 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
3958 ok(ret, "GetMenuItemInfo failed\n");
3959 ok(mii.fType == MF_BITMAP, "expected MF_BITMAP, got %#x\n", mii.fType);
3960 ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
3961 ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
3962 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
3963 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
3964 ok(mii.dwTypeData == (LPSTR)hbmp, "expected %p, got %p\n", hbmp, mii.dwTypeData);
3965 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
3966 ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
3967
3968 memset(&mii, 0x81, sizeof(mii));
3969 memset(buf, 0x81, sizeof(buf));
3970 mii.cbSize = sizeof(mii);
3972 mii.dwTypeData = buf;
3973 mii.cch = sizeof(buf);
3974 mii.dwItemData = 0x81818181;
3975 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
3976 ok(ret, "GetMenuItemInfo failed\n");
3977 ok(mii.fType == MF_BITMAP, "expected MF_BITMAP, got %#x\n", mii.fType);
3978 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
3979 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
3980 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
3981 ok(mii.dwItemData == 0, "expected 0, got %#Ix\n", mii.dwItemData);
3982 ok(mii.dwTypeData == (LPSTR)hbmp, "expected %p, got %p\n", hbmp, mii.dwTypeData);
3983 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
3984 ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
3985
3988
3989 hmenu = CreateMenu();
3990 ok(hmenu != 0, "CreateMenu failed\n");
3991
3992 /* menu item with a string and a "magic" bitmap */
3993 memset(&mii, 0, sizeof(mii));
3994 mii.cbSize = sizeof(mii);
3996 mii.dwTypeData = string;
3997 mii.cch = strlen(string);
3998 mii.hbmpItem = HBMMENU_POPUP_RESTORE;
3999 ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
4000 ok(ret, "InsertMenuItem failed\n");
4001 memset(&mii, 0x81, sizeof(mii));
4002 memset(buf, 0x81, sizeof(buf));
4003 mii.cbSize = sizeof(mii);
4005 mii.dwTypeData = buf;
4006 mii.cch = sizeof(buf);
4007 mii.dwItemData = 0x81818181;
4008 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4009 ok(ret, "GetMenuItemInfo failed\n");
4010 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4011 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
4012 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
4013 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4014 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4015 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4016 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4017 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4018 ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
4019
4020 memset(&mii, 0x81, sizeof(mii));
4021 mii.cbSize = sizeof(mii);
4022 mii.fMask = MIIM_TYPE;
4023 mii.dwTypeData = buf;
4024 mii.cch = sizeof(buf);
4025 mii.dwItemData = 0x81818181;
4026 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4027 ok(ret, "GetMenuItemInfo failed\n");
4028 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4029 ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
4030 ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
4031 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4032 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4033 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4034 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4035 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4036 ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
4037
4038 memset(&mii, 0x81, sizeof(mii));
4039 memset(buf, 0x81, sizeof(buf));
4040 mii.cbSize = sizeof(mii);
4042 mii.dwTypeData = buf;
4043 mii.cch = sizeof(buf);
4044 mii.dwItemData = 0x81818181;
4045 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4046 ok(ret, "GetMenuItemInfo failed\n");
4047 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4048 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
4049 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
4050 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4051 ok(mii.dwItemData == 0, "expected 0, got %#Ix\n", mii.dwItemData);
4052 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4053 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4054 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4055 ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
4056
4058
4059 hbmp = CreateBitmap(1, 1, 1, 1, NULL);
4060 hmenu = CreateMenu();
4061 ok(hmenu != 0, "CreateMenu failed\n");
4062
4063 /* menu item with a string */
4064 memset(&mii, 0, sizeof(mii));
4065 mii.cbSize = sizeof(mii);
4067 mii.dwItemData = (ULONG_PTR)hbmp;
4068 mii.dwTypeData = string;
4069 mii.cch = strlen(string);
4070 mii.hbmpItem = hbmp;
4071 ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
4072 ok(ret, "InsertMenuItem failed\n");
4073 memset(&mii, 0x81, sizeof(mii));
4074 memset(buf, 0x81, sizeof(buf));
4075 mii.cbSize = sizeof(mii);
4077 mii.dwTypeData = buf;
4078 mii.cch = sizeof(buf);
4079 mii.dwItemData = 0x81818181;
4080 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4081 ok(ret, "GetMenuItemInfo failed\n");
4082 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4083 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
4084 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
4085 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4086 ok(mii.dwItemData == (ULONG_PTR)hbmp, "expected %p, got %#Ix\n", hbmp, mii.dwItemData);
4087 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4088 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4089 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4090 ok(mii.hbmpItem == 0, "expected 0, got %p\n", mii.hbmpItem);
4091
4092 memset(&mii, 0x81, sizeof(mii));
4093 memset(buf, 0x81, sizeof(buf));
4094 mii.cbSize = sizeof(mii);
4095 mii.fMask = MIIM_TYPE;
4096 mii.dwTypeData = buf;
4097 mii.cch = sizeof(buf);
4098 mii.dwItemData = 0x81818181;
4099 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4100 ok(ret, "GetMenuItemInfo failed\n");
4101 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4102 ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
4103 ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
4104 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4105 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4106 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4107 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4108 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4109 ok(mii.hbmpItem == 0, "expected 0, got %p\n", mii.hbmpItem);
4110
4113
4114 /* menu item with a string */
4115 hbmp = CreateBitmap(1, 1, 1, 1, NULL);
4116 hmenu = CreateMenu();
4117 ok(hmenu != 0, "CreateMenu failed\n");
4118 memset(&mii, 0, sizeof(mii));
4119 mii.cbSize = sizeof(mii);
4120 mii.fMask = MIIM_STRING;
4121 mii.dwTypeData = string;
4122 mii.cch = strlen(string);
4123 ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
4124 ok(ret, "InsertMenuItem failed\n");
4125 memset(&mii, 0x81, sizeof(mii));
4126 memset(buf, 0x81, sizeof(buf));
4127 mii.cbSize = sizeof(mii);
4129 mii.dwTypeData = buf;
4130 mii.cch = sizeof(buf);
4131 mii.dwItemData = 0x81818181;
4132 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4133 ok(ret, "GetMenuItemInfo failed\n");
4134 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4135 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
4136 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
4137 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4138 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4139 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4140 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4141 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4142 ok(mii.hbmpItem == 0, "expected 0, got %p\n", mii.hbmpItem);
4143
4144 /* add "magic" bitmap to a menu item */
4145 mii.fMask = MIIM_BITMAP;
4146 mii.hbmpItem = HBMMENU_POPUP_RESTORE;
4147 ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4148 ok(ret, "SetMenuItemInfo failed\n");
4149 memset(&mii, 0x81, sizeof(mii));
4150 memset(buf, 0x81, sizeof(buf));
4151 mii.cbSize = sizeof(mii);
4153 mii.dwTypeData = buf;
4154 mii.cch = sizeof(buf);
4155 mii.dwItemData = 0x81818181;
4156 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4157 ok(ret, "GetMenuItemInfo failed\n");
4158 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4159 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
4160 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
4161 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4162 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4163 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4164 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4165 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4166 ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
4167
4168 memset(&mii, 0x81, sizeof(mii));
4169 memset(buf, 0x81, sizeof(buf));
4170 mii.cbSize = sizeof(mii);
4171 mii.fMask = MIIM_TYPE;
4172 mii.dwTypeData = buf;
4173 mii.cch = sizeof(buf);
4174 mii.dwItemData = 0x81818181;
4175 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4176 ok(ret, "GetMenuItemInfo failed\n");
4177 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4178 ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
4179 ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
4180 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4181 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4182 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4183 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4184 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4185 ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
4186
4187 /* replace "magic" bitmap by a normal one */
4188 mii.fMask = MIIM_BITMAP;
4189 mii.hbmpItem = hbmp;
4190 ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4191 ok(ret, "SetMenuItemInfo failed\n");
4192 memset(&mii, 0x81, sizeof(mii));
4193 memset(buf, 0x81, sizeof(buf));
4194 mii.cbSize = sizeof(mii);
4196 mii.dwTypeData = buf;
4197 mii.cch = sizeof(buf);
4198 mii.dwItemData = 0x81818181;
4199 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4200 ok(ret, "GetMenuItemInfo failed\n");
4201 ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
4202 ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
4203 ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
4204 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4205 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4206 ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
4207 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4208 ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
4209 ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
4210
4211 memset(&mii, 0x81, sizeof(mii));
4212 memset(buf, 0x81, sizeof(buf));
4213 mii.cbSize = sizeof(mii);
4214 mii.fMask = MIIM_TYPE;
4215 mii.dwTypeData = buf;
4216 mii.cch = sizeof(buf);
4217 mii.dwItemData = 0x81818181;
4218 ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
4219 ok(ret, "GetMenuItemInfo failed\n");
4220 ok(mii.fType == MF_BITMAP, "expected MF_BITMAP, got %#x\n", mii.fType);
4221 ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
4222 ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
4223 ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
4224 ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#Ix\n", mii.dwItemData);
4225 ok(mii.dwTypeData == (LPSTR)hbmp, "expected %p, got %p\n", hbmp, mii.dwTypeData);
4226 ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
4227 ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
4228
4231}
4232
4234{
4236
4245
4256
4265}
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
static int state
Definition: maze.c:121
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define ARRAY_SIZE(A)
Definition: main.h:20
HBITMAP hbmp
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define NO_ERROR
Definition: dderror.h:5
#define WAIT_TIMEOUT
Definition: dderror.h:14
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR empty[1]
Definition: string.c:47
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define CALLBACK
Definition: compat.h:35
#define lstrlenW
Definition: compat.h:750
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:518
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3330
#define RGB(r, g, b)
Definition: precomp.h:67
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLint GLuint mask
Definition: glext.h:6028
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLdouble GLdouble right
Definition: glext.h:10859
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLint GLint bottom
Definition: glext.h:7726
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static const WCHAR emptyW[]
Definition: navigate.c:40
static TfClientId tid
static const WCHAR testW[]
Definition: jsregexp.c:44
static const SecPkgInfoW infoW
Definition: kerberos.c:293
int winetest_debug
int winetest_interactive
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define SC_SCREENSAVE
Definition: mmsystem.h:934
char string[160]
Definition: util.h:11
#define sprintf
Definition: sprintf.c:45
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static const CHAR emptyA[]
Definition: printdlg.c:52
static CHAR string2[MAX_PATH]
Definition: automation.c:345
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define menu
Definition: input.c:3273
static void clear_ftype_and_state(HMENU hmenu, UINT id, UINT flags)
Definition: menu.c:2690
static INT popmenu
Definition: menu.c:55
#define TMII_SMII(c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1)
Definition: menu.c:1357
static void test_menu_cancelmode(void)
Definition: menu.c:3462
static int MOD_odheight
Definition: menu.c:78
static RECT MOD_rc[MOD_NRMENUS]
Definition: menu.c:76
static BOOL got_input
Definition: menu.c:56
static DWORD MyTrackPopupMenu(int ex, HMENU hmenu, UINT flags, INT x, INT y, HWND hwnd, LPTPMPARAMS ptpm)
Definition: menu.c:3264
static void test_AppendMenu(void)
Definition: menu.c:3797
static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: menu.c:90
#define TMII_MODM(flags, id, data)
Definition: menu.c:1353
#define ER
Definition: menu.c:1362
#define MOD_NRMENUS
Definition: menu.c:60
static HMENU create_menu_from_data(const struct menu_data *item, INT item_count)
Definition: menu.c:2837
static void test_getmenubarinfo(void)
Definition: menu.c:212
static BOOL bMenuVisible
Definition: menu.c:54
static void test_menu_hilitemenuitem(void)
Definition: menu.c:2491
static BOOL click_menu(HANDLE hWnd, struct menu_item_pair_s *mi)
Definition: menu.c:2241
static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter)
Definition: menu.c:2270
static void test_menu_maxdepth(void)
Definition: menu.c:3531
#define TMII_GMII(c2, l2, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, expname, eret2, eret3)
Definition: menu.c:1341
static HMENU g_hmenu
Definition: menu.c:3385
static void test_InsertMenu(void)
Definition: menu.c:2943
#define compare_menu(h, a)
static WPARAM selectitem_wp
Definition: menu.c:86
SIZE size
Definition: menu.c:65
static void test_menu_trackagain(void)
Definition: menu.c:3410
static void register_menu_check_class(void)
Definition: menu.c:193
#define create_menuitem(a)
static void test_menu_getmenuinfo(void)
Definition: menu.c:3070
static LRESULT WINAPI menu_fill_in_init(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: menu.c:3691
static void test_menualign(void)
Definition: menu.c:3589
#define NR_MENUS
#define TMII_DONE
Definition: menu.c:1347
static void test_system_menu(void)
Definition: menu.c:385
static void test_menu_bmp_and_string(void)
Definition: menu.c:950
static int gflag_entermenuloop
Definition: menu.c:83
static void test_CheckMenuRadioItem(void)
Definition: menu.c:2702
static struct @1863 MOD_txtsizes[]
static void compare_menu_data(HMENU hmenu, const struct menu_data *item, INT item_count)
Definition: menu.c:2898
static BOOL MOD_GotDrawItemMsg
Definition: menu.c:81
static int gflag_initmenupopup
Definition: menu.c:82
static HMENU get_bad_hmenu(UINT_PTR id)
Definition: menu.c:3791
static void test_menu_locked_by_window(void)
Definition: menu.c:572
static void test_menu_resource_layout(void)
Definition: menu.c:2749
#define TMII_INSMI(c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, eret1)
Definition: menu.c:1333
static void test_menu_circref(void)
Definition: menu.c:3559
static void check_menu_item_info(int line, HMENU hmenu, BOOL ansi, UINT mask, UINT type, UINT state, UINT id, HMENU submenu, HBITMAP checked, HBITMAP unchecked, ULONG_PTR data, void *type_data, UINT in_len, UINT out_len, HBITMAP item, LPCSTR expname, BOOL expect, BOOL expstring)
Definition: menu.c:1220
static LRESULT WINAPI menu_check_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: menu.c:38
static void check_menu_items(HMENU hmenu, UINT checked_cmd, UINT checked_type, UINT checked_state)
Definition: menu.c:2629
static void test_emptypopup(void)
Definition: menu.c:3724
SIZE sc_size
Definition: menu.c:66
static int gflag_enteridle
Definition: menu.c:85
static void insert_menu_item(int line, HMENU hmenu, BOOL ansi, UINT mask, UINT type, UINT state, UINT id, HMENU submenu, HBITMAP checked, HBITMAP unchecked, ULONG_PTR data, void *type_data, UINT len, HBITMAP item, BOOL expect)
Definition: menu.c:1190
static LRESULT WINAPI menu_track_again_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: menu.c:3387
static void test_menu_search_bycommand(void)
Definition: menu.c:1859
static LRESULT WINAPI menu_cancelmode_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: menu.c:3440
static int MOD_hic
Definition: menu.c:77
static HMENU create_menuitem_from_data(const struct menu_data *item, INT item_count)
Definition: menu.c:2859
#define create_menu(a)
static ATOM atomMenuCheckClass
Definition: menu.c:36
static void test_GetMenuItemRect(void)
Definition: menu.c:329
#define OK
Definition: menu.c:1361
static void test_menu_iteminfo(void)
Definition: menu.c:1365
static void modify_menu(int line, HMENU hmenu, BOOL ansi, UINT flags, UINT_PTR id, void *data)
Definition: menu.c:1293
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: menu.c:2329
static LPARAM selectitem_lp
Definition: menu.c:87
LPCSTR text
Definition: menu.c:64
static LRESULT WINAPI subpopuplocked_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: menu.c:606
static void test_subpopup_locked_by_menu(void)
Definition: menu.c:622
static void test_menu_ownerdraw(void)
Definition: menu.c:687
static int MOD_avec
Definition: menu.c:77
static void set_menu_item_info(int line, HMENU hmenu, BOOL ansi, UINT mask, UINT type, UINT state, UINT id, HMENU submenu, HBITMAP checked, HBITMAP unchecked, ULONG_PTR data, void *type_data, UINT len, HBITMAP item)
Definition: menu.c:1303
static SIZE MODsizes[MOD_NRMENUS]
Definition: menu.c:79
static void test_menu_flags(void)
Definition: menu.c:2460
static void test_mbs_help(int ispop, int hassub, int mnuopt, HWND hwnd, int arrowwidth, int count, HBITMAP hbmp, SIZE bmpsize, LPCSTR text, SIZE size, SIZE sc_size)
Definition: menu.c:794
static void test_menu_setmenuinfo(void)
Definition: menu.c:3115
static HWND g_hwndtosend
Definition: menu.c:3439
#define MOD_SIZE
Definition: menu.c:59
static void test_menu_trackpopupmenu(void)
Definition: menu.c:3276
static void test_menu_add_string(void)
Definition: menu.c:1063
static int gflag_initmenu
Definition: menu.c:84
static int g_got_enteridle
Definition: menu.c:3438
static struct menu_mouse_tests_s menu_tests[]
static void send_key(WORD wVk)
Definition: menu.c:2231
static HMENU hMenus[4]
Definition: menu.c:57
static unsigned int MOD_maxid
Definition: menu.c:75
static void test_menu_input(void)
Definition: menu.c:2401
static MONITORINFO mi
Definition: win.c:9400
static HMENU hmenu
Definition: win.c:78
int k
Definition: mpi.c:3369
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define WS_SYSMENU
Definition: pedump.c:629
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define err(...)
const WCHAR * str
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
HBRUSH hbrBackground
Definition: winuser.h:3278
HICON hIcon
Definition: winuser.h:3276
HINSTANCE hInstance
Definition: winuser.h:3275
HCURSOR hCursor
Definition: winuser.h:3277
int cbWndExtra
Definition: winuser.h:3274
UINT style
Definition: winuser.h:3271
LPCSTR lpszMenuName
Definition: winuser.h:3279
LPCSTR lpszClassName
Definition: winuser.h:3280
WNDPROC lpfnWndProc
Definition: winuser.h:3272
int cbClsExtra
Definition: winuser.h:3273
Definition: comerr.c:44
uacpi_u8 type
Definition: interpreter.c:38
Definition: parser.c:49
UINT id
Definition: menu.c:2833
const char * str
Definition: menu.c:2834
UINT type
Definition: menu.c:2833
struct menu_item_pair_s menu_item_pairs[5]
Definition: menu.c:2190
WORD wVk[5]
Definition: menu.c:2191
BOOL bMenuVisible
Definition: menu.c:2192
LONG bmWidth
Definition: wingdi.h:1868
ULONG_PTR itemData
Definition: winuser.h:3201
ULONG_PTR itemData
Definition: winuser.h:3754
BOOL fBarFocused
Definition: winuser.h:3838
DWORD cbSize
Definition: winuser.h:3834
LPSTR dwTypeData
Definition: winuser.h:3359
ULONG_PTR dwItemData
Definition: winuser.h:3358
DWORD cbSize
Definition: winuser.h:3892
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
#define GWLP_WNDPROC
Definition: treelist.c:66
#define GWLP_USERDATA
Definition: treelist.c:63
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define HIWORD(l)
Definition: typedefs.h:247
INT WINAPI DrawTextA(HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags)
Definition: font.c:373
static UINT WPARAM LPARAM BOOL ansi
Definition: misc.c:135
#define OBJID_MENU
Definition: winable.h:18
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
#define OBJID_CLIENT
Definition: winable.h:19
#define INPUT_MOUSE
Definition: winable.h:9
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define MAKEINTATOM(i)
Definition: winbase.h:1220
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define ERROR_POPUP_ALREADY_ACTIVE
Definition: winerror.h:1272
#define ERROR_INVALID_MENU_HANDLE
Definition: winerror.h:1227
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:1226
HGDIOBJ WINAPI GetStockObject(_In_ int)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
BOOL WINAPI TextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCSTR lpString, _In_ int c)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define WHITE_PEN
Definition: wingdi.h:905
#define BLACK_PEN
Definition: wingdi.h:903
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
BOOL WINAPI GetTextExtentPointA(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE lpsz)
static int init
Definition: wintirpc.c:33
BOOL WINAPI SetMenuItemInfoA(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOA)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define CS_VREDRAW
Definition: winuser.h:666
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define MOUSEEVENTF_ABSOLUTE
Definition: winuser.h:1205
BOOL WINAPI EndMenu(void)
#define SetWindowLongPtrA
Definition: winuser.h:5511
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define ODS_SELECTED
Definition: winuser.h:2581
BOOL WINAPI SetMenu(_In_ HWND, _In_opt_ HMENU)
#define MF_BYCOMMAND
Definition: winuser.h:202
#define WM_SYSCOMMAND
Definition: winuser.h:1769
#define MF_END
Definition: winuser.h:143
#define MIIM_STRING
Definition: winuser.h:738
#define SC_KEYMENU
Definition: winuser.h:2632
#define MIIM_ID
Definition: winuser.h:733
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
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)
#define COLOR_WINDOW
Definition: winuser.h:929
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define MF_UNHILITE
Definition: winuser.h:206
#define SM_CYSCREEN
Definition: winuser.h:971
UINT WINAPI GetMenuState(_In_ HMENU, _In_ UINT, _In_ UINT)
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
#define MOUSEEVENTF_LEFTUP
Definition: winuser.h:1196
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define VK_F10
Definition: winuser.h:2300
#define HBMMENU_POPUP_RESTORE
Definition: winuser.h:2680
#define SM_CXMENUCHECK
Definition: winuser.h:1042
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
struct tagMENUITEMINFOA MENUITEMINFOA
int WINAPI GetMenuStringW(_In_ HMENU hMenu, _In_ UINT uIDItem, _Out_writes_opt_(cchMax) LPWSTR lpString, _In_ int cchMax, _In_ UINT flags)
#define HBMMENU_POPUP_MINIMIZE
Definition: winuser.h:2682
#define MFT_RIGHTORDER
Definition: winuser.h:756
BOOL WINAPI InsertMenuW(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define MIIM_CHECKMARKS
Definition: winuser.h:735
HMENU WINAPI CreateMenu(void)
Definition: menu.c:829
#define WM_CANCELMODE
Definition: winuser.h:1663
#define DT_SINGLELINE
Definition: winuser.h:540
#define CS_HREDRAW
Definition: winuser.h:661
#define MF_STRING
Definition: winuser.h:138
#define MIIM_FTYPE
Definition: winuser.h:740
#define IDC_ARROW
Definition: winuser.h:695
#define SM_CYMENU
Definition: winuser.h:987
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3064
BOOL WINAPI SetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define MN_GETHMENU
Definition: winuser.h:1801
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define SC_TASKLIST
Definition: winuser.h:2635
BOOL WINAPI IsMenu(_In_ HMENU)
#define WM_INITMENU
Definition: winuser.h:1773
#define GetWindowLongPtrA
Definition: winuser.h:4982
UINT WINAPI GetMenuItemID(_In_ HMENU, _In_ int)
HBITMAP WINAPI LoadBitmapA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2517
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define MFT_SEPARATOR
Definition: winuser.h:755
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:3056
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
#define MNS_CHECKORBMP
Definition: winuser.h:771
BOOL WINAPI InsertMenuA(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
int WINAPI GetMenuStringA(_In_ HMENU hMenu, _In_ UINT uIDItem, _Out_writes_opt_(cchMax) LPSTR lpString, _In_ int cchMax, _In_ UINT flags)
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
BOOL WINAPI HiliteMenuItem(_In_ HWND, _In_ HMENU, _In_ UINT, _In_ UINT)
#define MF_POPUP
Definition: winuser.h:136
#define SM_CYFRAME
Definition: winuser.h:1007
#define WM_DRAWITEM
Definition: winuser.h:1673
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define IDI_APPLICATION
Definition: winuser.h:712
#define MIIM_STATE
Definition: winuser.h:732
struct tagMENUBARINFO MENUBARINFO
#define MF_DEFAULT
Definition: winuser.h:140
#define SC_SIZE
Definition: winuser.h:2620
#define MFS_DEFAULT
Definition: winuser.h:759
BOOL WINAPI ModifyMenuA(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
#define MFT_OWNERDRAW
Definition: winuser.h:752
#define SC_MINIMIZE
Definition: winuser.h:2622
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1194
#define WM_NCMOUSEMOVE
Definition: winuser.h:1719
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1195
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define WM_ENTERMENULOOP
Definition: winuser.h:1832
#define SM_CYMENUCHECK
Definition: winuser.h:1043
#define VK_RETURN
Definition: winuser.h:2237
BOOL WINAPI InsertMenuItemA(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOA)
#define MIIM_SUBMENU
Definition: winuser.h:734
#define HBMMENU_POPUP_CLOSE
Definition: winuser.h:2679
#define MF_MENUBREAK
Definition: winuser.h:134
#define WM_INITMENUPOPUP
Definition: winuser.h:1774
#define MF_ENABLED
Definition: winuser.h:128
#define MFS_GRAYED
Definition: winuser.h:762
#define MF_SEPARATOR
Definition: winuser.h:137
BOOL WINAPI DrawMenuBar(_In_ HWND)
#define MIIM_BITMAP
Definition: winuser.h:739
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2429
#define MF_BYPOSITION
Definition: winuser.h:203
#define PM_REMOVE
Definition: winuser.h:1207
#define MFT_BITMAP
Definition: winuser.h:749
BOOL WINAPI RemoveMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
BOOL WINAPI SetMenuInfo(_In_ HMENU, _In_ LPCMENUINFO)
BOOL WINAPI UpdateWindow(_In_ HWND)
#define MFT_RIGHTJUSTIFY
Definition: winuser.h:754
#define WM_EXITMENULOOP
Definition: winuser.h:1833
#define MFS_CHECKED
Definition: winuser.h:758
HDC WINAPI GetDC(_In_opt_ HWND)
#define MF_BITMAP
Definition: winuser.h:131
#define SC_CLOSE
Definition: winuser.h:2628
#define SC_MOVE
Definition: winuser.h:2621
BOOL WINAPI GetMenuInfo(_In_ HMENU, _Inout_ LPMENUINFO)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4470
#define WM_MEASUREITEM
Definition: winuser.h:1674
BOOL WINAPI AppendMenuA(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
#define WM_LBUTTONUP
Definition: winuser.h:1805
LONG WINAPI GetDialogBaseUnits(void)
Definition: dialog.c:2144
BOOL WINAPI GetMenuItemRect(_In_opt_ HWND, _In_ HMENU, _In_ UINT, _Out_ LPRECT)
#define CW_USEDEFAULT
Definition: winuser.h:225
BOOL WINAPI CheckMenuRadioItem(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT, _In_ UINT)
#define HBMMENU_MBAR_CLOSE
Definition: winuser.h:2676
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MNS_NOCHECK
Definition: winuser.h:766
#define VK_RIGHT
Definition: winuser.h:2262
#define WM_NCLBUTTONUP
Definition: winuser.h:1721
#define VK_DOWN
Definition: winuser.h:2263
#define SM_CXMENUSIZE
Definition: winuser.h:1028
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define MFS_UNCHECKED
Definition: winuser.h:764
#define MF_HILITE
Definition: winuser.h:205
#define MFT_STRING
Definition: winuser.h:757
BOOL WINAPI GetMenuItemInfoA(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOA)
#define SW_SHOW
Definition: winuser.h:786
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
HMENU WINAPI LoadMenuIndirectA(_In_ const MENUTEMPLATE *)
#define SM_CXSCREEN
Definition: winuser.h:970
BOOL WINAPI ModifyMenuW(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define WM_KEYDOWN
Definition: winuser.h:1743
#define MF_HELP
Definition: winuser.h:142
#define SM_CYMENUSIZE
Definition: winuser.h:1029
struct tagMENUINFO MENUINFO
#define TPM_RETURNCMD
Definition: winuser.h:2423
#define DT_CALCRECT
Definition: winuser.h:526
#define MF_OWNERDRAW
Definition: winuser.h:135
#define WM_MENUSELECT
Definition: winuser.h:1775
#define VK_ESCAPE
Definition: winuser.h:2250
#define SC_RESTORE
Definition: winuser.h:2634
#define WM_ENTERIDLE
Definition: winuser.h:1777
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
BOOL WINAPI GetMenuBarInfo(_In_ HWND, _In_ LONG, _In_ LONG, _Inout_ PMENUBARINFO)
#define ODT_MENU
Definition: winuser.h:2573
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SM_CYCAPTION
Definition: winuser.h:974
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
#define MFS_HILITE
Definition: winuser.h:763
#define HBMMENU_CALLBACK
Definition: winuser.h:2672
int WINAPI GetSystemMetrics(_In_ int)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1113
#define MIIM_DATA
Definition: winuser.h:737
#define WM_SYSKEYDOWN
Definition: winuser.h:1747
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1720
#define MIIM_TYPE
Definition: winuser.h:736
HMENU WINAPI GetMenu(_In_ HWND)
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
#define SC_MAXIMIZE
Definition: winuser.h:2624
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2459
#define COLOR_BTNFACE
Definition: winuser.h:939
#define VK_MENU
Definition: winuser.h:2240
#define MFT_RADIOCHECK
Definition: winuser.h:753
#define MFT_MENUBARBREAK
Definition: winuser.h:750
#define MF_GRAYED
Definition: winuser.h:129
#define MF_DISABLED
Definition: winuser.h:130
HMENU WINAPI LoadMenuA(_In_opt_ HINSTANCE, _In_ LPCSTR)
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193