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