ReactOS 0.4.15-dev-8058-ga7cbb60
menu.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Menus
5 * FILE: win32ss/user/ntuser/menu.c
6 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 */
8
9#include <win32k.h>
11
12/* INTERNAL ******************************************************************/
13
15
19
20/* Use global popup window because there's no way 2 menus can
21 * be tracked at the same time. */
24
27
28/* internal popup menu window messages */
29
30#define MM_SETMENUHANDLE (WM_USER + 0)
31#define MM_GETMENUHANDLE (WM_USER + 1)
32
33/* internal flags for menu tracking */
34
35#define TF_ENDMENU 0x10000
36#define TF_SUSPENDPOPUP 0x20000
37#define TF_SKIPREMOVE 0x40000
38
39
40/* maximum allowed depth of any branch in the menu tree.
41 * This value is slightly larger than in windows (25) to
42 * stay on the safe side. */
43#define MAXMENUDEPTH 30
44
45#define MNS_STYLE_MASK (MNS_NOCHECK|MNS_MODELESS|MNS_DRAGDROP|MNS_AUTODISMISS|MNS_NOTIFYBYPOS|MNS_CHECKORBMP)
46
47#define MENUITEMINFO_TYPE_MASK \
48 (MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \
49 MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \
50 MFT_RIGHTORDER | MFT_RIGHTJUSTIFY /* same as MF_HELP */ )
51
52#define TYPE_MASK (MENUITEMINFO_TYPE_MASK | MF_POPUP | MF_SYSMENU)
53
54#define STATE_MASK (~TYPE_MASK)
55
56#define MENUITEMINFO_STATE_MASK (STATE_MASK & ~(MF_BYPOSITION | MF_MOUSESELECT))
57
58#define MII_STATE_MASK (MFS_GRAYED|MFS_CHECKED|MFS_HILITE|MFS_DEFAULT)
59
60#define IS_SYSTEM_MENU(MenuInfo) \
61 (!!((MenuInfo)->fFlags & MNF_SYSMENU))
62
63#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
64#define IS_STRING_ITEM(flags) (MF_STRING == MENU_ITEM_TYPE(flags))
65
66/* Maximum number of menu items a menu can contain */
67#define MAX_MENU_ITEMS (0x4000)
68#define MAX_GOINTOSUBMENU (0x10)
69
70/* Space between 2 columns */
71#define MENU_COL_SPACE 4
72
73#define MENU_ITEM_HBMP_SPACE (5)
74#define MENU_BAR_ITEMS_SPACE (12)
75#define SEPARATOR_HEIGHT (5)
76#define MENU_TAB_SPACE (8)
77
78typedef struct
79{
81 PMENU CurrentMenu; /* current submenu (can be equal to hTopMenu)*/
82 PMENU TopMenu; /* initial menu */
83 PWND OwnerWnd; /* where notifications are sent */
85} MTRACKER;
86
87/* Internal MenuTrackMenu() flags */
88#define TPM_INTERNAL 0xF0000000
89#define TPM_BUTTONDOWN 0x40000000 /* menu was clicked before tracking */
90#define TPM_POPUPMENU 0x20000000 /* menu is a popup menu */
91
92#define ITEM_PREV -1
93#define ITEM_NEXT 1
94
95#define UpdateMenuItemState(state, change) \
96{\
97 if((change) & MF_GRAYED) { \
98 (state) |= MF_GRAYED; \
99 } else { \
100 (state) &= ~MF_GRAYED; \
101 } /* Separate the two for test_menu_resource_layout.*/ \
102 if((change) & MF_DISABLED) { \
103 (state) |= MF_DISABLED; \
104 } else { \
105 (state) &= ~MF_DISABLED; \
106 } \
107 if((change) & MFS_CHECKED) { \
108 (state) |= MFS_CHECKED; \
109 } else { \
110 (state) &= ~MFS_CHECKED; \
111 } \
112 if((change) & MFS_HILITE) { \
113 (state) |= MFS_HILITE; \
114 } else { \
115 (state) &= ~MFS_HILITE; \
116 } \
117 if((change) & MFS_DEFAULT) { \
118 (state) |= MFS_DEFAULT; \
119 } else { \
120 (state) &= ~MFS_DEFAULT; \
121 } \
122 if((change) & MF_MOUSESELECT) { \
123 (state) |= MF_MOUSESELECT; \
124 } else { \
125 (state) &= ~MF_MOUSESELECT; \
126 } \
127}
128
129#if 0
130void FASTCALL
131DumpMenuItemList(PMENU Menu, PITEM MenuItem)
132{
133 UINT cnt = 0, i = Menu->cItems;
134 while(i)
135 {
136 if(MenuItem->lpstr.Length)
137 DbgPrint(" %d. %wZ\n", ++cnt, &MenuItem->lpstr);
138 else
139 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt, (DWORD)MenuItem->lpstr.Buffer);
140 DbgPrint(" fType=");
141 if(MFT_BITMAP & MenuItem->fType)
142 DbgPrint("MFT_BITMAP ");
143 if(MFT_MENUBARBREAK & MenuItem->fType)
144 DbgPrint("MFT_MENUBARBREAK ");
145 if(MFT_MENUBREAK & MenuItem->fType)
146 DbgPrint("MFT_MENUBREAK ");
147 if(MFT_OWNERDRAW & MenuItem->fType)
148 DbgPrint("MFT_OWNERDRAW ");
149 if(MFT_RADIOCHECK & MenuItem->fType)
150 DbgPrint("MFT_RADIOCHECK ");
151 if(MFT_RIGHTJUSTIFY & MenuItem->fType)
152 DbgPrint("MFT_RIGHTJUSTIFY ");
153 if(MFT_SEPARATOR & MenuItem->fType)
154 DbgPrint("MFT_SEPARATOR ");
155 if(MFT_STRING & MenuItem->fType)
156 DbgPrint("MFT_STRING ");
157 DbgPrint("\n fState=");
158 if(MFS_DISABLED & MenuItem->fState)
159 DbgPrint("MFS_DISABLED ");
160 else
161 DbgPrint("MFS_ENABLED ");
162 if(MFS_CHECKED & MenuItem->fState)
163 DbgPrint("MFS_CHECKED ");
164 else
165 DbgPrint("MFS_UNCHECKED ");
166 if(MFS_HILITE & MenuItem->fState)
167 DbgPrint("MFS_HILITE ");
168 else
169 DbgPrint("MFS_UNHILITE ");
170 if(MFS_DEFAULT & MenuItem->fState)
171 DbgPrint("MFS_DEFAULT ");
172 if(MFS_GRAYED & MenuItem->fState)
173 DbgPrint("MFS_GRAYED ");
174 DbgPrint("\n wId=%d\n", MenuItem->wID);
175 MenuItem++;
176 i--;
177 }
178 DbgPrint("Entries: %d\n", cnt);
179 return;
180}
181#endif
182
183#define FreeMenuText(Menu,MenuItem) \
184{ \
185 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
186 (MenuItem)->lpstr.Length) { \
187 DesktopHeapFree(((PMENU)Menu)->head.rpdesk, (MenuItem)->lpstr.Buffer); \
188 } \
189}
190
193{
194 PMENU Menu = UserGetMenuObject(hMenu);
195 if (Menu)
196 Menu->head.cLockObj++;
197
198 return Menu;
199}
200
202{
203 HMENU hMenu;
204 PITEM pItem;
205 ULONG Error;
206 UINT i;
207 if (!pMenu) return NULL;
208
210
212 {
213 hMenu = UserHMGetHandle(pMenu);
214 pItem = pMenu->rgItems;
215 if (pItem)
216 {
217 i = pItem[0].wID;
218 pItem[0].wID = i;
219 }
220 }
222 {
223 ERR("Run away LOOP!\n");
225 _SEH2_YIELD(return NULL);
226 }
228
229 if ( UserObjectInDestroy(hMenu))
230 {
231 ERR("Menu is marked for destruction!\n");
232 pMenu = NULL;
233 }
235 return pMenu;
236}
237
238BOOL
241{
242 if (UserGetMenuObject(Menu)) return TRUE;
243 return FALSE;
244}
245
246
249{
251
252 if (!Wnd)
253 return NULL;
254
256}
257
259{
260 PMENU ret = 0;
262 if (win)
263 {
264 ret = UserGetMenuObject(win->SystemMenu);
265 }
266 return ret;
267}
268
269BOOL IntDestroyMenu( PMENU pMenu, BOOL bRecurse)
270{
271 PMENU SubMenu;
272
274 if (pMenu->rgItems) /* recursively destroy submenus */
275 {
276 int i;
277 ITEM *item = pMenu->rgItems;
278 for (i = pMenu->cItems; i > 0; i--, item++)
279 {
280 SubMenu = item->spSubMenu;
281 item->spSubMenu = NULL;
282
283 /* Remove Item Text */
284 FreeMenuText(pMenu,item);
285
286 /* Remove Item Bitmap and set it for this process */
287 if (item->hbmp && !(item->fState & MFS_HBMMENUBMP))
288 {
290 item->hbmp = NULL;
291 }
292
293 /* Remove Item submenu */
294 if (bRecurse && SubMenu)//VerifyMenu(SubMenu))
295 {
296 /* Release submenu since it was referenced when inserted */
297 IntReleaseMenuObject(SubMenu);
298 IntDestroyMenuObject(SubMenu, bRecurse);
299 }
300 }
301 /* Free the Item */
302 DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems );
303 pMenu->rgItems = NULL;
304 pMenu->cItems = 0;
305 }
306 return TRUE;
307}
308
309/* Callback for the object manager */
312{
314}
315
318{
320 if (Menu)
321 {
322 PWND Window;
323
324 if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId)
325 {
326 BOOL ret;
327 if (Menu->hWnd)
328 {
330 if (Window)
331 {
332 //Window->IDMenu = 0; Only in Win9x!! wine win test_SetMenu test...
333
334 /* DestroyMenu should not destroy system menu popup owner */
335 if ((Menu->fFlags & (MNF_POPUP | MNF_SYSSUBMENU)) == MNF_POPUP)
336 {
337 // Should we check it to see if it has Class?
338 ERR("FIXME Pop up menu window thing'ie\n");
339 //co_UserDestroyWindow( Window );
340 //Menu->hWnd = 0;
341 }
342 }
343 }
344
345 if (!UserMarkObjectDestroy(Menu)) return TRUE;
346
347 /* Remove all menu items */
348 IntDestroyMenu( Menu, bRecurse);
349
351 TRACE("IntDestroyMenuObject %d\n",ret);
352 return ret;
353 }
354 }
355 return FALSE;
356}
357
358BOOL
360{
361 NONCLIENTMETRICSW ncm;
362
363 /* get the menu font */
364 if (!ghMenuFont || !ghMenuFontBold)
365 {
366 ncm.cbSize = sizeof(ncm);
367 if(!UserSystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
368 {
369 ERR("MenuInit(): SystemParametersInfo(SPI_GETNONCLIENTMETRICS) failed!\n");
370 return FALSE;
371 }
372
373 ghMenuFont = GreCreateFontIndirectW(&ncm.lfMenuFont);
374 if (ghMenuFont == NULL)
375 {
376 ERR("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
377 return FALSE;
378 }
379 ncm.lfMenuFont.lfWeight = min(ncm.lfMenuFont.lfWeight + (FW_BOLD - FW_NORMAL), FW_HEAVY);
380 ghMenuFontBold = GreCreateFontIndirectW(&ncm.lfMenuFont);
381 if (ghMenuFontBold == NULL)
382 {
383 ERR("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
386 return FALSE;
387 }
388
391
393 }
394
395 return TRUE;
396}
397
398
399/**********************************************************************
400 * MENU_depth
401 *
402 * detect if there are loops in the menu tree (or the depth is too large)
403 */
405{
406 UINT i;
407 ITEM *item;
408 int subdepth;
409
410 if (!pmenu) return depth;
411
412 depth++;
413 if( depth > MAXMENUDEPTH) return depth;
414 item = pmenu->rgItems;
415 subdepth = depth;
416 for( i = 0; i < pmenu->cItems && subdepth <= MAXMENUDEPTH; i++, item++)
417 {
418 if( item->spSubMenu)//VerifyMenu(item->spSubMenu))
419 {
420 int bdepth = MENU_depth( item->spSubMenu, depth);
421 if( bdepth > subdepth) subdepth = bdepth;
422 }
423 if( subdepth > MAXMENUDEPTH)
424 TRACE("<- hmenu %p\n", item->spSubMenu);
425 }
426 return subdepth;
427}
428
429
430/******************************************************************************
431 *
432 * UINT MenuGetStartOfNextColumn(
433 * PMENU Menu)
434 *
435 *****************************************************************************/
436
438 PMENU menu )
439{
440 PITEM pItem;
441 UINT i;
442
443 if(!menu)
444 return NO_SELECTED_ITEM;
445
446 i = menu->iItem + 1;
447 if( i == NO_SELECTED_ITEM )
448 return i;
449
450 pItem = menu->rgItems;
451 if (!pItem) return NO_SELECTED_ITEM;
452
453 for( ; i < menu->cItems; ++i ) {
454 if (pItem[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
455 return i;
456 }
457
458 return NO_SELECTED_ITEM;
459}
460
461/******************************************************************************
462 *
463 * UINT MenuGetStartOfPrevColumn(
464 * PMENU Menu)
465 *
466 *****************************************************************************/
468 PMENU menu )
469{
470 UINT i;
471 PITEM pItem;
472
473 if( !menu )
474 return NO_SELECTED_ITEM;
475
476 if( menu->iItem == 0 || menu->iItem == NO_SELECTED_ITEM )
477 return NO_SELECTED_ITEM;
478
479 pItem = menu->rgItems;
480 if (!pItem) return NO_SELECTED_ITEM;
481
482 /* Find the start of the column */
483
484 for(i = menu->iItem; i != 0 &&
485 !(pItem[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK));
486 --i); /* empty */
487
488 if(i == 0)
489 return NO_SELECTED_ITEM;
490
491 for(--i; i != 0; --i) {
492 if (pItem[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
493 break;
494 }
495
496 TRACE("ret %d.\n", i );
497
498 return i;
499}
500
501/***********************************************************************
502 * MENU_FindItem
503 *
504 * Find a menu item. Return a pointer on the item, and modifies *hmenu
505 * in case the item was in a sub-menu.
506 */
508{
509 MENU *menu = *pmenu;
510 ITEM *fallback = NULL;
511 UINT fallback_pos = 0;
512 UINT i;
513
514 if (!menu) return NULL;
515
516 if (wFlags & MF_BYPOSITION)
517 {
518 if (!menu->cItems) return NULL;
519 if (*nPos >= menu->cItems) return NULL;
520 return &menu->rgItems[*nPos];
521 }
522 else
523 {
524 PITEM item = menu->rgItems;
525 for (i = 0; i < menu->cItems; i++, item++)
526 {
527 if (item->spSubMenu)
528 {
529 PMENU psubmenu = item->spSubMenu;//VerifyMenu(item->spSubMenu);
530 PITEM subitem = MENU_FindItem( &psubmenu, nPos, wFlags );
531 if (subitem)
532 {
533 *pmenu = psubmenu;
534 return subitem;
535 }
536 else if (item->wID == *nPos)
537 {
538 /* fallback to this item if nothing else found */
539 fallback_pos = i;
540 fallback = item;
541 }
542 }
543 else if (item->wID == *nPos)
544 {
545 *nPos = i;
546 return item;
547 }
548 }
549 }
550
551 if (fallback)
552 *nPos = fallback_pos;
553
554 return fallback;
555}
556
557/***********************************************************************
558 * MenuFindSubMenu
559 *
560 * Find a Sub menu. Return the position of the submenu, and modifies
561 * *hmenu in case it is found in another sub-menu.
562 * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
563 */
564static UINT FASTCALL MENU_FindSubMenu(PMENU *menu, PMENU SubTarget )
565{
566 UINT i;
567 PITEM item;
568
569 item = ((PMENU)*menu)->rgItems;
570 for (i = 0; i < ((PMENU)*menu)->cItems; i++, item++)
571 {
572 if (!item->spSubMenu)
573 continue;
574 else
575 {
576 if (item->spSubMenu == SubTarget)
577 {
578 return i;
579 }
580 else
581 {
582 PMENU pSubMenu = item->spSubMenu;
583 UINT pos = MENU_FindSubMenu( &pSubMenu, SubTarget );
584 if (pos != NO_SELECTED_ITEM)
585 {
586 *menu = pSubMenu;
587 return pos;
588 }
589 }
590 }
591 }
592 return NO_SELECTED_ITEM;
593}
594
596IntRemoveMenuItem( PMENU pMenu, UINT nPos, UINT wFlags, BOOL bRecurse )
597{
598 PITEM item;
599 PITEM newItems;
600
601 TRACE("(menu=%p pos=%04x flags=%04x)\n",pMenu, nPos, wFlags);
602 if (!(item = MENU_FindItem( &pMenu, &nPos, wFlags ))) return FALSE;
603
604 /* Remove item */
605
606 FreeMenuText(pMenu,item);
607 if (bRecurse && item->spSubMenu)
608 {
609 IntDestroyMenuObject(item->spSubMenu, bRecurse);
610 }
612 if (--pMenu->cItems == 0)
613 {
614 DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems );
615 pMenu->rgItems = NULL;
616 }
617 else
618 {
619 while (nPos < pMenu->cItems)
620 {
621 *item = *(item+1);
622 item++;
623 nPos++;
624 }
625 newItems = DesktopHeapReAlloc(pMenu->head.rpdesk, pMenu->rgItems, pMenu->cItems * sizeof(ITEM));
626 if (newItems)
627 {
628 pMenu->rgItems = newItems;
629 }
630 }
631 return TRUE;
632}
633
634/**********************************************************************
635 * MENU_InsertItem
636 *
637 * Insert (allocate) a new item into a menu.
638 */
640{
641 ITEM *newItems;
642
643 /* Find where to insert new item */
644
645 if (flags & MF_BYPOSITION) {
646 if (pos > menu->cItems)
647 pos = menu->cItems;
648 } else {
649 if (!MENU_FindItem( &menu, &pos, flags ))
650 {
651 if (submenu) *submenu = menu;
652 if (npos) *npos = pos;
653 pos = menu->cItems;
654 }
655 }
656
657 /* Make sure that MDI system buttons stay on the right side.
658 * Note: XP treats only bitmap handles 1 - 6 as "magic" ones
659 * regardless of their id.
660 */
661 while ( pos > 0 &&
662 (INT_PTR)menu->rgItems[pos - 1].hbmp >= (INT_PTR)HBMMENU_SYSTEM &&
664 pos--;
665
666 TRACE("inserting at %u flags %x\n", pos, flags);
667
668 /* Create new items array */
669
670 newItems = DesktopHeapAlloc(menu->head.rpdesk, sizeof(ITEM) * (menu->cItems+1) );
671 if (!newItems)
672 {
673 WARN("allocation failed\n" );
674 return NULL;
675 }
676 if (menu->cItems > 0)
677 {
678 /* Copy the old array into the new one */
679 if (pos > 0) RtlCopyMemory( newItems, menu->rgItems, pos * sizeof(ITEM) );
680 if (pos < menu->cItems) RtlCopyMemory( &newItems[pos+1], &menu->rgItems[pos], (menu->cItems-pos)*sizeof(ITEM) );
681 DesktopHeapFree(menu->head.rpdesk, menu->rgItems );
682 }
683 menu->rgItems = newItems;
684 menu->cItems++;
685 RtlZeroMemory( &newItems[pos], sizeof(*newItems) );
686 menu->cyMenu = 0; /* force size recalculate */
687 return &newItems[pos];
688}
689
692 _In_ PMENU MenuObject,
693 UINT uItem,
694 BOOL fByPosition,
695 PROSMENUITEMINFO ItemInfo,
697{
698 PITEM MenuItem;
699 PMENU SubMenu = NULL;
700
701 NT_ASSERT(MenuObject != NULL);
702
703 if (MAX_MENU_ITEMS <= MenuObject->cItems)
704 {
706 return FALSE;
707 }
708
709 SubMenu = MenuObject;
710
711 if(!(MenuItem = MENU_InsertItem( SubMenu, uItem, fByPosition ? MF_BYPOSITION : MF_BYCOMMAND, &SubMenu, &uItem ))) return FALSE;
712
713 if(!IntSetMenuItemInfo(SubMenu, MenuItem, ItemInfo, lpstr))
714 {
715 IntRemoveMenuItem(SubMenu, uItem, fByPosition ? MF_BYPOSITION : MF_BYCOMMAND, FALSE);
716 return FALSE;
717 }
718
719 /* Force size recalculation! */
720 SubMenu->cyMenu = 0;
721 MenuItem->hbmpChecked = MenuItem->hbmpUnchecked = 0;
722
723 TRACE("IntInsertMenuItemToList = %u %i\n", uItem, (BOOL)((INT)uItem >= 0));
724
725 return TRUE;
726}
727
731 _In_ BOOL IsMenuBar,
733 _In_ PPROCESSINFO ppi)
734{
735 PMENU Menu;
736
738 Desktop,
739 ppi->ptiList,
740 Handle,
741 TYPE_MENU,
742 sizeof(MENU));
743 if(!Menu)
744 {
745 *Handle = 0;
746 return NULL;
747 }
748
749 Menu->cyMax = 0; /* Default */
750 Menu->hbrBack = NULL; /* No brush */
751 Menu->dwContextHelpId = 0; /* Default */
752 Menu->dwMenuData = 0; /* Default */
753 Menu->iItem = NO_SELECTED_ITEM; // Focused item
754 Menu->fFlags = (IsMenuBar ? 0 : MNF_POPUP);
755 Menu->spwndNotify = NULL;
756 Menu->cyMenu = 0; // Height
757 Menu->cxMenu = 0; // Width
758 Menu->cItems = 0; // Item count
759 Menu->iTop = 0;
760 Menu->iMaxTop = 0;
761 Menu->cxTextAlign = 0;
762 Menu->rgItems = NULL;
763
764 Menu->hWnd = NULL;
765 Menu->TimeToHide = FALSE;
766
767 return Menu;
768}
769
772{
773 PITEM MenuItem, NewMenuItem = NULL;
774 UINT i;
775
776 if(!Source->cItems)
777 return FALSE;
778
779 NewMenuItem = DesktopHeapAlloc(Destination->head.rpdesk, Source->cItems * sizeof(ITEM));
780 if(!NewMenuItem) return FALSE;
781
782 RtlZeroMemory(NewMenuItem, Source->cItems * sizeof(ITEM));
783
784 Destination->rgItems = NewMenuItem;
785
786 MenuItem = Source->rgItems;
787 for (i = 0; i < Source->cItems; i++, MenuItem++, NewMenuItem++)
788 {
789 NewMenuItem->fType = MenuItem->fType;
790 NewMenuItem->fState = MenuItem->fState;
791 NewMenuItem->wID = MenuItem->wID;
792 NewMenuItem->spSubMenu = MenuItem->spSubMenu;
793 NewMenuItem->hbmpChecked = MenuItem->hbmpChecked;
794 NewMenuItem->hbmpUnchecked = MenuItem->hbmpUnchecked;
795 NewMenuItem->dwItemData = MenuItem->dwItemData;
796 if (MenuItem->lpstr.Length)
797 {
798 NewMenuItem->lpstr.Length = 0;
799 NewMenuItem->lpstr.MaximumLength = MenuItem->lpstr.MaximumLength;
800 NewMenuItem->lpstr.Buffer = DesktopHeapAlloc(Destination->head.rpdesk, MenuItem->lpstr.MaximumLength);
801 if (!NewMenuItem->lpstr.Buffer)
802 {
803 DesktopHeapFree(Destination->head.rpdesk, NewMenuItem);
804 break;
805 }
806 RtlCopyUnicodeString(&NewMenuItem->lpstr, &MenuItem->lpstr);
807 NewMenuItem->lpstr.Buffer[MenuItem->lpstr.Length / sizeof(WCHAR)] = 0;
808 NewMenuItem->Xlpstr = NewMenuItem->lpstr.Buffer;
809 }
810 else
811 {
812 NewMenuItem->lpstr.Buffer = MenuItem->lpstr.Buffer;
813 NewMenuItem->Xlpstr = NewMenuItem->lpstr.Buffer;
814 }
815 NewMenuItem->hbmp = MenuItem->hbmp;
816 Destination->cItems = i + 1;
817 }
818 return TRUE;
819}
820
823{
824 HANDLE hMenu;
825 PMENU Menu;
826
827 if(!Source)
828 return NULL;
829
830 /* A menu is valid process wide. We can pass to the object manager any thread ptr */
832 Source->head.rpdesk,
833 ((PPROCESSINFO)Source->head.hTaskWow)->ptiList,
834 &hMenu,
835 TYPE_MENU,
836 sizeof(MENU));
837 if(!Menu)
838 return NULL;
839
840 Menu->fFlags = Source->fFlags;
841 Menu->cyMax = Source->cyMax;
842 Menu->hbrBack = Source->hbrBack;
843 Menu->dwContextHelpId = Source->dwContextHelpId;
844 Menu->dwMenuData = Source->dwMenuData;
845 Menu->iItem = NO_SELECTED_ITEM;
846 Menu->spwndNotify = NULL;
847 Menu->cyMenu = 0;
848 Menu->cxMenu = 0;
849 Menu->cItems = 0;
850 Menu->iTop = 0;
851 Menu->iMaxTop = 0;
852 Menu->cxTextAlign = 0;
853 Menu->rgItems = NULL;
854
855 Menu->hWnd = NULL;
856 Menu->TimeToHide = FALSE;
857
859
860 return Menu;
861}
862
865{
866 ERR("SetMenuFlagRtoL\n");
867 Menu->fFlags |= MNF_RTOL;
868 return TRUE;
869}
870
872IntSetMenuContextHelpId(PMENU Menu, DWORD dwContextHelpId)
873{
874 Menu->dwContextHelpId = dwContextHelpId;
875 return TRUE;
876}
877
880{
881 if(lpmi->fMask & MIM_BACKGROUND)
882 lpmi->hbrBack = Menu->hbrBack;
883 if(lpmi->fMask & MIM_HELPID)
884 lpmi->dwContextHelpID = Menu->dwContextHelpId;
885 if(lpmi->fMask & MIM_MAXHEIGHT)
886 lpmi->cyMax = Menu->cyMax;
887 if(lpmi->fMask & MIM_MENUDATA)
888 lpmi->dwMenuData = Menu->dwMenuData;
889 if(lpmi->fMask & MIM_STYLE)
890 lpmi->dwStyle = Menu->fFlags & MNS_STYLE_MASK;
891
892 if (sizeof(MENUINFO) < lpmi->cbSize)
893 {
894 lpmi->cItems = Menu->cItems;
895
896 lpmi->iItem = Menu->iItem;
897 lpmi->cxMenu = Menu->cxMenu;
898 lpmi->cyMenu = Menu->cyMenu;
899 lpmi->spwndNotify = Menu->spwndNotify;
900 lpmi->cxTextAlign = Menu->cxTextAlign;
901 lpmi->iTop = Menu->iTop;
902 lpmi->iMaxTop = Menu->iMaxTop;
903 lpmi->dwArrowsOn = Menu->dwArrowsOn;
904
905 lpmi->fFlags = Menu->fFlags;
906 lpmi->Self = UserHMGetHandle(Menu);
907 lpmi->TimeToHide = Menu->TimeToHide;
908 lpmi->Wnd = Menu->hWnd;
909 }
910 return TRUE;
911}
912
915{
916 if(lpmi->fMask & MIM_BACKGROUND)
917 Menu->hbrBack = lpmi->hbrBack;
918 if(lpmi->fMask & MIM_HELPID)
919 Menu->dwContextHelpId = lpmi->dwContextHelpID;
920 if(lpmi->fMask & MIM_MAXHEIGHT)
921 Menu->cyMax = lpmi->cyMax;
922 if(lpmi->fMask & MIM_MENUDATA)
923 Menu->dwMenuData = lpmi->dwMenuData;
924 if(lpmi->fMask & MIM_STYLE)
925 Menu->fFlags ^= (Menu->fFlags ^ lpmi->dwStyle) & MNS_STYLE_MASK;
926 if(lpmi->fMask & MIM_APPLYTOSUBMENUS)
927 {
928 int i;
929 PITEM item = Menu->rgItems;
930 for ( i = Menu->cItems; i; i--, item++)
931 {
932 if ( item->spSubMenu )
933 {
934 IntSetMenuInfo( item->spSubMenu, lpmi);
935 }
936 }
937 }
938 if (sizeof(MENUINFO) < lpmi->cbSize)
939 {
940 Menu->iItem = lpmi->iItem;
941 Menu->cyMenu = lpmi->cyMenu;
942 Menu->cxMenu = lpmi->cxMenu;
943 Menu->spwndNotify = lpmi->spwndNotify;
944 Menu->cxTextAlign = lpmi->cxTextAlign;
945 Menu->iTop = lpmi->iTop;
946 Menu->iMaxTop = lpmi->iMaxTop;
947 Menu->dwArrowsOn = lpmi->dwArrowsOn;
948
949 Menu->TimeToHide = lpmi->TimeToHide;
950 Menu->hWnd = lpmi->Wnd;
951 }
952 if ( lpmi->fMask & MIM_STYLE)
953 {
954 if (lpmi->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented wine\n");
955 if (lpmi->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented wine\n");
956 if (lpmi->dwStyle & MNS_MODELESS) FIXME("MNS_MODELESS unimplemented wine\n");
957 }
958 return TRUE;
959}
960
962IntGetMenuItemInfo(PMENU Menu, /* UNUSED PARAM!! */
963 PITEM MenuItem, PROSMENUITEMINFO lpmii)
964{
966
967 if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
968 {
969 lpmii->fType = MenuItem->fType;
970 }
971 if(lpmii->fMask & MIIM_BITMAP)
972 {
973 lpmii->hbmpItem = MenuItem->hbmp;
974 }
975 if(lpmii->fMask & MIIM_CHECKMARKS)
976 {
977 lpmii->hbmpChecked = MenuItem->hbmpChecked;
978 lpmii->hbmpUnchecked = MenuItem->hbmpUnchecked;
979 }
980 if(lpmii->fMask & MIIM_DATA)
981 {
982 lpmii->dwItemData = MenuItem->dwItemData;
983 }
984 if(lpmii->fMask & MIIM_ID)
985 {
986 lpmii->wID = MenuItem->wID;
987 }
988 if(lpmii->fMask & MIIM_STATE)
989 {
990 lpmii->fState = MenuItem->fState;
991 }
992 if(lpmii->fMask & MIIM_SUBMENU)
993 {
994 lpmii->hSubMenu = (MenuItem->spSubMenu ? UserHMGetHandle(MenuItem->spSubMenu) : NULL);
995 }
996
997 if ((lpmii->fMask & MIIM_STRING) ||
998 ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)))
999 {
1000 if (lpmii->dwTypeData == NULL)
1001 {
1002 lpmii->cch = MenuItem->lpstr.Length / sizeof(WCHAR);
1003 }
1004 else
1005 {
1006 Status = MmCopyToCaller(lpmii->dwTypeData, MenuItem->lpstr.Buffer,
1007 min(lpmii->cch * sizeof(WCHAR),
1008 MenuItem->lpstr.MaximumLength));
1009 if (! NT_SUCCESS(Status))
1010 {
1012 return FALSE;
1013 }
1014 }
1015 }
1016
1017 if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize)
1018 {
1019 lpmii->Rect.left = MenuItem->xItem;
1020 lpmii->Rect.top = MenuItem->yItem;
1021 lpmii->Rect.right = MenuItem->cxItem; // Do this for now......
1022 lpmii->Rect.bottom = MenuItem->cyItem;
1023 lpmii->dxTab = MenuItem->dxTab;
1024 lpmii->lpstr = MenuItem->lpstr.Buffer;
1025 lpmii->maxBmpSize.cx = MenuItem->cxBmp;
1026 lpmii->maxBmpSize.cy = MenuItem->cyBmp;
1027 }
1028
1029 return TRUE;
1030}
1031
1034{
1035 PMENU SubMenuObject;
1036 BOOL circref = FALSE;
1037
1038 if(!MenuItem || !MenuObject || !lpmii)
1039 {
1040 return FALSE;
1041 }
1042 if ( lpmii->fMask & MIIM_FTYPE )
1043 {
1044 MenuItem->fType &= ~MENUITEMINFO_TYPE_MASK;
1045 MenuItem->fType |= lpmii->fType & MENUITEMINFO_TYPE_MASK;
1046 }
1047 if (lpmii->fMask & MIIM_TYPE)
1048 {
1049 #if 0
1050 if (lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP))
1051 {
1052 ERR("IntSetMenuItemInfo: Invalid combination of fMask bits used\n");
1054 /* This does not happen on Win9x/ME */
1056 return FALSE;
1057 }
1058 #endif
1059 /*
1060 * Delete the menu item type when changing type from
1061 * MF_STRING.
1062 */
1063 if (MenuItem->fType != lpmii->fType &&
1064 MENU_ITEM_TYPE(MenuItem->fType) == MFT_STRING)
1065 {
1066 FreeMenuText(MenuObject,MenuItem);
1067 RtlInitUnicodeString(&MenuItem->lpstr, NULL);
1068 MenuItem->Xlpstr = NULL;
1069 }
1070 if(lpmii->fType & MFT_BITMAP)
1071 {
1072 if(lpmii->hbmpItem)
1073 MenuItem->hbmp = lpmii->hbmpItem;
1074 else
1075 { /* Win 9x/Me stuff */
1076 MenuItem->hbmp = (HBITMAP)((ULONG_PTR)(LOWORD(lpmii->dwTypeData)));
1077 }
1078 lpmii->dwTypeData = 0;
1079 }
1080 }
1081 if(lpmii->fMask & MIIM_BITMAP)
1082 {
1083 MenuItem->hbmp = lpmii->hbmpItem;
1084 if (MenuItem->hbmp <= HBMMENU_POPUP_MINIMIZE && MenuItem->hbmp >= HBMMENU_CALLBACK)
1085 MenuItem->fState |= MFS_HBMMENUBMP;
1086 else
1087 MenuItem->fState &= ~MFS_HBMMENUBMP;
1088 }
1089 if(lpmii->fMask & MIIM_CHECKMARKS)
1090 {
1091 MenuItem->hbmpChecked = lpmii->hbmpChecked;
1092 MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked;
1093 }
1094 if(lpmii->fMask & MIIM_DATA)
1095 {
1096 MenuItem->dwItemData = lpmii->dwItemData;
1097 }
1098 if(lpmii->fMask & MIIM_ID)
1099 {
1100 MenuItem->wID = lpmii->wID;
1101 }
1102 if(lpmii->fMask & MIIM_STATE)
1103 {
1104 /* Remove MFS_DEFAULT flag from all other menu items if this item
1105 has the MFS_DEFAULT state */
1106 if(lpmii->fState & MFS_DEFAULT)
1107 UserSetMenuDefaultItem(MenuObject, -1, 0);
1108 /* Update the menu item state flags */
1109 UpdateMenuItemState(MenuItem->fState, lpmii->fState);
1110 }
1111
1112 if(lpmii->fMask & MIIM_SUBMENU)
1113 {
1114 if (lpmii->hSubMenu)
1115 {
1116 SubMenuObject = UserGetMenuObject(lpmii->hSubMenu);
1117 if ( SubMenuObject && !(UserObjectInDestroy(lpmii->hSubMenu)) )
1118 {
1121 if (MenuObject == SubMenuObject)
1122 {
1123 HANDLE hMenu;
1124 ERR("Pop Up Menu Double Trouble!\n");
1125 SubMenuObject = IntCreateMenu(&hMenu,
1126 FALSE,
1127 MenuObject->head.rpdesk,
1128 (PPROCESSINFO)MenuObject->head.hTaskWow); // It will be marked.
1129 if (!SubMenuObject) return FALSE;
1130 IntReleaseMenuObject(SubMenuObject); // This will be referenced again after insertion.
1131 circref = TRUE;
1132 }
1133 if ( MENU_depth( SubMenuObject, 0) > MAXMENUDEPTH )
1134 {
1135 ERR( "Loop detected in menu hierarchy or maximum menu depth exceeded!\n");
1136 if (circref) IntDestroyMenuObject(SubMenuObject, FALSE);
1137 return FALSE;
1138 }
1139 /* Make sure the submenu is marked as a popup menu */
1140 SubMenuObject->fFlags |= MNF_POPUP;
1141 // Now fix the test_subpopup_locked_by_menu tests....
1142 if (MenuItem->spSubMenu) IntReleaseMenuObject(MenuItem->spSubMenu);
1143 MenuItem->spSubMenu = SubMenuObject;
1144 UserReferenceObject(SubMenuObject);
1145 }
1146 else
1147 {
1149 return FALSE;
1150 }
1151 }
1152 else
1153 { // If submenu just dereference it.
1154 if (MenuItem->spSubMenu) IntReleaseMenuObject(MenuItem->spSubMenu);
1155 MenuItem->spSubMenu = NULL;
1156 }
1157 }
1158
1159 if ((lpmii->fMask & MIIM_STRING) ||
1160 ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)))
1161 {
1162 /* free the string when used */
1163 FreeMenuText(MenuObject,MenuItem);
1164 RtlInitUnicodeString(&MenuItem->lpstr, NULL);
1165 MenuItem->Xlpstr = NULL;
1166
1167 if(lpmii->dwTypeData && lpmii->cch && lpstr && lpstr->Buffer)
1168 {
1170
1171 if (!NT_VERIFY(lpmii->cch <= UNICODE_STRING_MAX_CHARS))
1172 {
1173 return FALSE;
1174 }
1175
1176 Source.Length = Source.MaximumLength = (USHORT)(lpmii->cch * sizeof(WCHAR));
1177 Source.Buffer = lpmii->dwTypeData;
1178
1179 MenuItem->lpstr.Buffer = DesktopHeapAlloc( MenuObject->head.rpdesk, Source.Length + sizeof(WCHAR));
1180 if(MenuItem->lpstr.Buffer != NULL)
1181 {
1182 MenuItem->lpstr.Length = 0;
1183 MenuItem->lpstr.MaximumLength = Source.Length + sizeof(WCHAR);
1184 RtlCopyUnicodeString(&MenuItem->lpstr, &Source);
1185 MenuItem->lpstr.Buffer[MenuItem->lpstr.Length / sizeof(WCHAR)] = 0;
1186
1187 MenuItem->cch = MenuItem->lpstr.Length / sizeof(WCHAR);
1188 MenuItem->Xlpstr = (USHORT*)MenuItem->lpstr.Buffer;
1189 }
1190 }
1191 }
1192
1193 if( !(MenuObject->fFlags & MNF_SYSMENU) &&
1194 !MenuItem->Xlpstr &&
1195 !lpmii->dwTypeData &&
1196 !(MenuItem->fType & MFT_OWNERDRAW) &&
1197 !MenuItem->hbmp)
1198 MenuItem->fType |= MFT_SEPARATOR;
1199
1200 if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize)
1201 {
1202 MenuItem->xItem = lpmii->Rect.left;
1203 MenuItem->yItem = lpmii->Rect.top;
1204 MenuItem->cxItem = lpmii->Rect.right; // Do this for now......
1205 MenuItem->cyItem = lpmii->Rect.bottom;
1206 MenuItem->dxTab = lpmii->dxTab;
1207 lpmii->lpstr = MenuItem->lpstr.Buffer; /* Send back new allocated string or zero */
1208 MenuItem->cxBmp = lpmii->maxBmpSize.cx;
1209 MenuItem->cyBmp = lpmii->maxBmpSize.cy;
1210 }
1211
1212 return TRUE;
1213}
1214
1215
1217IntEnableMenuItem(PMENU MenuObject, UINT uIDEnableItem, UINT uEnable)
1218{
1219 PITEM MenuItem;
1220 UINT res;
1221
1222 if (!(MenuItem = MENU_FindItem( &MenuObject, &uIDEnableItem, uEnable ))) return (UINT)-1;
1223
1224 res = MenuItem->fState & (MF_GRAYED | MF_DISABLED);
1225
1226 MenuItem->fState ^= (res ^ uEnable) & (MF_GRAYED | MF_DISABLED);
1227
1228 /* If the close item in the system menu change update the close button */
1229 if (res != uEnable)
1230 {
1231 switch (MenuItem->wID) // More than just close.
1232 {
1233 case SC_CLOSE:
1234 case SC_MAXIMIZE:
1235 case SC_MINIMIZE:
1236 case SC_MOVE:
1237 case SC_RESTORE:
1238 case SC_SIZE:
1239 if (MenuObject->fFlags & MNF_SYSSUBMENU && MenuObject->spwndNotify != 0)
1240 {
1241 //RECTL rc = MenuObject->spwndNotify->rcWindow;
1242
1243 /* Refresh the frame to reflect the change */
1244 //IntMapWindowPoints(0, MenuObject->spwndNotify, (POINT *)&rc, 2);
1245 //rc.bottom = 0;
1246 //co_UserRedrawWindow(MenuObject->spwndNotify, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
1247
1248 // Allow UxTheme!
1249 UserPaintCaption(MenuObject->spwndNotify, DC_BUTTONS);
1250 }
1251 default:
1252 break;
1253 }
1254 }
1255 return res;
1256}
1257
1259IntCheckMenuItem(PMENU MenuObject, UINT uIDCheckItem, UINT uCheck)
1260{
1261 PITEM MenuItem;
1262 DWORD res;
1263
1264 if (!(MenuItem = MENU_FindItem( &MenuObject, &uIDCheckItem, uCheck ))) return -1;
1265
1266 res = (DWORD)(MenuItem->fState & MF_CHECKED);
1267
1268 MenuItem->fState ^= (res ^ uCheck) & MF_CHECKED;
1269
1270 return res;
1271}
1272
1274UserSetMenuDefaultItem(PMENU MenuObject, UINT uItem, UINT fByPos)
1275{
1276 UINT i;
1277 PITEM MenuItem = MenuObject->rgItems;
1278
1279 if (!MenuItem) return FALSE;
1280
1281 /* reset all default-item flags */
1282 for (i = 0; i < MenuObject->cItems; i++, MenuItem++)
1283 {
1284 MenuItem->fState &= ~MFS_DEFAULT;
1285 }
1286
1287 /* no default item */
1288 if(uItem == (UINT)-1)
1289 {
1290 return TRUE;
1291 }
1292 MenuItem = MenuObject->rgItems;
1293 if ( fByPos )
1294 {
1295 if ( uItem >= MenuObject->cItems ) return FALSE;
1296 MenuItem[uItem].fState |= MFS_DEFAULT;
1297 return TRUE;
1298 }
1299 else
1300 {
1301 for (i = 0; i < MenuObject->cItems; i++, MenuItem++)
1302 {
1303 if (MenuItem->wID == uItem)
1304 {
1305 MenuItem->fState |= MFS_DEFAULT;
1306 return TRUE;
1307 }
1308 }
1309
1310 }
1311 return FALSE;
1312}
1313
1315IntGetMenuDefaultItem(PMENU MenuObject, UINT fByPos, UINT gmdiFlags, DWORD *gismc)
1316{
1317 UINT i = 0;
1318 PITEM MenuItem = MenuObject->rgItems;
1319
1320 /* empty menu */
1321 if (!MenuItem) return -1;
1322
1323 while ( !( MenuItem->fState & MFS_DEFAULT ) )
1324 {
1325 i++; MenuItem++;
1326 if (i >= MenuObject->cItems ) return -1;
1327 }
1328
1329 /* default: don't return disabled items */
1330 if ( (!(GMDI_USEDISABLED & gmdiFlags)) && (MenuItem->fState & MFS_DISABLED )) return -1;
1331
1332 /* search rekursiv when needed */
1333 if ( (gmdiFlags & GMDI_GOINTOPOPUPS) && MenuItem->spSubMenu )
1334 {
1335 UINT ret;
1336 (*gismc)++;
1337 ret = IntGetMenuDefaultItem( MenuItem->spSubMenu, fByPos, gmdiFlags, gismc );
1338 (*gismc)--;
1339 if ( -1 != ret ) return ret;
1340
1341 /* when item not found in submenu, return the popup item */
1342 }
1343 return ( fByPos ) ? i : MenuItem->wID;
1344}
1345
1346PMENU
1349 PMENU pMenu,
1350 int nPos)
1351{
1352 PITEM pItem;
1353 if (!(pItem = MENU_FindItem( &pMenu, (UINT*)&nPos, MF_BYPOSITION ))) return NULL;
1354 return pItem->spSubMenu;
1355}
1356
1357/***********************************************************************
1358 * MenuInitSysMenuPopup
1359 *
1360 * Grey the appropriate items in System menu.
1361 */
1363{
1364 BOOL gray;
1365 UINT DefItem;
1366
1367 gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
1368 IntEnableMenuItem( menu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
1369 gray = ((style & (WS_MAXIMIZE | WS_MINIMIZE)) != 0);
1370 IntEnableMenuItem( menu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
1371 gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
1373 gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
1375 gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
1376 IntEnableMenuItem( menu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
1377 gray = (clsStyle & CS_NOCLOSE) != 0;
1378
1379 /* The menu item must keep its state if it's disabled */
1380 if(gray)
1382
1383 /* Set default menu item */
1384 if(style & WS_MINIMIZE) DefItem = SC_RESTORE;
1385 else if(HitTest == HTCAPTION) DefItem = ((style & (WS_MAXIMIZE | WS_MINIMIZE)) ? SC_RESTORE : SC_MAXIMIZE);
1386 else DefItem = SC_CLOSE;
1387
1388 UserSetMenuDefaultItem(menu, DefItem, MF_BYCOMMAND);
1389}
1390
1391
1392/***********************************************************************
1393 * MenuDrawPopupGlyph
1394 *
1395 * Draws popup magic glyphs (can be found in system menu).
1396 */
1397static void FASTCALL
1398MENU_DrawPopupGlyph(HDC dc, LPRECT r, INT_PTR popupMagic, BOOL inactive, BOOL hilite)
1399{
1400 LOGFONTW lf;
1401 HFONT hFont, hOldFont;
1402 COLORREF clrsave;
1403 INT bkmode;
1404 WCHAR symbol;
1405 switch (popupMagic)
1406 {
1408 symbol = '2';
1409 break;
1411 symbol = '0';
1412 break;
1414 symbol = '1';
1415 break;
1417 symbol = 'r';
1418 break;
1419 default:
1420 ERR("Invalid popup magic bitmap %d\n", (int)popupMagic);
1421 return;
1422 }
1423 RtlZeroMemory(&lf, sizeof(LOGFONTW));
1424 RECTL_vInflateRect(r, -2, -2);
1425 lf.lfHeight = r->bottom - r->top;
1426 lf.lfWidth = 0;
1427 lf.lfWeight = FW_NORMAL;
1429 RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett"));
1431 /* save font and text color */
1432 hOldFont = NtGdiSelectFont(dc, hFont);
1433 clrsave = GreGetTextColor(dc);
1434 bkmode = GreGetBkMode(dc);
1435 /* set color and drawing mode */
1437 if (inactive)
1438 {
1439 /* draw shadow */
1440 if (!hilite)
1441 {
1443 GreTextOutW(dc, r->left + 1, r->top + 1, &symbol, 1);
1444 }
1445 }
1447 /* draw selected symbol */
1448 GreTextOutW(dc, r->left, r->top, &symbol, 1);
1449 /* restore previous settings */
1450 IntGdiSetTextColor(dc, clrsave);
1451 NtGdiSelectFont(dc, hOldFont);
1452 IntGdiSetBkMode(dc, bkmode);
1454}
1455
1456/***********************************************************************
1457 * MENU_AdjustMenuItemRect
1458 *
1459 * Adjust menu item rectangle according to scrolling state.
1460 */
1463{
1464 if (menu->dwArrowsOn)
1465 {
1466 UINT arrow_bitmap_height;
1467 arrow_bitmap_height = gpsi->oembmi[OBI_UPARROW].cy;
1468 rect->top += arrow_bitmap_height - menu->iTop;
1469 rect->bottom += arrow_bitmap_height - menu->iTop;
1470 }
1471}
1472
1473/***********************************************************************
1474 * MENU_FindItemByCoords
1475 *
1476 * Find the item at the specified coordinates (screen coords). Does
1477 * not work for child windows and therefore should not be called for
1478 * an arbitrary system menu.
1479 */
1481{
1482 ITEM *item;
1483 UINT i;
1484 INT cx, cy;
1485 RECT rect;
1486 PWND pWnd = ValidateHwndNoErr(menu->hWnd);
1487
1488 if (!IntGetWindowRect(pWnd, &rect)) return NULL;
1489
1493
1494 if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
1495 pt.x = rect.right - 1 - pt.x;
1496 else
1497 pt.x -= rect.left;
1498 pt.y -= rect.top;
1499 item = menu->rgItems;
1500 for (i = 0; i < menu->cItems; i++, item++)
1501 {
1502 //rect = item->rect;
1503 rect.left = item->xItem;
1504 rect.top = item->yItem;
1505 rect.right = item->cxItem; // Do this for now......
1506 rect.bottom = item->cyItem;
1507
1509 if (RECTL_bPointInRect(&rect, pt.x, pt.y))
1510 {
1511 if (pos) *pos = i;
1512 return item;
1513 }
1514 }
1515 return NULL;
1516}
1517
1519{
1520 MENU *menu = UserGetMenuObject(hMenu);
1521 UINT pos;
1522
1523 /*FIXME: Do we have to handle hWnd here? */
1524 if (!menu) return -1;
1525 if (!MENU_FindItemByCoords(menu, ptScreen, &pos)) return -1;
1526 return pos;
1527}
1528
1529/***********************************************************************
1530 * MenuFindItemByKey
1531 *
1532 * Find the menu item selected by a key press.
1533 * Return item id, -1 if none, -2 if we should close the menu.
1534 */
1536 WCHAR Key, BOOL ForceMenuChar)
1537{
1538 LRESULT MenuChar;
1539 WORD Flags = 0;
1540
1541 TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)Key, Key, menu );
1542
1543 if (!menu || !VerifyMenu(menu))
1544 menu = co_IntGetSubMenu( UserGetMenuObject(WndOwner->SystemMenu), 0 );
1545 if (menu)
1546 {
1547 ITEM *item = menu->rgItems;
1548
1549 if ( !ForceMenuChar )
1550 {
1551 UINT i;
1553
1554 for (i = 0; i < menu->cItems; i++, item++)
1555 {
1556 LPWSTR text = item->Xlpstr;
1557 if( text)
1558 {
1559 const WCHAR *p = text - 2;
1560 do
1561 {
1562 const WCHAR *q = p + 2;
1563 p = wcschr (q, '&');
1564 if (!p && cjk) p = wcschr (q, '\036'); /* Japanese Win16 */
1565 }
1566 while (p != NULL && p [1] == '&');
1567 if (p && (towupper(p[1]) == towupper(Key))) return i;
1568 }
1569 }
1570 }
1571
1572 Flags |= menu->fFlags & MNF_POPUP ? MF_POPUP : 0;
1573 Flags |= menu->fFlags & MNF_SYSMENU ? MF_SYSMENU : 0;
1574
1575 MenuChar = co_IntSendMessage( UserHMGetHandle(WndOwner), WM_MENUCHAR,
1577 if (HIWORD(MenuChar) == MNC_EXECUTE) return LOWORD(MenuChar);
1578 if (HIWORD(MenuChar) == MNC_CLOSE) return (UINT)(-2);
1579 }
1580 return (UINT)(-1);
1581}
1582
1583/***********************************************************************
1584 * MenuGetBitmapItemSize
1585 *
1586 * Get the size of a bitmap item.
1587 */
1588static void FASTCALL MENU_GetBitmapItemSize(PITEM lpitem, SIZE *size, PWND WndOwner)
1589{
1590 BITMAP bm;
1591 HBITMAP bmp = lpitem->hbmp;
1592
1593 size->cx = size->cy = 0;
1594
1595 /* check if there is a magic menu item associated with this item */
1596 if (IS_MAGIC_BITMAP(bmp))
1597 {
1598 switch((INT_PTR) bmp)
1599 {
1601 {
1602 MEASUREITEMSTRUCT measItem;
1603 measItem.CtlType = ODT_MENU;
1604 measItem.CtlID = 0;
1605 measItem.itemID = lpitem->wID;
1606 measItem.itemWidth = lpitem->cxItem - lpitem->xItem; //lpitem->Rect.right - lpitem->Rect.left;
1607 measItem.itemHeight = lpitem->cyItem - lpitem->yItem; //lpitem->Rect.bottom - lpitem->Rect.top;
1608 measItem.itemData = lpitem->dwItemData;
1609 co_IntSendMessage( UserHMGetHandle(WndOwner), WM_MEASUREITEM, 0, (LPARAM)&measItem);
1610 size->cx = measItem.itemWidth;
1611 size->cy = measItem.itemHeight;
1612 TRACE("HBMMENU_CALLBACK Height %d Width %d\n",measItem.itemHeight,measItem.itemWidth);
1613 return;
1614 }
1615 break;
1616
1617 case (INT_PTR) HBMMENU_SYSTEM:
1618 if (lpitem->dwItemData)
1619 {
1620 bmp = (HBITMAP) lpitem->dwItemData;
1621 break;
1622 }
1623 /* fall through */
1633 /* FIXME: Why we need to subtract these magic values? */
1634 /* to make them smaller than the menu bar? */
1637 return;
1638 }
1639 }
1640
1641 if (GreGetObject(bmp, sizeof(BITMAP), &bm))
1642 {
1643 size->cx = bm.bmWidth;
1644 size->cy = bm.bmHeight;
1645 }
1646}
1647
1648/***********************************************************************
1649 * MenuDrawBitmapItem
1650 *
1651 * Draw a bitmap item.
1652 */
1653static void FASTCALL MENU_DrawBitmapItem(HDC hdc, PITEM lpitem, const RECT *rect,
1654 PMENU Menu, PWND WndOwner, UINT odaction, BOOL MenuBar)
1655{
1656 BITMAP bm;
1657 DWORD rop;
1658 HDC hdcMem;
1659 HBITMAP bmp;
1660 int w = rect->right - rect->left;
1661 int h = rect->bottom - rect->top;
1662 int bmp_xoffset = 0;
1663 int left, top;
1664 BOOL flat_menu;
1665 HBITMAP hbmToDraw = lpitem->hbmp;
1666 bmp = hbmToDraw;
1667
1668 UserSystemParametersInfo(SPI_GETFLATMENU, 0, &flat_menu, 0);
1669
1670 /* Check if there is a magic menu item associated with this item */
1671 if (IS_MAGIC_BITMAP(hbmToDraw))
1672 {
1673 UINT flags = 0;
1674 RECT r;
1675
1676 r = *rect;
1677 switch ((INT_PTR)hbmToDraw)
1678 {
1679 case (INT_PTR)HBMMENU_SYSTEM:
1680 if (lpitem->dwItemData)
1681 {
1682 if (ValidateHwndNoErr((HWND)lpitem->dwItemData))
1683 {
1684 ERR("Get Item Data from this Window!!!\n");
1685 }
1686
1687 ERR("Draw Bitmap\n");
1688 bmp = (HBITMAP)lpitem->dwItemData;
1689 if (!GreGetObject( bmp, sizeof(bm), &bm )) return;
1690 }
1691 else
1692 {
1693 PCURICON_OBJECT pIcon = NULL;
1694 //if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
1695 //bmp = BmpSysMenu;
1696 //if (! GreGetObject(bmp, sizeof(bm), &bm)) return;
1697 /* only use right half of the bitmap */
1698 //bmp_xoffset = bm.bmWidth / 2;
1699 //bm.bmWidth -= bmp_xoffset;
1700 if (WndOwner)
1701 {
1702 pIcon = NC_IconForWindow(WndOwner);
1703 // FIXME: NC_IconForWindow should reference it for us */
1704 if (pIcon) UserReferenceObject(pIcon);
1705 }
1706 ERR("Draw ICON\n");
1707 if (pIcon)
1708 {
1711 LONG x = rect->left - cx/2 + 1 + (rect->bottom - rect->top)/2; // this is really what Window does
1712 LONG y = (rect->top + rect->bottom)/2 - cy/2; // center
1713 UserDrawIconEx(hdc, x, y, pIcon, cx, cy, 0, NULL, DI_NORMAL);
1714 UserDereferenceObject(pIcon);
1715 }
1716 return;
1717 }
1718 goto got_bitmap;
1721 break;
1723 r.right += 1;
1725 break;
1727 r.right += 1;
1729 break;
1732 break;
1735 break;
1737 {
1738 DRAWITEMSTRUCT drawItem;
1739 POINT origorg;
1740 drawItem.CtlType = ODT_MENU;
1741 drawItem.CtlID = 0;
1742 drawItem.itemID = lpitem->wID;
1743 drawItem.itemAction = odaction;
1744 drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
1745 drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
1746 drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
1747 drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
1748 drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
1749 drawItem.itemState |= (!(Menu->fFlags & MNF_UNDERLINE))?ODS_NOACCEL:0;
1750 drawItem.itemState |= (Menu->fFlags & MNF_INACTIVE)?ODS_INACTIVE:0;
1751 drawItem.hwndItem = (HWND)UserHMGetHandle(Menu);
1752 drawItem.hDC = hdc;
1753 drawItem.rcItem = *rect;
1754 drawItem.itemData = lpitem->dwItemData;
1755 /* some applications make this assumption on the DC's origin */
1756 GreSetViewportOrgEx( hdc, lpitem->xItem, lpitem->yItem, &origorg);
1757 RECTL_vOffsetRect(&drawItem.rcItem, -(LONG)lpitem->xItem, -(LONG)lpitem->yItem);
1758 co_IntSendMessage( UserHMGetHandle(WndOwner), WM_DRAWITEM, 0, (LPARAM)&drawItem);
1759 GreSetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
1760 return;
1761 }
1762 break;
1763
1768 MENU_DrawPopupGlyph(hdc, &r, (INT_PTR)hbmToDraw, lpitem->fState & MF_GRAYED, lpitem->fState & MF_HILITE);
1769 return;
1770 }
1771 RECTL_vInflateRect(&r, -1, -1);
1772 if (lpitem->fState & MF_HILITE) flags |= DFCS_PUSHED;
1774 return;
1775 }
1776
1777 if (!bmp || !GreGetObject( bmp, sizeof(bm), &bm )) return;
1778
1779 got_bitmap:
1782 /* handle fontsize > bitmap_height */
1783 top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top;
1784 left=rect->left;
1785 rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY;
1786 if ((lpitem->fState & MF_HILITE) && lpitem->hbmp)
1788 if (MenuBar &&
1789 !flat_menu &&
1790 (lpitem->fState & (MF_HILITE | MF_GRAYED)) == MF_HILITE)
1791 {
1792 ++left;
1793 ++top;
1794 }
1795 NtGdiBitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop , 0, 0);
1797}
1798
1799LONG
1801{
1802 static DWORD units;
1803
1804 if (!units)
1805 {
1806 HDC hdc;
1807 SIZE size;
1808
1809 if ((hdc = UserGetDCEx(NULL, NULL, DCX_CACHE)))
1810 {
1812 if (size.cx) units = MAKELONG( size.cx, size.cy );
1813 UserReleaseDC( 0, hdc, FALSE);
1814 }
1815 }
1816 return units;
1817}
1818
1819
1820/***********************************************************************
1821 * MenuCalcItemSize
1822 *
1823 * Calculate the size of the menu item and store it in lpitem->rect.
1824 */
1825static void FASTCALL MENU_CalcItemSize( HDC hdc, PITEM lpitem, PMENU Menu, PWND pwndOwner,
1826 INT orgX, INT orgY, BOOL menuBar, BOOL textandbmp)
1827{
1828 WCHAR *p;
1829 UINT check_bitmap_width = UserGetSystemMetrics( SM_CXMENUCHECK );
1830 UINT arrow_bitmap_width;
1831 RECT Rect;
1832 INT itemheight = 0;
1833
1834 TRACE("dc=%x owner=%x (%d,%d)\n", hdc, pwndOwner, orgX, orgY);
1835
1836 arrow_bitmap_width = gpsi->oembmi[OBI_MNARROW].cx;
1837
1839
1840 RECTL_vSetRect( &Rect, orgX, orgY, orgX, orgY );
1841
1842 if (lpitem->fType & MF_OWNERDRAW)
1843 {
1845 mis.CtlType = ODT_MENU;
1846 mis.CtlID = 0;
1847 mis.itemID = lpitem->wID;
1848 mis.itemData = lpitem->dwItemData;
1850 mis.itemWidth = 0;
1851 co_IntSendMessage( UserHMGetHandle(pwndOwner), WM_MEASUREITEM, 0, (LPARAM)&mis );
1852 /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average
1853 * width of a menufont character to the width of an owner-drawn menu.
1854 */
1855 Rect.right += mis.itemWidth + 2 * MenuCharSize.cx;
1856 if (menuBar) {
1857 /* under at least win95 you seem to be given a standard
1858 height for the menu and the height value is ignored */
1860 } else
1861 Rect.bottom += mis.itemHeight;
1862 // Or this,
1863 //lpitem->cxBmp = mis.itemWidth;
1864 //lpitem->cyBmp = mis.itemHeight;
1865 TRACE("MF_OWNERDRAW Height %d Width %d\n",mis.itemHeight,mis.itemWidth);
1866 TRACE("MF_OWNERDRAW id=%04lx size=%dx%d cx %d cy %d\n",
1867 lpitem->wID, Rect.right-Rect.left,
1868 Rect.bottom-Rect.top, MenuCharSize.cx, MenuCharSize.cy);
1869
1870 lpitem->xItem = Rect.left;
1871 lpitem->yItem = Rect.top;
1872 lpitem->cxItem = Rect.right;
1873 lpitem->cyItem = Rect.bottom;
1874
1875 return;
1876 }
1877
1878 lpitem->xItem = orgX;
1879 lpitem->yItem = orgY;
1880 lpitem->cxItem = orgX;
1881 lpitem->cyItem = orgY;
1882
1883 if (lpitem->fType & MF_SEPARATOR)
1884 {
1885 lpitem->cyItem += UserGetSystemMetrics( SM_CYMENUSIZE)/2;//SEPARATOR_HEIGHT;
1886 if( !menuBar)
1887 lpitem->cxItem += arrow_bitmap_width + MenuCharSize.cx;
1888 return;
1889 }
1890
1891 lpitem->dxTab = 0;
1892
1893 if (lpitem->hbmp)
1894 {
1895 SIZE size;
1896
1897 if (!menuBar) {
1898 MENU_GetBitmapItemSize(lpitem, &size, pwndOwner );
1899 /* Keep the size of the bitmap in callback mode to be able
1900 * to draw it correctly */
1901 lpitem->cxBmp = size.cx;
1902 lpitem->cyBmp = size.cy;
1903 Menu->cxTextAlign = max(Menu->cxTextAlign, size.cx);
1904 lpitem->cxItem += size.cx + 2;
1905 itemheight = size.cy + 2;
1906
1907 if( !((Menu->fFlags & MNS_STYLE_MASK) & MNS_NOCHECK))
1908 lpitem->cxItem += 2 * check_bitmap_width;
1909 lpitem->cxItem += 4 + MenuCharSize.cx;
1910 lpitem->dxTab = lpitem->cxItem;
1911 lpitem->cxItem += arrow_bitmap_width;
1912 } else /* hbmpItem & MenuBar */ {
1913 MENU_GetBitmapItemSize(lpitem, &size, pwndOwner );
1914 lpitem->cxItem += size.cx;
1915 if( lpitem->Xlpstr) lpitem->cxItem += 2;
1916 itemheight = size.cy;
1917
1918 /* Special case: Minimize button doesn't have a space behind it. */
1919 if (lpitem->hbmp == (HBITMAP)HBMMENU_MBAR_MINIMIZE ||
1921 lpitem->cxItem -= 1;
1922 }
1923 }
1924 else if (!menuBar) {
1925 if( !((Menu->fFlags & MNS_STYLE_MASK) & MNS_NOCHECK))
1926 lpitem->cxItem += check_bitmap_width;
1927 lpitem->cxItem += 4 + MenuCharSize.cx;
1928 lpitem->dxTab = lpitem->cxItem;
1929 lpitem->cxItem += arrow_bitmap_width;
1930 }
1931
1932 /* it must be a text item - unless it's the system menu */
1933 if (!(lpitem->fType & MF_SYSMENU) && lpitem->Xlpstr) {
1934 HFONT hfontOld = NULL;
1935 RECT rc;// = lpitem->Rect;
1936 LONG txtheight, txtwidth;
1937
1938 rc.left = lpitem->xItem;
1939 rc.top = lpitem->yItem;
1940 rc.right = lpitem->cxItem; // Do this for now......
1941 rc.bottom = lpitem->cyItem;
1942
1943 if ( lpitem->fState & MFS_DEFAULT ) {
1944 hfontOld = NtGdiSelectFont( hdc, ghMenuFontBold );
1945 }
1946 if (menuBar) {
1947 txtheight = DrawTextW( hdc, lpitem->Xlpstr, -1, &rc, DT_SINGLELINE|DT_CALCRECT);
1948
1949 lpitem->cxItem += rc.right - rc.left;
1950 itemheight = max( max( itemheight, txtheight), UserGetSystemMetrics( SM_CYMENU) - 1);
1951
1952 lpitem->cxItem += 2 * MenuCharSize.cx;
1953 } else {
1954 if ((p = wcschr( lpitem->Xlpstr, '\t' )) != NULL) {
1955 RECT tmprc = rc;
1956 LONG tmpheight;
1957 int n = (int)( p - lpitem->Xlpstr);
1958 /* Item contains a tab (only meaningful in popup menus) */
1959 /* get text size before the tab */
1960 txtheight = DrawTextW( hdc, lpitem->Xlpstr, n, &rc,
1962 txtwidth = rc.right - rc.left;
1963 p += 1; /* advance past the Tab */
1964 /* get text size after the tab */
1965 tmpheight = DrawTextW( hdc, p, -1, &tmprc,
1967 lpitem->dxTab += txtwidth;
1968 txtheight = max( txtheight, tmpheight);
1969 txtwidth += MenuCharSize.cx + /* space for the tab */
1970 tmprc.right - tmprc.left; /* space for the short cut */
1971 } else {
1972 txtheight = DrawTextW( hdc, lpitem->Xlpstr, -1, &rc,
1974 txtwidth = rc.right - rc.left;
1975 lpitem->dxTab += txtwidth;
1976 }
1977 lpitem->cxItem += 2 + txtwidth;
1978 itemheight = max( itemheight,
1979 max( txtheight + 2, MenuCharSize.cy + 4));
1980 }
1981 if (hfontOld)
1982 {
1983 NtGdiSelectFont (hdc, hfontOld);
1984 }
1985 } else if( menuBar) {
1986 itemheight = max( itemheight, UserGetSystemMetrics(SM_CYMENU)-1);
1987 }
1988 lpitem->cyItem += itemheight;
1989 TRACE("(%ld,%ld)-(%ld,%ld)\n", lpitem->xItem, lpitem->yItem, lpitem->cxItem, lpitem->cyItem);
1990}
1991
1992/***********************************************************************
1993 * MENU_GetMaxPopupHeight
1994 */
1995static UINT
1997{
1998 if (lppop->cyMax)
1999 {
2000 //ERR("MGMaxPH cyMax %d\n",lppop->cyMax);
2001 return lppop->cyMax;
2002 }
2003 //ERR("MGMaxPH SyMax %d\n",UserGetSystemMetrics(SM_CYSCREEN) - UserGetSystemMetrics(SM_CYBORDER));
2005}
2006
2007/***********************************************************************
2008 * MenuPopupMenuCalcSize
2009 *
2010 * Calculate the size of a popup menu.
2011 */
2012static void FASTCALL MENU_PopupMenuCalcSize(PMENU Menu, PWND WndOwner)
2013{
2014 PITEM lpitem;
2015 HDC hdc;
2016 int start, i;
2017 int orgX, orgY, maxX, maxTab, maxTabWidth, maxHeight;
2018 BOOL textandbmp = FALSE;
2019
2020 Menu->cxMenu = Menu->cyMenu = 0;
2021 if (Menu->cItems == 0) return;
2022
2024
2026
2027 start = 0;
2028 maxX = 0;
2029
2030 Menu->cxTextAlign = 0;
2031
2032 while (start < Menu->cItems)
2033 {
2034 lpitem = &Menu->rgItems[start];
2035 orgX = maxX;
2036 if( lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))
2037 orgX += MENU_COL_SPACE;
2038 orgY = 0;
2039
2040 maxTab = maxTabWidth = 0;
2041 /* Parse items until column break or end of menu */
2042 for (i = start; i < Menu->cItems; i++, lpitem++)
2043 {
2044 if (i != start &&
2045 (lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
2046
2047 MENU_CalcItemSize(hdc, lpitem, Menu, WndOwner, orgX, orgY, FALSE, textandbmp);
2048 maxX = max(maxX, lpitem->cxItem);
2049 orgY = lpitem->cyItem;
2050 if (IS_STRING_ITEM(lpitem->fType) && lpitem->dxTab )
2051 {
2052 maxTab = max( maxTab, lpitem->dxTab );
2053 maxTabWidth = max(maxTabWidth, lpitem->cxItem - lpitem->dxTab);
2054 }
2055 if( lpitem->Xlpstr && lpitem->hbmp) textandbmp = TRUE;
2056 }
2057
2058 /* Finish the column (set all items to the largest width found) */
2059 maxX = max( maxX, maxTab + maxTabWidth );
2060 for (lpitem = &Menu->rgItems[start]; start < i; start++, lpitem++)
2061 {
2062 lpitem->cxItem = maxX;
2063 if (IS_STRING_ITEM(lpitem->fType) && lpitem->dxTab)
2064 lpitem->dxTab = maxTab;
2065 }
2066 Menu->cyMenu = max(Menu->cyMenu, orgY);
2067 }
2068
2069 Menu->cxMenu = maxX;
2070 /* if none of the items have both text and bitmap then
2071 * the text and bitmaps are all aligned on the left. If there is at
2072 * least one item with both text and bitmap then bitmaps are
2073 * on the left and texts left aligned with the right hand side
2074 * of the bitmaps */
2075 if( !textandbmp) Menu->cxTextAlign = 0;
2076
2077 /* Adjust popup height if it exceeds maximum */
2078 maxHeight = MENU_GetMaxPopupHeight(Menu);
2079 Menu->iMaxTop = Menu->cyMenu;
2080 if (Menu->cyMenu >= maxHeight)
2081 {
2082 Menu->cyMenu = maxHeight;
2083 Menu->dwArrowsOn = 1;
2084 }
2085 else
2086 {
2087 Menu->dwArrowsOn = 0;
2088 }
2089 UserReleaseDC( 0, hdc, FALSE );
2090}
2091
2092/***********************************************************************
2093 * MENU_MenuBarCalcSize
2094 *
2095 * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap
2096 * height is off by 1 pixel which causes lengthy window relocations when
2097 * active document window is maximized/restored.
2098 *
2099 * Calculate the size of the menu bar.
2100 */
2101static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, PMENU lppop, PWND pwndOwner )
2102{
2103 ITEM *lpitem;
2104 UINT start, i, helpPos;
2105 int orgX, orgY, maxY;
2106
2107 if ((lprect == NULL) || (lppop == NULL)) return;
2108 if (lppop->cItems == 0) return;
2109 //TRACE("lprect %p %s\n", lprect, wine_dbgstr_rect( lprect));
2110 lppop->cxMenu = lprect->right - lprect->left;
2111 lppop->cyMenu = 0;
2112 maxY = lprect->top;
2113 start = 0;
2114 helpPos = ~0U;
2115 lppop->cxTextAlign = 0;
2116 while (start < lppop->cItems)
2117 {
2118 lpitem = &lppop->rgItems[start];
2119 orgX = lprect->left;
2120 orgY = maxY;
2121
2122 /* Parse items until line break or end of menu */
2123 for (i = start; i < lppop->cItems; i++, lpitem++)
2124 {
2125 if ((helpPos == ~0U) && (lpitem->fType & MF_RIGHTJUSTIFY)) helpPos = i;
2126 if ((i != start) &&
2127 (lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
2128
2129 TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY );
2130 //debug_print_menuitem (" item: ", lpitem, "");
2131 //MENU_CalcItemSize( hdc, lpitem, pwndOwner, orgX, orgY, TRUE, lppop );
2132 MENU_CalcItemSize(hdc, lpitem, lppop, pwndOwner, orgX, orgY, TRUE, FALSE);
2133
2134 if (lpitem->cxItem > lprect->right)
2135 {
2136 if (i != start) break;
2137 else lpitem->cxItem = lprect->right;
2138 }
2139 maxY = max( maxY, lpitem->cyItem );
2140 orgX = lpitem->cxItem;
2141 }
2142
2143 /* Finish the line (set all items to the largest height found) */
2144
2145/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the
2146 HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
2147#if 0
2148 while (start < i) lppop->rgItems[start++].cyItem = maxY;
2149#endif
2150 start = i; /* This works! */
2151 }
2152
2153 lprect->bottom = maxY + 1;
2154 lppop->cyMenu = lprect->bottom - lprect->top;
2155
2156 /* Flush right all items between the MF_RIGHTJUSTIFY and */
2157 /* the last item (if several lines, only move the last line) */
2158 if (helpPos == ~0U) return;
2159 lpitem = &lppop->rgItems[lppop->cItems-1];
2160 orgY = lpitem->yItem;
2161 orgX = lprect->right;
2162 for (i = lppop->cItems - 1; i >= helpPos; i--, lpitem--) {
2163 if (lpitem->yItem != orgY) break; /* Other line */
2164 if (lpitem->cxItem >= orgX) break; /* Too far right already */
2165 lpitem->xItem += orgX - lpitem->cxItem;
2166 lpitem->cxItem = orgX;
2167 orgX = lpitem->xItem;
2168 }
2169}
2170
2171/***********************************************************************
2172 * MENU_DrawScrollArrows
2173 *
2174 * Draw scroll arrows.
2175 */
2177{
2178 UINT arrow_bitmap_height;
2179 RECT rect;
2180 UINT Flags = 0;
2181
2182 arrow_bitmap_height = gpsi->oembmi[OBI_DNARROW].cy;
2183
2184 rect.left = 0;
2185 rect.top = 0;
2186 rect.right = lppop->cxMenu;
2187 rect.bottom = arrow_bitmap_height;
2190
2191 rect.top = lppop->cyMenu - arrow_bitmap_height;
2192 rect.bottom = lppop->cyMenu;
2194 if (!(lppop->iTop < lppop->iMaxTop - (MENU_GetMaxPopupHeight(lppop) - 2 * arrow_bitmap_height)))
2197}
2198
2199/***********************************************************************
2200 * MenuDrawMenuItem
2201 *
2202 * Draw a single menu item.
2203 */
2204static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC hdc,
2205 PITEM lpitem, UINT Height, BOOL menuBar, UINT odaction)
2206{
2207 RECT rect;
2208 PWCHAR Text;
2209 BOOL flat_menu = FALSE;
2210 int bkgnd;
2211 UINT arrow_bitmap_width = 0;
2212 //RECT bmprc;
2213
2214 if (!menuBar) {
2215 arrow_bitmap_width = gpsi->oembmi[OBI_MNARROW].cx;
2216 }
2217
2218 if (lpitem->fType & MF_SYSMENU)
2219 {
2220 if (!(Wnd->style & WS_MINIMIZE))
2221 {
2222 NC_GetInsideRect(Wnd, &rect);
2224 }
2225 return;
2226 }
2227
2228 UserSystemParametersInfo (SPI_GETFLATMENU, 0, &flat_menu, 0);
2229 bkgnd = (menuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU;
2230
2231 /* Setup colors */
2232
2233 if (lpitem->fState & MF_HILITE)
2234 {
2235 if(menuBar && !flat_menu) {
2238 } else {
2239 if (lpitem->fState & MF_GRAYED)
2241 else
2244 }
2245 }
2246 else
2247 {
2248 if (lpitem->fState & MF_GRAYED)
2250 else
2252 IntGdiSetBkColor( hdc, IntGetSysColor( bkgnd ) );
2253 }
2254
2255 //TRACE("rect=%s\n", wine_dbgstr_rect( &lpitem->Rect));
2256 //rect = lpitem->Rect;
2257 rect.left = lpitem->xItem;
2258 rect.top = lpitem->yItem;
2259 rect.right = lpitem->cxItem; // Do this for now......
2260 rect.bottom = lpitem->cyItem;
2261
2263
2264 if (lpitem->fType & MF_OWNERDRAW)
2265 {
2266 /*
2267 ** Experimentation under Windows reveals that an owner-drawn
2268 ** menu is given the rectangle which includes the space it requested
2269 ** in its response to WM_MEASUREITEM _plus_ width for a checkmark
2270 ** and a popup-menu arrow. This is the value of lpitem->rect.
2271 ** Windows will leave all drawing to the application except for
2272 ** the popup-menu arrow. Windows always draws that itself, after
2273 ** the menu owner has finished drawing.
2274 */
2275 DRAWITEMSTRUCT dis;
2276 COLORREF old_bk, old_text;
2277
2278 dis.CtlType = ODT_MENU;
2279 dis.CtlID = 0;
2280 dis.itemID = lpitem->wID;
2281 dis.itemData = (DWORD)lpitem->dwItemData;
2282 dis.itemState = 0;
2283 if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED;
2284 if (lpitem->fState & MF_DEFAULT) dis.itemState |= ODS_DEFAULT;
2285 if (lpitem->fState & MF_DISABLED) dis.itemState |= ODS_DISABLED;
2286 if (lpitem->fState & MF_GRAYED) dis.itemState |= ODS_GRAYED | ODS_DISABLED;
2287 if (lpitem->fState & MF_HILITE) dis.itemState |= ODS_SELECTED;
2288 if (!(Menu->fFlags & MNF_UNDERLINE)) dis.itemState |= ODS_NOACCEL;
2289 if (Menu->fFlags & MNF_INACTIVE) dis.itemState |= ODS_INACTIVE;
2290 dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
2291 dis.hwndItem = (HWND) UserHMGetHandle(Menu);
2292 dis.hDC = hdc;
2293 dis.rcItem = rect;
2294 TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
2295 "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", Wnd,
2296 dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
2297 dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
2298 dis.rcItem.bottom);
2299 TRACE("Ownerdraw: Width %d Height %d\n", dis.rcItem.right-dis.rcItem.left, dis.rcItem.bottom-dis.rcItem.top);
2300 old_bk = GreGetBkColor(hdc);
2301 old_text = GreGetTextColor(hdc);
2302 co_IntSendMessage(UserHMGetHandle(WndOwner), WM_DRAWITEM, 0, (LPARAM) &dis);
2303 IntGdiSetBkColor(hdc, old_bk);
2304 IntGdiSetTextColor(hdc, old_text);
2305 /* Draw the popup-menu arrow */
2306 if (!menuBar && lpitem->spSubMenu)
2307 {
2308 RECT rectTemp;
2309 RtlCopyMemory(&rectTemp, &rect, sizeof(RECT));
2310 rectTemp.left = rectTemp.right - UserGetSystemMetrics(SM_CXMENUCHECK);
2312 }
2313 return;
2314 }
2315
2316 if (menuBar && (lpitem->fType & MF_SEPARATOR)) return;
2317
2318 if (lpitem->fState & MF_HILITE)
2319 {
2320 if (flat_menu)
2321 {
2322 RECTL_vInflateRect (&rect, -1, -1);
2323 FillRect(hdc, &rect, IntGetSysColorBrush(COLOR_MENUHILIGHT));
2324 RECTL_vInflateRect (&rect, 1, 1);
2326 }
2327 else
2328 {
2329 if (menuBar)
2330 {
2333 }
2334 else
2335 {
2337 }
2338 }
2339 }
2340 else
2341 FillRect( hdc, &rect, IntGetSysColorBrush(bkgnd) );
2342
2344
2345 /* vertical separator */
2346 if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
2347 {
2348 HPEN oldPen;
2349 RECT rc = rect;
2350
2351 rc.left -= 3;//MENU_COL_SPACE / 2 + 1; == 3!!
2352 rc.top = 3;
2353 rc.bottom = Height - 3;
2354 if (flat_menu)
2355 {
2356 oldPen = NtGdiSelectPen( hdc, NtGdiGetStockObject(DC_PEN) );
2358 GreMoveTo( hdc, rc.left, rc.top, NULL );
2359 NtGdiLineTo( hdc, rc.left, rc.bottom );
2360 NtGdiSelectPen( hdc, oldPen );
2361 }
2362 else
2364 }
2365
2366 /* horizontal separator */
2367 if (lpitem->fType & MF_SEPARATOR)
2368 {
2369 HPEN oldPen;
2370 RECT rc = rect;
2371
2372 rc.left++;
2373 rc.right--;
2374 rc.top = (rc.top + rc.bottom) / 2 - 1;
2375 if (flat_menu)
2376 {
2377 oldPen = NtGdiSelectPen( hdc, NtGdiGetStockObject(DC_PEN) );
2379 GreMoveTo( hdc, rc.left, rc.top, NULL );
2380 NtGdiLineTo( hdc, rc.right, rc.top );
2381 NtGdiSelectPen( hdc, oldPen );
2382 }
2383 else
2384 DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
2385 return;
2386 }
2387#if 0
2388 /* helper lines for debugging */
2389 /* This is a very good test tool when hacking menus! (JT) 07/16/2006 */
2393 GreMoveTo(hdc, rect.left, (rect.top + rect.bottom) / 2, NULL);
2394 NtGdiLineTo(hdc, rect.right, (rect.top + rect.bottom) / 2);
2395#endif
2396#if 0 // breaks mdi menu bar icons.
2397 if (lpitem->hbmp) {
2398 /* calculate the bitmap rectangle in coordinates relative
2399 * to the item rectangle */
2400 if( menuBar) {
2401 if( lpitem->hbmp == HBMMENU_CALLBACK)
2402 bmprc.left = 3;
2403 else
2404 bmprc.left = lpitem->Xlpstr ? MenuCharSize.cx : 0;
2405 }
2406 else if ((Menu->fFlags & MNS_STYLE_MASK) & MNS_NOCHECK)
2407 bmprc.left = 4;
2408 else if ((Menu->fFlags & MNS_STYLE_MASK) & MNS_CHECKORBMP)
2409 bmprc.left = 2;
2410 else
2411 bmprc.left = 4 + UserGetSystemMetrics(SM_CXMENUCHECK);
2412
2413 bmprc.right = bmprc.left + lpitem->cxBmp;
2414
2415 if( menuBar && !(lpitem->hbmp == HBMMENU_CALLBACK))
2416 bmprc.top = 0;
2417 else
2418 bmprc.top = (rect.bottom - rect.top - lpitem->cyBmp) / 2;
2419
2420 bmprc.bottom = bmprc.top + lpitem->cyBmp;
2421 }
2422#endif
2423 if (!menuBar)
2424 {
2425 HBITMAP bm;
2426 INT y = rect.top + rect.bottom;
2427 RECT rc = rect;
2428 BOOL checked = FALSE;
2429 UINT check_bitmap_width = UserGetSystemMetrics( SM_CXMENUCHECK );
2430 UINT check_bitmap_height = UserGetSystemMetrics( SM_CYMENUCHECK );
2431 /* Draw the check mark
2432 *
2433 * FIXME:
2434 * Custom checkmark bitmaps are monochrome but not always 1bpp.
2435 */
2436 if( !((Menu->fFlags & MNS_STYLE_MASK) & MNS_NOCHECK)) {
2437 bm = (lpitem->fState & MF_CHECKED) ? lpitem->hbmpChecked :
2438 lpitem->hbmpUnchecked;
2439 if (bm) /* we have a custom bitmap */
2440 {
2442
2444 NtGdiBitBlt( hdc, rc.left, (y - check_bitmap_height) / 2,
2445 check_bitmap_width, check_bitmap_height,
2446 hdcMem, 0, 0, SRCCOPY, 0,0);
2448 checked = TRUE;
2449 }
2450 else if (lpitem->fState & MF_CHECKED) /* standard bitmaps */
2451 {
2452 RECT r;
2453 r = rect;
2454 r.right = r.left + check_bitmap_width;
2456 (lpitem->fType & MFT_RADIOCHECK) ?
2458 checked = TRUE;
2459 }
2460 }
2461 if ( lpitem->hbmp )//&& !( checked && ((Menu->fFlags & MNS_STYLE_MASK) & MNS_CHECKORBMP)))
2462 {
2463 RECT bmpRect = rect;
2464 if (!((Menu->fFlags & MNS_STYLE_MASK) & MNS_CHECKORBMP) && !((Menu->fFlags & MNS_STYLE_MASK) & MNS_NOCHECK))
2465 bmpRect.left += check_bitmap_width + 2;
2466 if (!(checked && ((Menu->fFlags & MNS_STYLE_MASK) & MNS_CHECKORBMP)))
2467 {
2468 bmpRect.right = bmpRect.left + lpitem->cxBmp;
2469 MENU_DrawBitmapItem(hdc, lpitem, &bmpRect, Menu, WndOwner, odaction, menuBar);
2470 }
2471 }
2472 /* Draw the popup-menu arrow */
2473 if (lpitem->spSubMenu)
2474 {
2475 RECT rectTemp;
2476 RtlCopyMemory(&rectTemp, &rect, sizeof(RECT));
2477 rectTemp.left = rectTemp.right - check_bitmap_width;
2479 }
2480 rect.left += 4;
2481 if( !((Menu->fFlags & MNS_STYLE_MASK) & MNS_NOCHECK))
2482 rect.left += check_bitmap_width;
2483 rect.right -= arrow_bitmap_width;
2484 }
2485 else if( lpitem->hbmp)
2486 { /* Draw the bitmap */
2487 MENU_DrawBitmapItem(hdc, lpitem, &rect/*bmprc*/, Menu, WndOwner, odaction, menuBar);
2488 }
2489
2490 /* process text if present */
2491 if (lpitem->Xlpstr)
2492 {
2493 int i = 0;
2494 HFONT hfontOld = 0;
2495
2496 UINT uFormat = menuBar ?
2499
2500 if (((Menu->fFlags & MNS_STYLE_MASK) & MNS_CHECKORBMP))
2501 rect.left += max(0, (int)(Menu->cxTextAlign - UserGetSystemMetrics(SM_CXMENUCHECK)));
2502 else
2503 rect.left += Menu->cxTextAlign;
2504
2505 if ( lpitem->fState & MFS_DEFAULT )
2506 {
2507 hfontOld = NtGdiSelectFont(hdc, ghMenuFontBold);
2508 }
2509
2510 if (menuBar) {
2511 if( lpitem->hbmp)
2512 rect.left += lpitem->cxBmp;
2513 if( !(lpitem->hbmp == HBMMENU_CALLBACK))
2514 rect.left += MenuCharSize.cx;
2515 rect.right -= MenuCharSize.cx;
2516 }
2517
2518 Text = lpitem->Xlpstr;
2519 if(Text)
2520 {
2521 for (i = 0; Text[i]; i++)
2522 if (Text[i] == L'\t' || Text[i] == L'\b')
2523 break;
2524 }
2525
2526 if (menuBar &&
2527 !flat_menu &&
2528 (lpitem->fState & (MF_HILITE | MF_GRAYED)) == MF_HILITE)
2529 {
2530 RECTL_vOffsetRect(&rect, +1, +1);
2531 }
2532
2533 if (!menuBar)
2534 --rect.bottom;
2535
2536 if(lpitem->fState & MF_GRAYED)
2537 {
2538 if (!(lpitem->fState & MF_HILITE) )
2539 {
2540 ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
2542 DrawTextW( hdc, Text, i, &rect, uFormat );
2543 --rect.left; --rect.top; --rect.right; --rect.bottom;
2544 }
2546 }
2547 DrawTextW( hdc, Text, i, &rect, uFormat);
2548
2549 /* paint the shortcut text */
2550 if (!menuBar && L'\0' != Text[i]) /* There's a tab or flush-right char */
2551 {
2552 if (L'\t' == Text[i])
2553 {
2554 rect.left = lpitem->dxTab;
2555 uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
2556 }
2557 else
2558 {
2559 rect.right = lpitem->dxTab;
2560 uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
2561 }
2562
2563 if (lpitem->fState & MF_GRAYED)
2564 {
2565 if (!(lpitem->fState & MF_HILITE) )
2566 {
2567 ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
2569 DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat);
2570 --rect.left; --rect.top; --rect.right; --rect.bottom;
2571 }
2573 }
2574 DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
2575 }
2576
2577 if (!menuBar)
2578 ++rect.bottom;
2579
2580 if (menuBar &&
2581 !flat_menu &&
2582 (lpitem->fState & (MF_HILITE | MF_GRAYED)) == MF_HILITE)
2583 {
2584 RECTL_vOffsetRect(&rect, -1, -1);
2585 }
2586
2587 if (hfontOld)
2588 {
2589 NtGdiSelectFont (hdc, hfontOld);
2590 }
2591 }
2592}
2593
2594/***********************************************************************
2595 * MenuDrawPopupMenu
2596 *
2597 * Paint a popup menu.
2598 */
2600{
2601 HBRUSH hPrevBrush = 0, brush = IntGetSysColorBrush(COLOR_MENU);
2602 RECT rect;
2603
2604 TRACE("DPM wnd=%p dc=%p menu=%p\n", wnd, hdc, menu);
2605
2606 IntGetClientRect( wnd, &rect );
2607
2608 if (menu && menu->hbrBack) brush = menu->hbrBack;
2609 if((hPrevBrush = NtGdiSelectBrush( hdc, brush ))
2611 {
2612 HPEN hPrevPen;
2613
2614 /* FIXME: Maybe we don't have to fill the background manually */
2615 FillRect(hdc, &rect, brush);
2616
2618 if ( hPrevPen )
2619 {
2620 TRACE("hmenu %p Style %08x\n", UserHMGetHandle(menu), (menu->fFlags & MNS_STYLE_MASK));
2621 /* draw menu items */
2622 if (menu && menu->cItems)
2623 {
2624 ITEM *item;
2625 UINT u;
2626
2627 item = menu->rgItems;
2628 for( u = menu->cItems; u > 0; u--, item++)
2629 {
2630 MENU_DrawMenuItem(wnd, menu, menu->spwndNotify, hdc, item,
2631 menu->cyMenu, FALSE, ODA_DRAWENTIRE);
2632 }
2633 /* draw scroll arrows */
2634 if (menu->dwArrowsOn)
2635 {
2637 }
2638 }
2639 }
2640 else
2641 {
2642 NtGdiSelectBrush( hdc, hPrevBrush );
2643 }
2644 }
2645}
2646
2647/**********************************************************************
2648 * MENU_IsMenuActive
2649 */
2651{
2653}
2654
2655/**********************************************************************
2656 * MENU_EndMenu
2657 *
2658 * Calls EndMenu() if the hwnd parameter belongs to the menu owner
2659 *
2660 * Does the (menu stuff) of the default window handling of WM_CANCELMODE
2661 */
2662void MENU_EndMenu( PWND pwnd )
2663{
2664 PMENU menu = NULL;
2666 if ( menu && ( UserHMGetHandle(pwnd) == menu->hWnd || pwnd == menu->spwndNotify ) )
2667 {
2669 {
2671
2672 if (fInEndMenu)
2673 {
2674 ERR("Already in End loop\n");
2675 return;
2676 }
2677
2678 fInEndMenu = TRUE;
2680 }
2681 }
2682}
2683
2686{
2687 UINT i;
2688 HFONT FontOld = NULL;
2689 BOOL flat_menu = FALSE;
2690
2691 UserSystemParametersInfo(SPI_GETFLATMENU, 0, &flat_menu, 0);
2692
2693 if (!pMenu)
2694 {
2695 pMenu = UserGetMenuObject(UlongToHandle(pWnd->IDMenu));
2696 }
2697
2698 if (!Font)
2699 {
2700 Font = ghMenuFont;
2701 }
2702
2703 if (Rect == NULL || !pMenu)
2704 {
2706 }
2707
2708 TRACE("(%x, %x, %p, %x, %x)\n", pWnd, hDC, Rect, pMenu, Font);
2709
2710 FontOld = NtGdiSelectFont(hDC, Font);
2711
2712 if (pMenu->cyMenu == 0)
2713 {
2714 MENU_MenuBarCalcSize(hDC, Rect, pMenu, pWnd);
2715 }
2716
2717 Rect->bottom = Rect->top + pMenu->cyMenu;
2718
2719 FillRect(hDC, Rect, IntGetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU));
2720
2723 GreMoveTo(hDC, Rect->left, Rect->bottom - 1, NULL);
2724 NtGdiLineTo(hDC, Rect->right, Rect->bottom - 1);
2725
2726 if (pMenu->cItems == 0)
2727 {
2728 NtGdiSelectFont(hDC, FontOld);
2730 }
2731
2732 for (i = 0; i < pMenu->cItems; i++)
2733 {
2734 MENU_DrawMenuItem(pWnd, pMenu, pWnd, hDC, &pMenu->rgItems[i], pMenu->cyMenu, TRUE, ODA_DRAWENTIRE);
2735 }
2736
2737 NtGdiSelectFont(hDC, FontOld);
2738
2739 return pMenu->cyMenu;
2740}
2741
2742UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, PWND pWnd, BOOL suppress_draw )
2743{
2744 HFONT hfontOld = 0;
2746
2747 if (lppop == NULL)
2748 {
2749 // No menu. Do not reserve any space
2750 return 0;
2751 }
2752
2753 if (lprect == NULL)
2754 {
2756 }
2757
2758 if (suppress_draw)
2759 {
2760 hfontOld = NtGdiSelectFont(hDC, ghMenuFont);
2761
2762 MENU_MenuBarCalcSize(hDC, lprect, lppop, pWnd);
2763
2764 lprect->bottom = lprect->top + lppop->cyMenu;
2765
2766 if (hfontOld) NtGdiSelectFont( hDC, hfontOld);
2767
2768 return lppop->cyMenu;
2769 }
2770 else
2771 {
2772 return IntDrawMenuBarTemp(pWnd, hDC, lprect, lppop, NULL);
2773 }
2774}
2775
2776/***********************************************************************
2777 * MENU_InitPopup
2778 *
2779 * Popup menu initialization before WM_ENTERMENULOOP.
2780 */
2781static BOOL MENU_InitPopup( PWND pWndOwner, PMENU menu, UINT flags )
2782{
2783 PWND pWndCreated;
2784 PPOPUPMENU pPopupMenu;
2785 CREATESTRUCTW Cs;
2786 LARGE_STRING WindowName;
2787 UNICODE_STRING ClassName;
2789
2790 TRACE("owner=%p hmenu=%p\n", pWndOwner, menu);
2791
2792 menu->spwndNotify = pWndOwner;
2793
2794 if (flags & TPM_LAYOUTRTL || pWndOwner->ExStyle & WS_EX_LAYOUTRTL)
2795 ex_style |= WS_EX_LAYOUTRTL;
2796
2797 ClassName.Buffer = WC_MENU;
2798 ClassName.Length = 0;
2799
2800 RtlZeroMemory(&WindowName, sizeof(WindowName));
2801 RtlZeroMemory(&Cs, sizeof(Cs));
2803 Cs.dwExStyle = ex_style;
2804 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2805 Cs.lpszName = (LPCWSTR) &WindowName;
2806 Cs.lpszClass = (LPCWSTR) &ClassName;
2808 Cs.hwndParent = UserHMGetHandle(pWndOwner);
2809
2810 /* NOTE: In Windows, top menu popup is not owned. */
2811 pWndCreated = co_UserCreateWindowEx( &Cs, &ClassName, &WindowName, NULL, WINVER );
2812
2813 if( !pWndCreated ) return FALSE;
2814
2815 //
2816 // Setup pop up menu structure.
2817 //
2818 menu->hWnd = UserHMGetHandle(pWndCreated);
2819
2820 pPopupMenu = ((PMENUWND)pWndCreated)->ppopupmenu;
2821
2822 pPopupMenu->spwndActivePopup = pWndCreated; // top_popup = MenuInfo.Wnd or menu->hWnd
2823 pPopupMenu->spwndNotify = pWndOwner; // Same as MenuInfo.spwndNotify(which could be wrong) or menu->hwndOwner
2824 //pPopupMenu->spmenu = menu; Should be set up already from WM_CREATE!
2825
2826 pPopupMenu->fIsTrackPopup = !!(flags & TPM_POPUPMENU);
2827 pPopupMenu->fIsSysMenu = !!(flags & TPM_SYSTEM_MENU);
2828 pPopupMenu->fNoNotify = !!(flags & TPM_NONOTIFY);
2829 pPopupMenu->fRightButton = !!(flags & TPM_RIGHTBUTTON);
2830 pPopupMenu->fSynchronous = !!(flags & TPM_RETURNCMD);
2831
2832 if (pPopupMenu->fRightButton)
2833 pPopupMenu->fFirstClick = !!(UserGetKeyState(VK_RBUTTON) & 0x8000);
2834 else
2835 pPopupMenu->fFirstClick = !!(UserGetKeyState(VK_LBUTTON) & 0x8000);
2836
2837 if (gpsi->aiSysMet[SM_MENUDROPALIGNMENT] ||
2838 menu->fFlags & MNF_RTOL)
2839 {
2840 pPopupMenu->fDroppedLeft = TRUE;
2841 }
2842 return TRUE;
2843}
2844
2845
2846#define SHOW_DEBUGRECT 0
2847
2848#if SHOW_DEBUGRECT
2849static void DebugRect(const RECT* rectl, COLORREF color)
2850{
2851 HBRUSH brush;
2852 RECT rr;
2853 HDC hdc;
2854
2855 if (!rectl)
2856 return;
2857
2859
2861
2862 rr = *rectl;
2863 RECTL_vInflateRect(&rr, 1, 1);
2864 FrameRect(hdc, rectl, brush);
2865 FrameRect(hdc, &rr, brush);
2866
2867 NtGdiDeleteObjectApp(brush);
2869}
2870
2871static void DebugPoint(INT x, INT y, COLORREF color)
2872{
2873 RECT r1 = {x-10, y, x+10, y};
2874 RECT r2 = {x, y-10, x, y+10};
2875 DebugRect(&r1, color);
2876 DebugRect(&r2, color);
2877}
2878#endif
2879
2881{
2882 RECT other = {x, y, x + width, y + height};
2883 RECT dum;
2884
2885 return RECTL_bIntersectRect(&dum, pRect, &other);
2886}
2887
2888static BOOL MENU_MoveRect(UINT flags, INT* x, INT* y, INT width, INT height, const RECT* pExclude, PMONITOR monitor)
2889{
2890 /* Figure out if we should move vertical or horizontal */
2891 if (flags & TPM_VERTICAL)
2892 {
2893 /* Move in the vertical direction: TPM_BOTTOMALIGN means drop it above, otherways drop it below */
2894 if (flags & TPM_BOTTOMALIGN)
2895 {
2896 if (pExclude->top - height >= monitor->rcMonitor.top)
2897 {
2898 *y = pExclude->top - height;
2899 return TRUE;
2900 }
2901 }
2902 else
2903 {
2904 if (pExclude->bottom + height < monitor->rcMonitor.bottom)
2905 {
2906 *y = pExclude->bottom;
2907 return TRUE;
2908 }
2909 }
2910 }
2911 else
2912 {
2913 /* Move in the horizontal direction: TPM_RIGHTALIGN means drop it to the left, otherways go right */
2914 if (flags & TPM_RIGHTALIGN)
2915 {
2916 if (pExclude->left - width >= monitor->rcMonitor.left)
2917 {
2918 *x = pExclude->left - width;
2919 return TRUE;
2920 }
2921 }
2922 else
2923 {
2924 if (pExclude->right + width < monitor->rcMonitor.right)
2925 {
2926 *x = pExclude->right;
2927 return TRUE;
2928 }
2929 }
2930 }
2931 return FALSE;
2932}
2933
2934/***********************************************************************
2935 * MenuShowPopup
2936 *
2937 * Display a popup menu.
2938 */
2939static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT flags,
2940 INT x, INT y, const RECT* pExclude)
2941{
2942 INT width, height;
2943 POINT ptx;
2944 PMONITOR monitor;
2945 PWND pWnd;
2947 BOOL bIsPopup = (flags & TPM_POPUPMENU) != 0;
2948
2949 TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x\n",
2950 pwndOwner, menu, id, x, y);
2951
2952 if (menu->iItem != NO_SELECTED_ITEM)
2953 {
2954 menu->rgItems[menu->iItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
2955 menu->iItem = NO_SELECTED_ITEM;
2956 }
2957
2958#if SHOW_DEBUGRECT
2959 if (pExclude)
2960 DebugRect(pExclude, RGB(255, 0, 0));
2961#endif
2962
2963 menu->dwArrowsOn = 0;
2964 MENU_PopupMenuCalcSize(menu, pwndOwner);
2965
2966 /* adjust popup menu pos so that it fits within the desktop */
2967
2970
2971 if (flags & TPM_LAYOUTRTL)
2973
2974 if (flags & TPM_RIGHTALIGN)
2975 x -= width;
2976 if (flags & TPM_CENTERALIGN)
2977 x -= width / 2;
2978
2979 if (flags & TPM_BOTTOMALIGN)
2980 y -= height;
2981 if (flags & TPM_VCENTERALIGN)
2982 y -= height / 2;
2983
2984 /* FIXME: should use item rect */
2985 ptx.x = x;
2986 ptx.y = y;
2987#if SHOW_DEBUGRECT
2988 DebugPoint(x, y, RGB(0, 0, 255));
2989#endif
2990 monitor = UserMonitorFromPoint( ptx, MONITOR_DEFAULTTONEAREST );
2991
2992 /* We are off the right side of the screen */
2993 if (x + width > monitor->rcMonitor.right)
2994 {
2995 if ((x - width) < monitor->rcMonitor.left || x >= monitor->rcMonitor.right)
2996 x = monitor->rcMonitor.right - width;
2997 else
2998 x -= width;
2999 }
3000
3001 /* We are off the left side of the screen */
3002 if (x < monitor->rcMonitor.left)
3003 {
3004 /* Re-orient the menu around the x-axis */
3005 x += width;
3006
3007 if (x < monitor->rcMonitor.left || x >= monitor->rcMonitor.right || bIsPopup)
3008 x = monitor->rcMonitor.left;
3009 }
3010
3011 /* Same here, but then the top */
3012 if (y < monitor->rcMonitor.top)
3013 {
3014 y += height;
3015
3016 if (y < monitor->rcMonitor.top || y >= monitor->rcMonitor.bottom || bIsPopup)
3017 y = monitor->rcMonitor.top;
3018 }
3019
3020 /* And the bottom */
3021 if (y + height > monitor->rcMonitor.bottom)
3022 {
3023 if ((y - height) < monitor->rcMonitor.top || y >= monitor->rcMonitor.bottom)
3024 y = monitor->rcMonitor.bottom - height;
3025 else
3026 y -= height;
3027 }
3028
3029 if (pExclude)
3030 {
3031 RECT Cleaned;
3032
3033 if (RECTL_bIntersectRect(&Cleaned, pExclude, &monitor->rcMonitor) &&
3034 RECTL_Intersect(&Cleaned, x, y, width, height))
3035 {
3036 UINT flag_mods[] = {
3037 0, /* First try the 'normal' way */
3038 TPM_BOTTOMALIGN | TPM_RIGHTALIGN, /* Then try the opposite side */
3039 TPM_VERTICAL, /* Then swap horizontal / vertical */
3040 TPM_BOTTOMALIGN | TPM_RIGHTALIGN | TPM_VERTICAL, /* Then the other side again (still swapped hor/ver) */
3041 };
3042
3043 UINT n;
3044 for (n = 0; n < RTL_NUMBER_OF(flag_mods); ++n)
3045 {
3046 INT tx = x;
3047 INT ty = y;
3048
3049 /* Try to move a bit around */
3050 if (MENU_MoveRect(flags ^ flag_mods[n], &tx, &ty, width, height, &Cleaned, monitor) &&
3051 !RECTL_Intersect(&Cleaned, tx, ty, width, height))
3052 {
3053 x = tx;
3054 y = ty;
3055 break;
3056 }
3057 }
3058 /* If none worked, we go with the original x/y */
3059 }
3060 }
3061
3062#if SHOW_DEBUGRECT
3063 {
3064 RECT rr = {x, y, x + width, y + height};
3065 DebugRect(&rr, RGB(0, 255, 0));
3066 }
3067#endif
3068
3069 pWnd = ValidateHwndNoErr( menu->hWnd );
3070
3071 if (!pWnd)
3072 {
3073 ERR("menu->hWnd bad hwnd %p\n",menu->hWnd);
3074 return FALSE;
3075 }
3076
3077 if (!top_popup) {
3078 top_popup = menu->hWnd;
3080 }
3081
3082 /* Display the window */
3083 UserRefObjectCo(pWnd, &Ref);
3085
3087
3088 IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
3089 UserDerefObjectCo(pWnd);
3090
3091 return TRUE;
3092}
3093
3094/***********************************************************************
3095 * MENU_EnsureMenuItemVisible
3096 */
3098{
3100 if (lppop->dwArrowsOn)
3101 {
3102 ITEM *item = &lppop->rgItems[wIndex];
3103 UINT nMaxHeight = MENU_GetMaxPopupHeight(lppop);
3104 UINT nOldPos = lppop->iTop;
3105 RECT rc;
3106 UINT arrow_bitmap_height;
3107 PWND pWnd = ValidateHwndNoErr(lppop->hWnd);
3108
3109 IntGetClientRect(pWnd, &rc);
3110
3111 arrow_bitmap_height = gpsi->oembmi[OBI_DNARROW].cy;
3112
3113 rc.top += arrow_bitmap_height;
3114 rc.bottom -= arrow_bitmap_height;
3115
3116 nMaxHeight -= UserGetSystemMetrics(SM_CYBORDER) + 2 * arrow_bitmap_height;
3117 UserRefObjectCo(pWnd, &Ref);
3118 if (item->cyItem > lppop->iTop + nMaxHeight)
3119 {
3120 lppop->iTop = item->cyItem - nMaxHeight;
3121 IntScrollWindow(pWnd, 0, nOldPos - lppop->iTop, &rc, &rc);
3122 MENU_DrawScrollArrows(lppop, hdc);
3123 //ERR("Scroll Down iTop %d iMaxTop %d nMaxHeight %d\n",lppop->iTop,lppop->iMaxTop,nMaxHeight);
3124 }
3125 else if (item->yItem < lppop->iTop)
3126 {
3127 lppop->iTop = item->yItem;
3128 IntScrollWindow(pWnd, 0, nOldPos - lppop->iTop, &rc, &rc);
3129 MENU_DrawScrollArrows(lppop, hdc);
3130 //ERR("Scroll Up iTop %d iMaxTop %d nMaxHeight %d\n",lppop->iTop,lppop->iMaxTop,nMaxHeight);
3131 }
3132 UserDerefObjectCo(pWnd);
3133 }
3134}
3135
3136/***********************************************************************
3137 * MenuSelectItem
3138 */
3139static void FASTCALL MENU_SelectItem(PWND pwndOwner, PMENU menu, UINT wIndex,
3140 BOOL sendMenuSelect, PMENU topmenu)
3141{
3142 HDC hdc;
3143 PWND pWnd;
3144
3145 TRACE("M_SI: owner=%p menu=%p index=0x%04x select=0x%04x\n", pwndOwner, menu, wIndex, sendMenuSelect);
3146
3147 if (!menu || !menu->cItems) return;
3148
3149 pWnd = ValidateHwndNoErr(menu->hWnd);
3150
3151 if (!pWnd) return;
3152
3153 if (menu->iItem == wIndex) return;
3154
3155 if (menu->fFlags & MNF_POPUP)
3156 hdc = UserGetDCEx(pWnd, 0, DCX_USESTYLE);
3157 else
3158 hdc = UserGetDCEx(pWnd, 0, DCX_CACHE | DCX_WINDOW);
3159
3160 if (!top_popup) {
3161 top_popup = menu->hWnd; //pPopupMenu->spwndActivePopup or
3162 //pPopupMenu->fIsTrackPopup set pPopupMenu->spwndPopupMenu;
3163 top_popup_hmenu = UserHMGetHandle(menu); //pPopupMenu->spmenu
3164 }
3165
3167
3168 /* Clear previous highlighted item */
3169 if (menu->iItem != NO_SELECTED_ITEM)
3170 {
3171 menu->rgItems[menu->iItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
3172 MENU_DrawMenuItem(pWnd, menu, pwndOwner, hdc, &menu->rgItems[menu->iItem],
3173 menu->cyMenu, !(menu->fFlags & MNF_POPUP),
3174 ODA_SELECT);
3175 }
3176
3177 /* Highlight new item (if any) */
3178 menu->iItem = wIndex;
3179 if (menu->iItem != NO_SELECTED_ITEM)
3180 {
3181 if (!(menu->rgItems[wIndex].fType & MF_SEPARATOR))
3182 {
3183 menu->rgItems[wIndex].fState |= MF_HILITE;
3184 MENU_EnsureMenuItemVisible(menu, wIndex, hdc);
3185 MENU_DrawMenuItem(pWnd, menu, pwndOwner, hdc,
3186 &menu->rgItems[wIndex], menu->cyMenu, !(menu->fFlags & MNF_POPUP), ODA_SELECT);
3187 }
3188 if (sendMenuSelect)
3189 {
3190 ITEM *ip = &menu->rgItems[menu->iItem];
3191 WPARAM wParam = MAKEWPARAM( ip->spSubMenu ? wIndex : ip->wID,
3192 ip->fType | ip->fState |
3193 (ip->spSubMenu ? MF_POPUP : 0) |
3194 (menu->fFlags & MNF_SYSMENU ? MF_SYSMENU : 0 ) );
3195
3197 }
3198 }
3199 else if (sendMenuSelect)
3200 {
3201 if (topmenu)
3202 {
3203 int pos;
3204 pos = MENU_FindSubMenu(&topmenu, menu);
3205 if (pos != NO_SELECTED_ITEM)
3206 {
3207 ITEM *ip = &topmenu->rgItems[pos];
3208 WPARAM wParam = MAKEWPARAM( Pos, ip->fType | ip->fState |
3209 (ip->spSubMenu ? MF_POPUP : 0) |
3210 (topmenu->fFlags & MNF_SYSMENU ? MF_SYSMENU : 0 ) );
3211
3213 }
3214 }
3215 }
3216 UserReleaseDC(pWnd, hdc, FALSE);
3217}
3218
3219/***********************************************************************
3220 * MenuMoveSelection
3221 *
3222 * Moves currently selected item according to the Offset parameter.
3223 * If there is no selection then it should select the last item if
3224 * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
3225 */
3226static void FASTCALL MENU_MoveSelection(PWND pwndOwner, PMENU menu, INT offset)
3227{
3228 INT i;
3229
3230 TRACE("pwnd=%x menu=%x off=0x%04x\n", pwndOwner, menu, offset);
3231
3232 if ((!menu) || (!menu->rgItems)) return;
3233
3234 if ( menu->iItem != NO_SELECTED_ITEM )
3235 {
3236 if ( menu->cItems == 1 )
3237 return;
3238 else
3239 for (i = menu->iItem + offset ; i >= 0 && i < menu->cItems
3240 ; i += offset)
3241 if (!(menu->rgItems[i].fType & MF_SEPARATOR))
3242 {
3243 MENU_SelectItem( pwndOwner, menu, i, TRUE, 0 );
3244 return;
3245 }
3246 }
3247
3248 for ( i = (offset > 0) ? 0 : menu->cItems - 1;
3249 i >= 0 && i < menu->cItems ; i += offset)
3250 if (!(menu->rgItems[i].fType & MF_SEPARATOR))
3251 {
3252 MENU_SelectItem( pwndOwner, menu, i, TRUE, 0 );
3253 return;
3254 }
3255}
3256
3257/***********************************************************************
3258 * MenuHideSubPopups
3259 *
3260 * Hide the sub-popup menus of this menu.
3261 */
3262static void FASTCALL MENU_HideSubPopups(PWND pWndOwner, PMENU Menu,
3263 BOOL SendMenuSelect, UINT wFlags)
3264{
3265 TRACE("owner=%x menu=%x 0x%04x\n", pWndOwner, Menu, SendMenuSelect);
3266
3267 if ( Menu && top_popup )
3268 {
3269 PITEM Item;
3270
3271 if (Menu->iItem != NO_SELECTED_ITEM)
3272 {
3273 Item = &Menu->rgItems[Menu->iItem];
3274 if (!(Item->spSubMenu) ||
3275 !(Item->fState & MF_MOUSESELECT)) return;
3276 Item->fState &= ~MF_MOUSESELECT;
3277 }
3278 else
3279 return;
3280
3281 if (Item->spSubMenu)
3282 {
3283 PWND pWnd;
3284 if (!VerifyMenu(Item->spSubMenu)) return;
3285 MENU_HideSubPopups(pWndOwner, Item->spSubMenu, FALSE, wFlags);
3286 MENU_SelectItem(pWndOwner, Item->spSubMenu, NO_SELECTED_ITEM, SendMenuSelect, NULL);
3287 TRACE("M_HSP top p hm %p pWndOwner IDMenu %p\n",top_popup_hmenu,pWndOwner->IDMenu);
3288 pWnd = ValidateHwndNoErr(Item->spSubMenu->hWnd);
3289 if (pWnd != NULL)
3290 {
3292 }
3293
3294 /* Native returns handle to destroyed window */
3295 if (!(wFlags & TPM_NONOTIFY))
3296 {
3297 co_IntSendMessage( UserHMGetHandle(pWndOwner), WM_UNINITMENUPOPUP, (WPARAM)UserHMGetHandle(Item->spSubMenu),
3298 MAKELPARAM(0, IS_SYSTEM_MENU(Item->spSubMenu) ? MF_SYSMENU : 0));
3299 }
3301 // Call WM_UNINITMENUPOPUP FIRST before destroy!!
3302 // Fixes todo_wine User32 test menu.c line 2239 GetMenuBarInfo callback....
3303 //
3304 Item->spSubMenu->hWnd = NULL;
3306 }
3307 }
3308}
3309
3310/***********************************************************************
3311 * MenuShowSubPopup
3312 *
3313 * Display the sub-menu of the selected item of this menu.
3314 * Return the handle of the submenu, or menu if no submenu to display.
3315 */
3316static PMENU FASTCALL MENU_ShowSubPopup(PWND WndOwner, PMENU Menu, BOOL SelectFirst, UINT Flags)
3317{
3318 RECT Rect, ParentRect;
3319 ITEM *Item;
3320 HDC Dc;
3321 PWND pWnd;
3322
3323 TRACE("owner=%x menu=%p 0x%04x\n", WndOwner, Menu, SelectFirst);
3324
3325 if (!Menu) return Menu;
3326
3327 if (Menu->iItem == NO_SELECTED_ITEM) return Menu;
3328
3329 Item = &Menu->rgItems[Menu->iItem];
3330 if (!(Item->spSubMenu) || (Item->fState & (MF_GRAYED | MF_DISABLED)))
3331 return Menu;
3332
3333 /* message must be sent before using item,
3334 because nearly everything may be changed by the application ! */
3335
3336 /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
3337 if (!(Flags & TPM_NONOTIFY))
3338 {
3340 (WPARAM) UserHMGetHandle(Item->spSubMenu),
3341 MAKELPARAM(Menu->iItem, IS_SYSTEM_MENU(Menu)));
3342 }
3343
3344 Item = &Menu->rgItems[Menu->iItem];
3345 //Rect = ItemInfo.Rect;
3346 Rect.left = Item->xItem;
3347 Rect.top = Item->yItem;
3348 Rect.right = Item->cxItem; // Do this for now......
3349 Rect.bottom = Item->cyItem;
3350
3351 pWnd = ValidateHwndNoErr(Menu->hWnd);
3352
3353 /* Grab the rect of our (entire) parent menu, so we can try to not overlap it */
3354 if (Menu->fFlags & MNF_POPUP)
3355 {
3356 if (!IntGetWindowRect(pWnd, &ParentRect))
3357 {
3358 ERR("No pWnd\n");
3359 ParentRect = Rect;
3360 }
3361
3362 /* Ensure we can slightly overlap our parent */
3363 RECTL_vInflateRect(&ParentRect, -UserGetSystemMetrics(SM_CXEDGE) * 2, 0);
3364 }
3365 else
3366 {
3367 /* Inside the menu bar, we do not want to grab the entire window... */
3368 ParentRect = Rect;
3369 if (pWnd)
3370 RECTL_vOffsetRect(&ParentRect, pWnd->rcWindow.left, pWnd->rcWindow.top);
3371 }
3372
3373 /* correct item if modified as a reaction to WM_INITMENUPOPUP message */
3374 if (!(Item->fState & MF_HILITE))
3375 {
3376 if (Menu->fFlags & MNF_POPUP) Dc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE);
3377 else Dc = UserGetDCEx(pWnd, 0, DCX_CACHE | DCX_WINDOW);
3378
3380
3381 Item->fState |= MF_HILITE;
3382 MENU_DrawMenuItem(pWnd, Menu, WndOwner, Dc, Item, Menu->cyMenu,
3383 !(Menu->fFlags & MNF_POPUP), ODA_DRAWENTIRE);
3384
3385 UserReleaseDC(pWnd, Dc, FALSE);
3386 }
3387
3388 if (!Item->yItem && !Item->xItem && !Item->cyItem && !Item->cxItem)
3389 {
3390 Item->xItem = Rect.left;
3391 Item->yItem = Rect.top;
3392 Item->cxItem = Rect.right; // Do this for now......
3393 Item->cyItem = Rect.bottom;
3394 }
3395 Item->fState |= MF_MOUSESELECT;
3396
3397 if (IS_SYSTEM_MENU(Menu))
3398 {
3399 MENU_InitSysMenuPopup(Item->spSubMenu, pWnd->style, pWnd->pcls->style, HTSYSMENU);
3400
3401 NC_GetSysPopupPos(pWnd, &Rect);
3402 /* Ensure we do not overlap this */
3403 ParentRect = Rect;
3404 if (Flags & TPM_LAYOUTRTL) Rect.left = Rect.right;
3405 Rect.top = Rect.bottom;
3408 }
3409 else
3410 {
3411 IntGetWindowRect(pWnd, &Rect);
3412 if (Menu->fFlags & MNF_POPUP)
3413 {
3414 RECT rc;
3415 rc.left = Item->xItem;
3416 rc.top = Item->yItem;
3417 rc.right = Item->cxItem;
3418 rc.bottom = Item->cyItem;
3419
3420 MENU_AdjustMenuItemRect(Menu, &rc);
3421
3422 /* The first item in the popup menu has to be at the
3423 same y position as the focused menu item */
3424 if(Flags & TPM_LAYOUTRTL)
3426 else
3428
3429 Rect.top += rc.top;
3430 }
3431 else
3432 {
3433 if(Flags & TPM_LAYOUTRTL)
3434 Rect.left += Rect.right - Item->xItem; //ItemInfo.Rect.left;
3435 else
3436 Rect.left += Item->xItem; //ItemInfo.Rect.left;
3437 Rect.top += Item->cyItem; //ItemInfo.Rect.bottom;
3438 Rect.right = Item->cxItem - Item->xItem; //ItemInfo.Rect.right - ItemInfo.Rect.left;
3439 Rect.bottom = Item->cyItem - Item->yItem; //ItemInfo.Rect.bottom - ItemInfo.Rect.top;
3440 }
3441 }
3442
3443 /* Next menu does not need to be shown vertical anymore */
3444 if (Menu->fFlags & MNF_POPUP)
3445 Flags &= (~TPM_VERTICAL);
3446
3447
3448
3449 /* use default alignment for submenus */
3451
3452 MENU_InitPopup( WndOwner, Item->spSubMenu, Flags );
3453
3454 MENU_ShowPopup( WndOwner, Item->spSubMenu, Menu->iItem, Flags,
3455 Rect.left, Rect.top, &ParentRect);
3456 if (SelectFirst)
3457 {
3458 MENU_MoveSelection(WndOwner, Item->spSubMenu, ITEM_NEXT);
3459 }
3460 return Item->spSubMenu;
3461}
3462
3463/***********************************************************************
3464 * MenuExecFocusedItem
3465 *
3466 * Execute a menu item (for instance when user pressed Enter).
3467 * Return the wID of the executed item. Otherwise, -1 indicating
3468 * that no menu item was executed, -2 if a popup is shown;
3469 * Have to receive the flags for the TrackPopupMenu options to avoid
3470 * sending unwanted message.
3471 *
3472 */
3474{
3475 PITEM Item;
3476
3477 TRACE("%p menu=%p\n", pmt, Menu);
3478
3479 if (!Menu || !Menu->cItems || Menu->iItem == NO_SELECTED_ITEM)
3480 {
3481 return -1;
3482 }
3483
3484 Item = &Menu->rgItems[Menu->iItem];
3485
3486 TRACE("%p %08x %p\n", Menu, Item->wID, Item->spSubMenu);
3487
3488 if (!(Item->spSubMenu))
3489 {
3490 if (!(Item->fState & (MF_GRAYED | MF_DISABLED)) && !(Item->fType & MF_SEPARATOR))
3491 {
3492 /* If TPM_RETURNCMD is set you return the id, but
3493 do not send a message to the owner */
3494 if (!(Flags & TPM_RETURNCMD))
3495 {
3496 if (Menu->fFlags & MNF_SYSMENU)
3497 {
3499 MAKELPARAM((SHORT) pmt->Pt.x, (SHORT) pmt->Pt.y));
3500 }
3501 else
3502 {
3503 DWORD dwStyle = ((Menu->fFlags & MNS_STYLE_MASK) | ( pmt->TopMenu ? (pmt->TopMenu->fFlags & MNS_STYLE_MASK) : 0) );
3504
3505 if (dwStyle & MNS_NOTIFYBYPOS)
3506 UserPostMessage(UserHMGetHandle(pmt->OwnerWnd), WM_MENUCOMMAND, Menu->iItem, (LPARAM)UserHMGetHandle(Menu));
3507 else
3509 }
3510 }
3511 return Item->wID;
3512 }
3513 }
3514 else
3515 {
3516 pmt->CurrentMenu = MENU_ShowSubPopup(pmt->OwnerWnd, Menu, TRUE, Flags);
3517 return -2;
3518 }
3519
3520 return -1;
3521}
3522
3523/***********************************************************************
3524 * MenuSwitchTracking
3525 *
3526 * Helper function for menu navigation routines.
3527 */
3529{
3530 TRACE("%x menu=%x 0x%04x\n", pmt, PtMenu, Index);
3531
3532 if ( pmt->TopMenu != PtMenu &&
3533 !((PtMenu->fFlags | pmt->TopMenu->fFlags) & MNF_POPUP) )
3534 {
3535 /* both are top level menus (system and menu-bar) */
3538 pmt->TopMenu = PtMenu;
3539 }
3540 else
3541 {
3542 MENU_HideSubPopups(pmt->OwnerWnd, PtMenu, FALSE, wFlags);
3543 }
3544
3545 MENU_SelectItem(pmt->OwnerWnd, PtMenu, Index, TRUE, NULL);
3546}
3547
3548/***********************************************************************
3549 * MenuButtonDown
3550 *
3551 * Return TRUE if we can go on with menu tracking.
3552 */
3554{
3555 TRACE("%x PtMenu=%p\n", pmt, PtMenu);
3556
3557 if (PtMenu)
3558 {
3559 UINT id = 0;
3560 PITEM item;
3561
3562 // Special check for the icon system menu
3563 if (IS_SYSTEM_MENU(PtMenu) && !(PtMenu->fFlags & MNF_POPUP))
3564 {
3565 item = PtMenu->rgItems;
3566 }
3567 else
3568 {
3569 item = MENU_FindItemByCoords( PtMenu, pmt->Pt, &id );
3570 }
3571
3572 if (item)
3573 {
3574 if (PtMenu->iItem != id)
3575 MENU_SwitchTracking(pmt, PtMenu, id, Flags);
3576
3577 /* If the popup menu is not already "popped" */
3578 if (!(item->fState & MF_MOUSESELECT))
3579 {
3580 pmt->CurrentMenu = MENU_ShowSubPopup(pmt->OwnerWnd, PtMenu, FALSE, Flags);
3581 }
3582
3583 return TRUE;
3584 }
3585 /* Else the click was on the menu bar, finish the tracking */
3586 }
3587 return FALSE;
3588}
3589
3590/***********************************************************************
3591 * MenuButtonUp
3592 *
3593 * Return the value of MenuExecFocusedItem if
3594 * the selected item was not a popup. Else open the popup.
3595 * A -1 return value indicates that we go on with menu tracking.
3596 *
3597 */
3599{
3600 TRACE("%p pmenu=%x\n", pmt, PtMenu);
3601
3602 if (PtMenu)
3603 {
3604 UINT Id = 0;
3605 ITEM *item;
3606
3607 // Special check for the icon system menu
3608 if (IS_SYSTEM_MENU(PtMenu) && !(PtMenu->fFlags & MNF_POPUP))
3609 {
3610 item = PtMenu->rgItems;
3611 }
3612 else
3613 {
3614 item = MENU_FindItemByCoords( PtMenu, pmt->Pt, &Id );
3615 }
3616
3617 if (item && ( PtMenu->iItem == Id))
3618 {
3619 if (!(item->spSubMenu))
3620 {
3621 INT ExecutedMenuId = MENU_ExecFocusedItem( pmt, PtMenu, Flags);
3622 if (ExecutedMenuId == -1 || ExecutedMenuId == -2) return -1;
3623 return ExecutedMenuId;
3624 }
3625
3626 /* If we are dealing with the menu bar */
3627 /* and this is a click on an already "popped" item: */
3628 /* Stop the menu tracking and close the opened submenus */
3629 if (pmt->TopMenu == PtMenu && PtMenu->TimeToHide)
3630 {
3631 return 0;
3632 }
3633 }
3634 if ( IntGetMenu(PtMenu->hWnd) == PtMenu )
3635 {
3636 PtMenu->TimeToHide = TRUE;
3637 }
3638 }
3639 return -1;
3640}
3641
3642/***********************************************************************
3643 * MenuPtMenu
3644 *
3645 * Walks menu chain trying to find a menu pt maps to.
3646 */
3648{
3649 PITEM pItem;
3650 PMENU ret = NULL;
3651
3652 if (!menu) return NULL;
3653
3654 /* try subpopup first (if any) */
3655 if (menu->iItem != NO_SELECTED_ITEM)
3656 {
3657 pItem = menu->rgItems;
3658 if ( pItem ) pItem = &pItem[menu->iItem];
3659 if ( pItem && pItem->spSubMenu && pItem->fState & MF_MOUSESELECT)
3660 {
3661 ret = MENU_PtMenu( pItem->spSubMenu, pt);
3662 }
3663 }
3664
3665 /* check the current window (avoiding WM_HITTEST) */
3666 if (!ret)
3667 {
3668 PWND pWnd = ValidateHwndNoErr(menu->hWnd);
3669 INT ht = GetNCHitEx(pWnd, pt);
3670 if ( menu->fFlags & MNF_POPUP )
3671 {
3672 if (ht != HTNOWHERE && ht != HTERROR) ret = menu;
3673 }
3674 else if (ht == HTSYSMENU)
3675 ret = get_win_sys_menu(menu->hWnd);
3676 else if (ht == HTMENU)
3677 ret = IntGetMenu( menu->hWnd );
3678 }
3679 return ret;
3680}
3681
3682/***********************************************************************
3683 * MenuMouseMove
3684 *
3685 * Return TRUE if we can go on with menu tracking.
3686 */
3688{
3690
3691 if ( PtMenu )
3692 MENU_FindItemByCoords( PtMenu, pmt->Pt, &Index );
3693
3694 if (Index == NO_SELECTED_ITEM)
3695 {
3697 }
3698 else if (PtMenu->iItem != Index)
3699 {
3700 MENU_SwitchTracking(pmt, PtMenu, Index, Flags);
3701 pmt->CurrentMenu = MENU_ShowSubPopup(pmt->OwnerWnd, PtMenu, FALSE, Flags);
3702 }
3703 return TRUE;
3704}
3705
3706/***********************************************************************
3707 * MenuGetSubPopup
3708 *
3709 * Return the handle of the selected sub-popup menu (if any).
3710 */
3712{
3713 ITEM *item;
3714
3715 if ((!menu) || (menu->iItem == NO_SELECTED_ITEM)) return 0;
3716
3717 item = &menu->rgItems[menu->iItem];
3718 if (item && (item->spSubMenu) && (item->fState & MF_MOUSESELECT))
3719 {
3720 return item->spSubMenu;
3721 }
3722 return 0;
3723}
3724
3725/***********************************************************************
3726 * MenuDoNextMenu
3727 *
3728 * NOTE: WM_NEXTMENU documented in Win32 is a bit different.
3729 */
3731{
3732 BOOL atEnd = FALSE;
3733
3734 /* When skipping left, we need to do something special after the
3735 first menu. */
3736 if (Vk == VK_LEFT && pmt->TopMenu->iItem == 0)
3737 {
3738 atEnd = TRUE;
3739 }
3740 /* When skipping right, for the non-system menu, we need to
3741 handle the last non-special menu item (ie skip any window
3742 icons such as MDI maximize, restore or close) */
3743 else if ((Vk == VK_RIGHT) && !IS_SYSTEM_MENU(pmt->TopMenu))
3744 {
3745 UINT i = pmt->TopMenu->iItem + 1;
3746 while (i < pmt->TopMenu->cItems) {
3747 if ((pmt->TopMenu->rgItems[i].wID >= SC_SIZE &&
3748 pmt->TopMenu->rgItems[i].wID <= SC_RESTORE)) {
3749 i++;
3750 } else break;
3751 }
3752 if (i == pmt->TopMenu->cItems) {
3753 atEnd = TRUE;
3754 }
3755 }
3756 /* When skipping right, we need to cater for the system menu */
3757 else if ((Vk == VK_RIGHT) && IS_SYSTEM_MENU(pmt->TopMenu))
3758 {
3759 if (pmt->TopMenu->iItem == (pmt->TopMenu->cItems - 1)) {
3760 atEnd = TRUE;
3761 }
3762 }
3763
3764 if ( atEnd )
3765 {
3766 MDINEXTMENU NextMenu;
3767 PMENU MenuTmp;
3768 PWND pwndTemp;
3769 HMENU hNewMenu;
3770 HWND hNewWnd;
3771 UINT Id = 0;
3772
3773 MenuTmp = (IS_SYSTEM_MENU(pmt->TopMenu)) ? co_IntGetSubMenu(pmt->TopMenu, 0) : pmt->TopMenu;
3774 NextMenu.hmenuIn = UserHMGetHandle(MenuTmp);
3775 NextMenu.hmenuNext = NULL;
3776 NextMenu.hwndNext = NULL;
3778
3779 TRACE("%p [%p] -> %p [%p]\n",
3780 pmt->CurrentMenu, pmt->OwnerWnd, NextMenu.hmenuNext, NextMenu.hwndNext );
3781
3782 if (NULL == NextMenu.hmenuNext || NULL == NextMenu.hwndNext)
3783 {
3784 hNewWnd = UserHMGetHandle(pmt->OwnerWnd);
3785 if (IS_SYSTEM_MENU(pmt->TopMenu))
3786 {
3787 /* switch to the menu bar */
3788
3789 if (pmt->OwnerWnd->style & WS_CHILD || !(MenuTmp = IntGetMenu(hNewWnd))) return FALSE;
3790
3791 if (Vk == VK_LEFT)
3792 {
3793 Id = MenuTmp->cItems - 1;
3794
3795 /* Skip backwards over any system predefined icons,
3796 eg. MDI close, restore etc icons */
3797 while ((Id > 0) &&
3798 (MenuTmp->rgItems[Id].wID >= SC_SIZE &&
3799 MenuTmp->rgItems[Id].wID <= SC_RESTORE)) Id--;
3800
3801 }
3802 hNewMenu = UserHMGetHandle(MenuTmp);
3803 }
3804 else if (pmt->OwnerWnd->style & WS_SYSMENU)
3805 {
3806 /* switch to the system menu */
3807 MenuTmp = get_win_sys_menu(hNewWnd);
3808 if (MenuTmp) hNewMenu = UserHMGetHandle(MenuTmp);
3809 else hNewMenu = NULL;
3810 }
3811 else
3812 return FALSE;
3813 }
3814 else /* application returned a new menu to switch to */
3815 {
3816 hNewMenu = NextMenu.hmenuNext;
3817 hNewWnd = NextMenu.hwndNext;
3818
3819 if ((MenuTmp = UserGetMenuObject(hNewMenu)) && (pwndTemp = ValidateHwndNoErr(hNewWnd)))
3820 {
3821 if ( pwndTemp->style & WS_SYSMENU && (get_win_sys_menu(hNewWnd) == MenuTmp) )
3822 {
3823 /* get the real system menu */
3824 MenuTmp = get_win_sys_menu(hNewWnd);
3825 hNewMenu = UserHMGetHandle(MenuTmp);
3826 }
3827 else if (pwndTemp->style & WS_CHILD || IntGetMenu(hNewWnd) != MenuTmp)
3828 {
3829 /* FIXME: Not sure what to do here;
3830 * perhaps try to track NewMenu as a popup? */
3831
3832 WARN(" -- got confused.\n");
3833 return FALSE;
3834 }
3835 }
3836 else return FALSE;
3837 }
3838
3839 if (hNewMenu != UserHMGetHandle(pmt->TopMenu))
3840 {
3842
3843 if (pmt->CurrentMenu != pmt->TopMenu)
3845 }
3846
3847 if (hNewWnd != UserHMGetHandle(pmt->OwnerWnd))
3848 {
3850 pmt->OwnerWnd = ValidateHwndNoErr(hNewWnd);
3853 pti->MessageQueue->QF_flags &= ~QF_CAPTURELOCKED;
3855 pti->MessageQueue->QF_flags |= QF_CAPTURELOCKED;
3856 }
3857
3858 pmt->TopMenu = pmt->CurrentMenu = UserGetMenuObject(hNewMenu); /* all subpopups are hidden */
3859 MENU_SelectItem(pmt->OwnerWnd, pmt->TopMenu, Id, TRUE, 0);
3860
3861 return TRUE;
3862 }
3863 return FALSE;
3864}
3865
3866/***********************************************************************
3867 * MenuSuspendPopup
3868 *
3869 * The idea is not to show the popup if the next input message is
3870 * going to hide it anyway.
3871 */
3873{
3874 MSG msg;
3875
3876 msg.hwnd = UserHMGetHandle(pmt->OwnerWnd);
3877
3878 co_IntGetPeekMessage( &msg, 0, uMsg, uMsg, PM_NOYIELD | PM_REMOVE, FALSE);
3879 pmt->TrackFlags |= TF_SKIPREMOVE;
3880
3881 switch( uMsg )
3882 {
3883 case WM_KEYDOWN:
3885 if( msg.message == WM_KEYUP || msg.message == WM_PAINT )
3886 {
3889 if( msg.message == WM_KEYDOWN &&
3890 (msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT))
3891 {
3893 return TRUE;
3894 }
3895 }
3896 break;
3897 }
3898 /* failures go through this */
3899 pmt->TrackFlags &= ~TF_SUSPENDPOPUP;
3900 return FALSE;
3901}
3902
3903/***********************************************************************
3904 * MenuKeyEscape
3905 *
3906 * Handle a VK_ESCAPE key event in a menu.
3907 */
3909{
3910 BOOL EndMenu = TRUE;
3911
3912 if (pmt->CurrentMenu != pmt->TopMenu)
3913 {
3914 if (pmt->CurrentMenu && (pmt->CurrentMenu->fFlags & MNF_POPUP))
3915 {
3916 PMENU MenuPrev, MenuTmp;
3917
3918 MenuPrev = MenuTmp = pmt->TopMenu;
3919
3920 /* close topmost popup */
3921 while (MenuTmp != pmt->CurrentMenu)
3922 {
3923 MenuPrev = MenuTmp;
3924 MenuTmp = MENU_GetSubPopup(MenuPrev);
3925 }
3926
3927 MENU_HideSubPopups(pmt->OwnerWnd, MenuPrev, TRUE, Flags);
3928 pmt->CurrentMenu = MenuPrev;
3929 EndMenu = FALSE;
3930 }
3931 }
3932
3933 return EndMenu;
3934}
3935
3936/***********************************************************************
3937 * MenuKeyLeft
3938 *
3939 * Handle a VK_LEFT key event in a menu.
3940 */
3942{
3943 PMENU MenuTmp, MenuPrev;
3944 UINT PrevCol;
3945
3946 MenuPrev = MenuTmp = pmt->TopMenu;
3947
3948 /* Try to move 1 column left (if possible) */
3949 if ( (PrevCol = MENU_GetStartOfPrevColumn(pmt->CurrentMenu)) != NO_SELECTED_ITEM)
3950 {
3951 MENU_SelectItem(pmt->OwnerWnd, pmt->CurrentMenu, PrevCol, TRUE, 0);
3952 return;
3953 }
3954
3955 /* close topmost popup */
3956 while (MenuTmp != pmt->CurrentMenu)
3957 {
3958 MenuPrev = MenuTmp;
3959 MenuTmp = MENU_GetSubPopup(MenuPrev);
3960 }
3961
3962 MENU_HideSubPopups(pmt->OwnerWnd, MenuPrev, TRUE, Flags);
3963 pmt->CurrentMenu = MenuPrev;
3964
3965 if ((MenuPrev == pmt->TopMenu) && !(pmt->TopMenu->fFlags & MNF_POPUP))
3966 {
3967 /* move menu bar selection if no more popups are left */
3968
3969 if (!MENU_DoNextMenu(pmt, VK_LEFT, Flags))
3971
3972 if (MenuPrev != MenuTmp || pmt->TrackFlags & TF_SUSPENDPOPUP)
3973 {
3974 /* A sublevel menu was displayed - display the next one
3975 * unless there is another displacement coming up */
3976
3977 if (!MENU_SuspendPopup(pmt, msg))
3979 TRUE, Flags);
3980 }
3981 }
3982}
3983
3984/***********************************************************************
3985 * MenuKeyRight
3986 *
3987 * Handle a VK_RIGHT key event in a menu.
3988 */
3990{
3991 PMENU menutmp;
3992 UINT NextCol;
3993
3994 TRACE("MenuKeyRight called, cur %p, top %p.\n",
3995 pmt->CurrentMenu, pmt->TopMenu);
3996
3997 if ((pmt->TopMenu->fFlags & MNF_POPUP) || (pmt->CurrentMenu != pmt->TopMenu))
3998 {
3999 /* If already displaying a popup, try to display sub-popup */
4000
4001 menutmp = pmt->CurrentMenu;
4002 pmt->CurrentMenu = MENU_ShowSubPopup(pmt->OwnerWnd, menutmp, TRUE, Flags);
4003
4004 /* if subpopup was displayed then we are done */
4005 if (menutmp != pmt->CurrentMenu) return;
4006 }
4007
4008 /* Check to see if there's another column */
4009 if ( (NextCol = MENU_GetStartOfNextColumn(pmt->CurrentMenu)) != NO_SELECTED_ITEM)
4010 {
4011 TRACE("Going to %d.\n", NextCol);
4012 MENU_SelectItem(pmt->OwnerWnd, pmt->CurrentMenu, NextCol, TRUE, 0);
4013 return;
4014 }
4015
4016 if (!(pmt->TopMenu->fFlags & MNF_POPUP)) /* menu bar tracking */
4017 {
4018 if (pmt->CurrentMenu != pmt->TopMenu)
4019 {
4021 menutmp = pmt->CurrentMenu = pmt->TopMenu;
4022 }
4023 else
4024 {
4025 menutmp = NULL;
4026 }
4027
4028 /* try to move to the next item */
4029 if ( !MENU_DoNextMenu(pmt, VK_RIGHT, Flags))
4031
4032 if ( menutmp || pmt->TrackFlags & TF_SUSPENDPOPUP )
4033 {
4034 if ( !MENU_SuspendPopup(pmt, msg) )
4036 }
4037 }
4038}
4039
4040/***********************************************************************
4041 * MenuTrackMenu
4042 *
4043 * Menu tracking code.
4044 */
4046 PWND pwnd)
4047{
4048 MSG msg;
4049 BOOL fRemove;
4050 INT executedMenuId = -1;
4051 MTRACKER mt;
4052 HWND capture_win;
4053 PMENU pmMouse;
4054 BOOL enterIdleSent = FALSE;
4055 BOOL firstClick = TRUE;
4056 PWND pWnd;
4058
4059 if (pti != pwnd->head.pti)
4060 {
4061 ERR("Not the same PTI!!!!\n");
4062 }
4063
4064 mt.TrackFlags = 0;
4065 mt.CurrentMenu = pmenu;
4066 mt.TopMenu = pmenu;
4067 mt.OwnerWnd = pwnd;
4068 mt.Pt.x = x;
4069 mt.Pt.y = y;
4070
4071 TRACE("MTM : hmenu=%p flags=0x%08x (%d,%d) hwnd=%x\n",
4072 UserHMGetHandle(pmenu), wFlags, x, y, UserHMGetHandle(pwnd));
4073
4074 pti->MessageQueue->QF_flags &= ~QF_ACTIVATIONCHANGE;
4075
4076 if (wFlags & TPM_BUTTONDOWN)
4077 {
4078 /* Get the result in order to start the tracking or not */
4079 fRemove = MENU_ButtonDown( &mt, pmenu, wFlags );
4080 fInsideMenuLoop = fRemove;
4081 }
4082
4084
4085 if (wFlags & TPM_POPUPMENU && pmenu->cItems == 0) // Tracking empty popup menu...
4086 {
4088 pti->MessageQueue->QF_flags &= ~QF_CAPTURELOCKED;
4089 co_UserSetCapture(NULL); /* release the capture */
4090 return 0;
4091 }
4092
4093 capture_win = IntGetCapture();
4094
4095 while (fInsideMenuLoop)
4096 {
4098 if (!VerifyMenu( mt.CurrentMenu )) /* sometimes happens if I do a window manager close */
4099 break;
4100
4101 /* we have to keep the message in the queue until it's
4102 * clear that menu loop is not over yet. */
4103
4104 for (;;)
4105 {
4106 if (co_IntGetPeekMessage( &msg, 0, 0, 0, PM_NOREMOVE, FALSE ))
4107 {
4108 if (!IntCallMsgFilter( &msg, MSGF_MENU )) break;
4109 /* remove the message from the queue */
4110 co_IntGetPeekMessage( &msg, 0, msg.message, msg.message, PM_REMOVE, FALSE );
4111 }
4112 else
4113 {
4114 /* ReactOS Checks */
4115 if (!VerifyWnd(mt.OwnerWnd) ||
4117 //pti->MessageQueue->QF_flags & QF_ACTIVATIONCHANGE || // See CORE-17338
4118 capture_win != IntGetCapture() ) // Should not happen, but this is ReactOS...
4119 {
4120 ErrorExit = TRUE; // Do not wait on dead windows, now win test_capture_4 works.
4121 break;
4122 }
4123
4124 if (!enterIdleSent)
4125 {
4127 enterIdleSent = TRUE;
4129 }
4130 co_IntWaitMessage(NULL, 0, 0);
4131 }
4132 }
4133
4134 if (ErrorExit) break; // Gracefully dropout.
4135
4136 /* check if EndMenu() tried to cancel us, by posting this message */
4137 if (msg.message == WM_CANCELMODE)
4138 {
4139 /* we are now out of the loop */
4141
4142 /* remove the message from the queue */
4143 co_IntGetPeekMessage( &msg, 0, msg.message, msg.message, PM_REMOVE, FALSE );
4144
4145 /* break out of internal loop, ala ESCAPE */
4146 break;
4147 }
4148
4149 mt.Pt = msg.pt;
4150
4151 if ( (msg.hwnd == mt.CurrentMenu->hWnd) || ((msg.message!=WM_TIMER) && (msg.message!=WM_SYSTIMER)) )
4152 enterIdleSent=FALSE;
4153
4154 fRemove = FALSE;
4155 if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
4156 {
4157 /*
4158 * Use the mouse coordinates in lParam instead of those in the MSG
4159 * struct to properly handle synthetic messages. They are already
4160 * in screen coordinates.
4161 */
4162 mt.Pt.x = (short)LOWORD(msg.lParam);
4163 mt.Pt.y = (short)HIWORD(msg.lParam);
4164
4165 /* Find a menu for this mouse event */
4166 pmMouse = MENU_PtMenu( mt.TopMenu, mt.Pt );
4167
4168 switch(msg.message)
4169 {
4170 /* no WM_NC... messages in captured state */
4171
4172 case WM_RBUTTONDBLCLK:
4173 case WM_RBUTTONDOWN:
4174 if (!(wFlags & TPM_RIGHTBUTTON))
4175 {
4176 if ( msg.message == WM_RBUTTONDBLCLK ) fInsideMenuLoop = FALSE; // Must exit or loop forever!
4177 break;
4178 }
4179 /* fall through */
4180 case WM_LBUTTONDBLCLK:
4181 case WM_LBUTTONDOWN:
4182 {
4183 /* If the message belongs to the menu, removes it from the queue */
4184 /* Else, end menu tracking */
4185 pWnd = ValidateHwndNoErr(mt.TopMenu->hWnd);
4186 /* Don't remove WM_LBUTTONDBLCLK to allow the closing of a window or program */
4187 if (msg.message == WM_LBUTTONDBLCLK && GetNCHitEx(pWnd, mt.Pt) == HTSYSMENU)
4188 fRemove = FALSE;
4189 else
4190 fRemove = MENU_ButtonDown(&mt, pmMouse, wFlags);
4191
4192 fInsideMenuLoop = fRemove;
4193 if (msg.message == WM_RBUTTONDBLCLK)
4194 fInsideMenuLoop = FALSE; // Must exit or loop forever
4195 break;
4196 }
4197
4198 case WM_RBUTTONUP:
4199 if (!(wFlags & TPM_RIGHTBUTTON)) break;
4200 /* fall through */
4201 case WM_LBUTTONUP:
4202 /* Check if a menu was selected by the mouse */
4203 if (pmMouse)
4204 {
4205 pWnd = ValidateHwndNoErr(mt.TopMenu->hWnd);
4206 /* Exit system menu if system icon is clicked a second time */
4207 if (!firstClick && GetNCHitEx(pWnd, mt.Pt) == HTSYSMENU)
4208 {
4209 fRemove = TRUE;
4211 }
4212 else
4213 {
4214 /* End the loop if executedMenuId is an item ID */
4215 /* or if the job was done (executedMenuId = 0). */
4216 executedMenuId = MENU_ButtonUp( &mt, pmMouse, wFlags);
4217 fRemove = (executedMenuId != -1);
4218 fInsideMenuLoop = !fRemove;
4219 firstClick = FALSE;
4220 }
4221 }
4222 /* No menu was selected by the mouse */
4223 /* if the function was called by TrackPopupMenu, continue
4224 with the menu tracking. If not, stop it */
4225 else
4227
4228 break;
4229
4230 case WM_MOUSEMOVE:
4231 /* the selected menu item must be changed every time */
4232 /* the mouse moves. */
4233
4234 if (pmMouse)
4235 fInsideMenuLoop |= MENU_MouseMove( &mt, pmMouse, wFlags );
4236
4237 } /* switch(msg.message) - mouse */
4238 }
4239 else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
4240 {
4241 fRemove = TRUE; /* Keyboard messages are always removed */
4242 switch(msg.message)
4243 {
4244 case WM_KEYDOWN:
4245 case WM_SYSKEYDOWN:
4246 switch(msg.wParam)
4247 {
4248 case VK_MENU:
4249 case VK_F10:
4251 break;
4252
4253 case VK_HOME:
4254 case VK_END:
4257 break;
4258
4259 case VK_UP:
4260 case VK_DOWN: /* If on menu bar, pull-down the menu */
4261 if (!(mt.CurrentMenu->fFlags & MNF_POPUP))
4263 else /* otherwise try to move selection */
4265 break;
4266
4267 case VK_LEFT:
4268 MENU_KeyLeft( &mt, wFlags, msg.message );
4269 break;
4270
4271 case VK_RIGHT:
4272 MENU_KeyRight( &mt, wFlags, msg.message );
4273 break;
4274
4275 case VK_ESCAPE:
4277 break;
4278
4279 case VK_F1:
4280 {
4281 HELPINFO hi;
4282 hi.cbSize = sizeof(HELPINFO);
4285 hi.iCtrlId = 0;
4286 else
4287 hi.iCtrlId = pmenu->rgItems[mt.CurrentMenu->iItem].wID;
4289 hi.dwContextId = pmenu->dwContextHelpId;
4290 hi.MousePos = msg.pt;
4291 co_IntSendMessage( UserHMGetHandle(pwnd), WM_HELP, 0, (LPARAM)&hi);
4292 break;
4293 }
4294
4295 default:
4297 break;
4298 }
4299 break; /* WM_KEYDOWN */
4300
4301 case WM_CHAR:
4302 case WM_SYSCHAR:
4303 {
4304 UINT pos;
4305 BOOL fEndMenu;
4306
4307 if (msg.wParam == L'\r' || msg.wParam == L' ')
4308 {
4309 executedMenuId = MENU_ExecFocusedItem(&mt, mt.CurrentMenu, wFlags);
4310 fEndMenu = (executedMenuId != -2);
4311 fInsideMenuLoop = !fEndMenu;
4312 break;
4313 }
4314
4315 /* Hack to avoid control chars. */
4316 /* We will find a better way real soon... */
4317 if (msg.wParam < 32) break;
4318
4320
4321 if (pos == (UINT)-2) fInsideMenuLoop = FALSE;
4322 else if (pos == (UINT)-1) UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); //MessageBeep(0);
4323 else
4324 {
4326 executedMenuId = MENU_ExecFocusedItem(&mt, mt.CurrentMenu, wFlags);
4327 fEndMenu = (executedMenuId != -2);
4328 fInsideMenuLoop = !fEndMenu;
4329 }
4330 }
4331 break;
4332 } /* switch(msg.message) - kbd */
4333 }
4334 else
4335 {
4336 co_IntGetPeekMessage( &msg, 0, msg.message, msg.message, PM_REMOVE, FALSE );
4338 continue;
4339 }
4340
4341 if (fInsideMenuLoop) fRemove = TRUE;
4342
4343 /* finally remove message from the queue */
4344
4345 if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
4346 co_IntGetPeekMessage( &msg, 0, msg.message, msg.message, PM_REMOVE, FALSE );
4347 else mt.TrackFlags &= ~TF_SKIPREMOVE;
4348 }
4349
4351 pti->MessageQueue->QF_flags &= ~QF_CAPTURELOCKED;
4352 co_UserSetCapture(NULL); /* release the capture */
4353
4354 /* If dropdown is still painted and the close box is clicked on
4355 then the menu will be destroyed as part of the DispatchMessage above.
4356 This will then invalidate the menu handle in mt.hTopMenu. We should
4357 check for this first. */
4358 if ( VerifyMenu( mt.TopMenu ) )
4359 {
4360 if (VerifyWnd(mt.OwnerWnd))
4361 {
4363
4364 if (mt.TopMenu->fFlags & MNF_POPUP)
4365 {
4366 PWND pwndTM = ValidateHwndNoErr(mt.TopMenu->hWnd);
4367 if (pwndTM)
4368 {
4369 IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, pwndTM, OBJID_CLIENT, CHILDID_SELF, 0);
4370
4371 co_UserDestroyWindow(pwndTM);
4372 }
4373 mt.TopMenu->hWnd = NULL;
4374
4375 if (!(wFlags & TPM_NONOTIFY))
4376 {
4379 }
4380 }
4383 }
4384
4385 /* Reset the variable for hiding menu */
4386 mt.TopMenu->TimeToHide = FALSE;
4387 }
4388
4390 /* The return value is only used by TrackPopupMenu */
4391 if (!(wFlags & TPM_RETURNCMD)) return TRUE;
4392 if (executedMenuId == -1) executedMenuId = 0;
4393 return executedMenuId;
4394}
4395
4396/***********************************************************************
4397 * MenuInitTracking
4398 */
4400{
4401 HWND capture_win;
4403
4404 TRACE("hwnd=%p hmenu=%p\n", UserHMGetHandle(pWnd), UserHMGetHandle(Menu));
4405
4407
4408 /* This makes the menus of applications built with Delphi work.
4409 * It also enables menus to be displayed in more than one window,
4410 * but there are some bugs left that need to be fixed in this case.
4411 */
4412 if (!bPopup)
4413 {
4414 Menu->hWnd = UserHMGetHandle(pWnd);
4415 }
4416
4417 if (!top_popup) {
4418 top_popup = Menu->hWnd;
4420 }
4421
4423 fInEndMenu = FALSE;
4424
4425 /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
4426 if (!(wFlags & TPM_NONOTIFY))
4427 {
4429 }
4430
4431 //
4432 // Capture is set before calling WM_INITMENU and after WM_ENTERMENULOOP, see msg_menu.
4433 //
4434 capture_win = (wFlags & TPM_POPUPMENU) ? Menu->hWnd : UserHMGetHandle(pWnd);
4435 MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, capture_win); // 1
4436 co_UserSetCapture(capture_win); // 2
4437 pti->MessageQueue->QF_flags |= QF_CAPTURELOCKED; // Set the Q bits so noone can change this!
4438
4440
4441 if (!(wFlags & TPM_NONOTIFY))
4442 {
4444 /* If an app changed/recreated menu bar entries in WM_INITMENU
4445 * menu sizes will be recalculated once the menu created/shown.
4446 */
4447 }
4448
4449 IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
4450 pWnd,
4452 CHILDID_SELF, 0);
4453 return TRUE;
4454}
4455
4456/***********************************************************************
4457 * MenuExitTracking
4458 */
4460{
4461 TRACE("Exit Track hwnd=%p bPopup %d\n", UserHMGetHandle(pWnd), bPopup);
4462
4463 IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, pWnd, OBJID_WINDOW, CHILDID_SELF, 0);
4464
4465 if (!(wFlags & TPM_NONOTIFY))
4467
4469
4470 top_popup = 0;
4472
4473 return TRUE;
4474}
4475
4476/***********************************************************************
4477 * MenuTrackMouseMenuBar
4478 *
4479 * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
4480 */
4482{
4483 PMENU pMenu = (ht == HTSYSMENU) ? IntGetSystemMenu(pWnd, FALSE) : IntGetMenu( UserHMGetHandle(pWnd) ); // See 74276 and CORE-12801
4485
4486 TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", pWnd, ht, pt.x, pt.y);
4487
4488 if (pWnd->ExStyle & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
4489 if (VerifyMenu(pMenu))
4490 {
4491 /* map point to parent client coordinates */
4494 {
4496 }
4497
4498 MENU_InitTracking(pWnd, pMenu, FALSE, wFlags);
4499 /* fetch the window menu again, it may have changed */
4500 pMenu = (ht == HTSYSMENU) ? get_win_sys_menu( UserHMGetHandle(pWnd) ) : IntGetMenu( UserHMGetHandle(pWnd) );
4501 MENU_TrackMenu(pMenu, wFlags, pt.x, pt.y, pWnd);
4503 }
4504}
4505
4506/***********************************************************************
4507 * MenuTrackKbdMenuBar
4508 *
4509 * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
4510 */
4512{
4513 UINT uItem = NO_SELECTED_ITEM;
4514 PMENU TrackMenu;
4516
4517 TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", UserHMGetHandle(pwnd), wParam, wChar);
4518
4519 /* find window that has a menu */
4520
4521 while (!( (pwnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD ) )
4522 if (!(pwnd = UserGetAncestor( pwnd, GA_PARENT ))) return;
4523
4524 /* check if we have to track a system menu */
4525
4526 TrackMenu = IntGetMenu( UserHMGetHandle(pwnd) );
4527 if (!TrackMenu || (pwnd->style & WS_MINIMIZE) != 0 || wChar == ' ' )
4528 {
4529 if (!(pwnd->style & WS_SYSMENU)) return;
4530 TrackMenu = get_win_sys_menu( UserHMGetHandle(pwnd) );
4531 uItem = 0;
4532 wParam |= HTSYSMENU; /* prevent item lookup */
4533 }
4534
4535 if (!VerifyMenu( TrackMenu )) return;
4536
4537 MENU_InitTracking( pwnd, TrackMenu, FALSE, wFlags );
4538
4539 /* fetch the window menu again, it may have changed */
4540 TrackMenu = (wParam & HTSYSMENU) ? get_win_sys_menu( UserHMGetHandle(pwnd) ) : IntGetMenu( UserHMGetHandle(pwnd) );
4541
4542 if( wChar && wChar != ' ' )
4543 {
4544 uItem = MENU_FindItemByKey( pwnd, TrackMenu, wChar, (wParam & HTSYSMENU) );
4545 if ( uItem >= (UINT)(-2) )
4546 {
4547 if( uItem == (UINT)(-1) ) UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); //MessageBeep(0);
4548 /* schedule end of menu tracking */
4549 wFlags |= TF_ENDMENU;
4550 goto track_menu;
4551 }
4552 }
4553
4554 MENU_SelectItem( pwnd, TrackMenu, uItem, TRUE, 0 );
4555
4556 if (!(wParam & HTSYSMENU) || wChar == ' ')
4557 {
4558 if( uItem == NO_SELECTED_ITEM )
4559 MENU_MoveSelection( pwnd, TrackMenu, ITEM_NEXT );
4560 else
4562 }
4563
4564track_menu:
4565 MENU_TrackMenu( TrackMenu, wFlags, 0, 0, pwnd );
4567}
4568
4569/**********************************************************************
4570 * TrackPopupMenuEx (USER32.@)
4571 */
4573 PWND pWnd, LPTPMPARAMS lpTpm)
4574{
4575 BOOL ret = FALSE;
4577
4578 if (pti != pWnd->head.pti)
4579 {
4580 ERR("Must be the same pti!\n");
4581 return ret;
4582 }
4583
4584 TRACE("hmenu %p flags %04x (%d,%d) hwnd %p lpTpm %p \n", //rect %s\n",
4585 UserHMGetHandle(menu), wFlags, x, y, UserHMGetHandle(pWnd), lpTpm); //,
4586 //lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" );
4587
4588 if (menu->hWnd && IntIsWindow(menu->hWnd))
4589 {
4591 return FALSE;
4592 }
4593
4594 if (MENU_InitPopup( pWnd, menu, wFlags ))
4595 {
4596 MENU_InitTracking(pWnd, menu, TRUE, wFlags);
4597
4598 /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
4599 if (!(wFlags & TPM_NONOTIFY))
4600 {
4602 }
4603
4604 if (menu->fFlags & MNF_SYSMENU)
4605 MENU_InitSysMenuPopup( menu, pWnd->style, pWnd->pcls->style, HTSYSMENU);
4606
4607 if (MENU_ShowPopup(pWnd, menu, 0, wFlags | TPM_POPUPMENU, x, y, lpTpm ? &lpTpm->rcExclude : NULL))
4608 ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, pWnd);
4609 else
4610 {
4612 pti->MessageQueue->QF_flags &= ~QF_CAPTURELOCKED;
4613 co_UserSetCapture(NULL); /* release the capture */
4614 }
4615
4617
4618 if (menu->hWnd)
4619 {
4620 PWND pwndM = ValidateHwndNoErr( menu->hWnd );
4621 if (pwndM) // wine hack around this with their destroy function.
4622 {
4623 if (!(pWnd->state & WNDS_DESTROYED))
4624 co_UserDestroyWindow( pwndM ); // Fix wrong error return.
4625 }
4626 menu->hWnd = 0;
4627
4628 if (!(wFlags & TPM_NONOTIFY))
4629 {
4630 co_IntSendMessage( UserHMGetHandle(pWnd), WM_UNINITMENUPOPUP, (WPARAM)UserHMGetHandle(menu),
4631 MAKELPARAM(0, IS_SYSTEM_MENU(menu) ? MF_SYSMENU : 0));
4632 }
4633 }
4634 }
4635 return ret;
4636}
4637
4638//
4639// Menu Class Proc.
4640//
4643 PWND Wnd,
4644 UINT Message,
4645 WPARAM wParam,
4646 LPARAM lParam,
4647 LRESULT *lResult)
4648{
4649 PPOPUPMENU pPopupMenu;
4650
4651 *lResult = 0;
4652
4653 TRACE("PMWP : pwnd=%x msg=%d wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
4654
4655 if (Wnd)
4656 {
4657 if (!Wnd->fnid)
4658 {
4659 if (Message != WM_NCCREATE)
4660 {
4661 *lResult = IntDefWindowProc(Wnd, Message, wParam, lParam, FALSE);
4662 return TRUE;
4663 }
4664 Wnd->fnid = FNID_MENU;
4665 pPopupMenu = DesktopHeapAlloc( Wnd->head.rpdesk, sizeof(POPUPMENU) );
4666 if (pPopupMenu == NULL)
4667 {
4668 return TRUE;
4669 }
4670 pPopupMenu->posSelectedItem = NO_SELECTED_ITEM;
4671 pPopupMenu->spwndPopupMenu = Wnd;
4672 ((PMENUWND)Wnd)->ppopupmenu = pPopupMenu;
4673 TRACE("Pop Up Menu is Setup! Msg %d\n",Message);
4674 *lResult = 1;
4675 return TRUE;
4676 }
4677 else
4678 {
4679 if (Wnd->fnid != FNID_MENU)
4680 {
4681 ERR("Wrong window class for Menu! fnid %x\n",Wnd->fnid);
4682 return TRUE;
4683 }
4684 pPopupMenu = ((PMENUWND)Wnd)->ppopupmenu;
4685 }
4686 }
4687
4688 switch(Message)
4689 {
4690 case WM_CREATE:
4691 {
4693 pPopupMenu->spmenu = UserGetMenuObject(cs->lpCreateParams);
4694 if (pPopupMenu->spmenu)
4695 {
4696 UserReferenceObject(pPopupMenu->spmenu);
4697 }
4698 break;
4699 }
4700
4701 case WM_MOUSEACTIVATE: /* We don't want to be activated */
4702 *lResult = MA_NOACTIVATE;
4703 break;
4704
4705 case WM_PAINT:
4706 {
4707 PAINTSTRUCT ps;
4708 IntBeginPaint(Wnd, &ps);
4709 MENU_DrawPopupMenu(Wnd, ps.hdc, pPopupMenu->spmenu);
4710 IntEndPaint(Wnd, &ps);
4711 break;
4712 }
4713
4714 case WM_PRINTCLIENT:
4715 {
4716 MENU_DrawPopupMenu( Wnd, (HDC)wParam, pPopupMenu->spmenu);
4717 break;
4718 }
4719
4720 case WM_ERASEBKGND:
4721 *lResult = 1;
4722 break;
4723
4724 case WM_DESTROY:
4725 /* zero out global pointer in case resident popup window was destroyed. */
4726 if (pPopupMenu)
4727 {
4728 if (UserHMGetHandle(Wnd) == top_popup)
4729 {
4730 top_popup = NULL;
4732 }
4733 }
4734 else
4735 {
4736 ERR("No Window Pop Up!\n");
4737 }
4738 break;
4739
4740 case WM_NCDESTROY:
4741 {
4742 if (pPopupMenu->spmenu)
4743 {
4744 IntReleaseMenuObject(pPopupMenu->spmenu);
4745 }
4746 DesktopHeapFree(Wnd->head.rpdesk, pPopupMenu );
4747 ((PMENUWND)Wnd)->ppopupmenu = 0;
4748 Wnd->fnid = FNID_DESTROY;
4749 break;
4750 }
4751
4752 case MM_SETMENUHANDLE: // wine'isms
4753 case MN_SETHMENU:
4754 {
4756 if (!pmenu)
4757 {
4758 ERR("Bad Menu Handle\n");
4759 break;
4760 }
4761 UserReferenceObject(pmenu);
4762 if (pPopupMenu->spmenu)
4763 {
4764 IntReleaseMenuObject(pPopupMenu->spmenu);
4765 }
4766 pPopupMenu->spmenu = pmenu;
4767 break;
4768 }
4769
4770 case MM_GETMENUHANDLE: // wine'isms
4771 case MN_GETHMENU:
4772 *lResult = (LRESULT)(pPopupMenu ? (pPopupMenu->spmenu ? UserHMGetHandle(pPopupMenu->spmenu) : NULL) : NULL);
4773 break;
4774
4775 default:
4776 if (Message > MN_GETHMENU && Message < MN_GETHMENU+19)
4777 {
4778 ERR("Someone is passing unknown menu messages %d\n",Message);
4779 }
4780 TRACE("PMWP to IDWP %d\n",Message);
4781 *lResult = IntDefWindowProc(Wnd, Message, wParam, lParam, FALSE);
4782 break;
4783 }
4784
4785 return TRUE;
4786}
4787
4790 PMENU MenuObject,
4791 UINT uItemHilite,
4792 UINT uHilite)
4793{
4794 PITEM MenuItem;
4795 UINT uItem = uItemHilite;
4796
4797 if (!(MenuItem = MENU_FindItem( &MenuObject, &uItem, uHilite ))) return TRUE;
4798
4799 if (uHilite & MF_HILITE)
4800 {
4801 MenuItem->fState |= MF_HILITE;
4802 }
4803 else
4804 {
4805 MenuItem->fState &= ~MF_HILITE;
4806 }
4807 if (MenuObject->iItem == uItemHilite) return TRUE;
4808 MENU_HideSubPopups( WindowObject, MenuObject, FALSE, 0 );
4809 MENU_SelectItem( WindowObject, MenuObject, uItemHilite, TRUE, 0 );
4810
4811 return TRUE; // Always returns true!!!!
4812}
4813
4816{
4817
4818 DWORD dwStyle = 0;
4819 DWORD dwExStyle = 0;
4820 BOOLEAN retValue = TRUE;
4821
4822 if (bti->cbSize == sizeof(TITLEBARINFO))
4823 {
4824 RtlZeroMemory(&bti->rgstate[0],sizeof(DWORD)*(CCHILDREN_TITLEBAR+1));
4825
4827
4828 dwStyle = pWindowObject->style;
4829 dwExStyle = pWindowObject->ExStyle;
4830
4831 bti->rcTitleBar.top = 0;
4832 bti->rcTitleBar.left = 0;
4833 bti->rcTitleBar.right = pWindowObject->rcWindow.right - pWindowObject->rcWindow.left;
4834 bti->rcTitleBar.bottom = pWindowObject->rcWindow.bottom - pWindowObject->rcWindow.top;
4835
4836 /* Is it iconiced ? */
4837 if ((dwStyle & WS_ICONIC)!=WS_ICONIC)
4838 {
4839 /* Remove frame from rectangle */
4840 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
4841 {
4842 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXFRAME) and UserGetSystemMetrics(SM_CYFRAME) */
4844 }
4845 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
4846 {
4847 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXDLGFRAME) and UserGetSystemMetrics(SM_CYDLGFRAME) */
4849 }
4850 else if (HAS_THINFRAME( dwStyle, dwExStyle))
4851 {
4852 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXBORDER) and UserGetSystemMetrics(SM_CYBORDER) */
4854 }
4855
4856 /* We have additional border information if the window
4857 * is a child (but not an MDI child) */
4858 if ( (dwStyle & WS_CHILD) &&
4859 ((dwExStyle & WS_EX_MDICHILD) == 0 ) )
4860 {
4861 if (dwExStyle & WS_EX_CLIENTEDGE)
4862 {
4863 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXEDGE) and UserGetSystemMetrics(SM_CYEDGE) */
4865 }
4866
4867 if (dwExStyle & WS_EX_STATICEDGE)
4868 {
4869 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXBORDER) and UserGetSystemMetrics(SM_CYBORDER) */
4871 }
4872 }
4873 }
4874
4875 bti->rcTitleBar.top += pWindowObject->rcWindow.top;
4876 bti->rcTitleBar.left += pWindowObject->rcWindow.left;
4877 bti->rcTitleBar.right += pWindowObject->rcWindow.left;
4878
4879 bti->rcTitleBar.bottom = bti->rcTitleBar.top;
4880 if (dwExStyle & WS_EX_TOOLWINDOW)
4881 {
4882 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CYSMCAPTION) */
4884 }
4885 else
4886 {
4887 /* FIXME: Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CYCAPTION) and UserGetSystemMetrics(SM_CXSIZE) */
4890 }
4891
4892 if (dwStyle & WS_CAPTION)
4893 {
4895 if (dwStyle & WS_SYSMENU)
4896 {
4897 if (!(dwStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)))
4898 {
4901 }
4902 else
4903 {
4904 if (!(dwStyle & WS_MINIMIZEBOX))
4905 {
4907 }
4908 if (!(dwStyle & WS_MAXIMIZEBOX))
4909 {
4911 }
4912 }
4913
4914 if (!(dwExStyle & WS_EX_CONTEXTHELP))
4915 {
4917 }
4918 if (pWindowObject->pcls->style & CS_NOCLOSE)
4919 {
4921 }
4922 }
4923 else
4924 {
4929 }
4930 }
4931 else
4932 {
4934 }
4935 }
4936 else
4937 {
4939 retValue = FALSE;
4940 }
4941
4942 return retValue;
4943}
4944
4947 PMENU Menu,
4948 UINT uItem,
4949 BOOL fByPosition,
4950 LPCMENUITEMINFOW UnsafeItemInfo,
4952{
4954 ROSMENUITEMINFO ItemInfo;
4955
4956 /* Try to copy the whole MENUITEMINFOW structure */
4957 Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, sizeof(MENUITEMINFOW));
4958 if (NT_SUCCESS(Status))
4959 {
4960 if (sizeof(MENUITEMINFOW) != ItemInfo.cbSize
4961 && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
4962 {
4964 return FALSE;
4965 }
4966 return IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo, lpstr);
4967 }
4968
4969 /* Try to copy without last field (not present in older versions) */
4970 Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, FIELD_OFFSET(MENUITEMINFOW, hbmpItem));
4971 if (NT_SUCCESS(Status))
4972 {
4973 if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
4974 {
4976 return FALSE;
4977 }
4978 ItemInfo.hbmpItem = (HBITMAP)0;
4979 return IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo, lpstr);
4980 }
4981
4983 return FALSE;
4984}
4985
4987{
4988 PMENU MenuObject;
4989 PITEM pItem;
4990
4991 if (!(MenuObject = UserGetMenuObject(hMenu)))
4992 {
4993 return (UINT)-1;
4994 }
4995
4996 if (!(pItem = MENU_FindItem( &MenuObject, &uId, uFlags ))) return -1;
4997
4998 if (pItem->spSubMenu)
4999 {
5000 return (pItem->spSubMenu->cItems << 8) | ((pItem->fState|pItem->fType|MF_POPUP) & 0xff);
5001 }
5002 else
5003 return (pItem->fType | pItem->fState);
5004}
5005
5007{
5008 PMENU MenuObject;
5009 PITEM pItem;
5010
5011 if (!(MenuObject = UserGetMenuObject(hMenu)))
5012 {
5013 return NULL;
5014 }
5015
5016 if (!(pItem = MENU_FindItem( &MenuObject, (UINT*)&nPos, MF_BYPOSITION ))) return NULL;
5017
5018 if (pItem->spSubMenu)
5019 {
5020 HMENU hsubmenu = UserHMGetHandle(pItem->spSubMenu);
5021 return hsubmenu;
5022 }
5023 return NULL;
5024}
5025
5027{
5028 PMENU menu, pSubTarget;
5029 UINT Pos;
5030 if (((*hMenu)==(HMENU)0xffff) ||(!(menu = UserGetMenuObject(*hMenu))))
5031 return NO_SELECTED_ITEM;
5032
5033 pSubTarget = UserGetMenuObject(hSubTarget);
5034
5035 Pos = MENU_FindSubMenu(&menu, pSubTarget );
5036
5037 *hMenu = (menu ? UserHMGetHandle(menu) : NULL);
5038
5039 return Pos;
5040}
5041
5042
5044{
5045 PWINSTATION_OBJECT WinStaObject;
5046 HANDLE Handle;
5047 PMENU Menu;
5049 PEPROCESS CurrentProcess = PsGetCurrentProcess();
5050
5051 if (gpepCSRSS != CurrentProcess)
5052 {
5053 /*
5054 * gpepCSRSS does not have a Win32WindowStation
5055 */
5056
5058 UserMode,
5059 0,
5060 &WinStaObject,
5061 0);
5062
5063 if (!NT_SUCCESS(Status))
5064 {
5065 ERR("Validation of window station handle (%p) failed\n",
5066 CurrentProcess->Win32WindowStation);
5068 return (HMENU)0;
5069 }
5070 Menu = IntCreateMenu(&Handle, !PopupMenu, Desktop, GetW32ProcessInfo());
5071 if (Menu && Menu->head.rpdesk->rpwinstaParent != WinStaObject)
5072 {
5073 ERR("Desktop Window Station does not match Process one!\n");
5074 }
5075 ObDereferenceObject(WinStaObject);
5076 }
5077 else
5078 {
5079 Menu = IntCreateMenu(&Handle, !PopupMenu, GetW32ThreadInfo()->rpdesk, GetW32ProcessInfo());
5080 }
5081
5082 if (Menu) UserDereferenceObject(Menu);
5083 return (HMENU)Handle;
5084}
5085
5088 PMENU Menu,
5089 UINT Item,
5090 BOOL ByPosition,
5091 PROSMENUITEMINFO ItemInfo,
5092 BOOL SetOrGet,
5094{
5095 PITEM MenuItem;
5096 BOOL Ret;
5097
5098 if (!(MenuItem = MENU_FindItem( &Menu, &Item, (ByPosition ? MF_BYPOSITION : MF_BYCOMMAND) )))
5099 {
5101 return FALSE;
5102 }
5103 if (SetOrGet)
5104 {
5105 Ret = IntSetMenuItemInfo(Menu, MenuItem, ItemInfo, lpstr);
5106 }
5107 else
5108 {
5109 Ret = IntGetMenuItemInfo(Menu, MenuItem, ItemInfo);
5110 }
5111 return Ret;
5112}
5113
5116 PMENU Menu,
5117 UINT Item,
5118 BOOL ByPosition,
5119 PROSMENUITEMINFO UnsafeItemInfo,
5120 BOOL SetOrGet,
5122{
5123 PITEM MenuItem;
5124 ROSMENUITEMINFO ItemInfo;
5126 UINT Size;
5127 BOOL Ret;
5128
5129 Status = MmCopyFromCaller(&Size, &UnsafeItemInfo->cbSize, sizeof(UINT));
5130 if (! NT_SUCCESS(Status))
5131 {
5133 return FALSE;
5134 }
5135 if ( Size != sizeof(MENUITEMINFOW) &&
5136 Size != FIELD_OFFSET(MENUITEMINFOW, hbmpItem) &&
5137 Size != sizeof(ROSMENUITEMINFO) )
5138 {
5140 return FALSE;
5141 }
5142 Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, Size);
5143 if (! NT_SUCCESS(Status))
5144 {
5146 return FALSE;
5147 }
5148 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
5149 set/get hbmpItem */
5150 if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) == Size
5151 && 0 != (ItemInfo.fMask & MIIM_BITMAP))
5152 {
5154 return FALSE;
5155 }
5156
5157 if (!(MenuItem = MENU_FindItem( &Menu, &Item, (ByPosition ? MF_BYPOSITION : MF_BYCOMMAND) )))
5158 {
5159 /* workaround for Word 95: pretend that SC_TASKLIST item exists. */
5160 if ( SetOrGet && Item == SC_TASKLIST && !ByPosition )
5161 return TRUE;
5162
5164 return FALSE;
5165 }
5166
5167 if (SetOrGet)
5168 {
5169 Ret = IntSetMenuItemInfo(Menu, MenuItem, &ItemInfo, lpstr);
5170 }
5171 else
5172 {
5173 Ret = IntGetMenuItemInfo(Menu, MenuItem, &ItemInfo);
5174 if (Ret)
5175 {
5176 Status = MmCopyToCaller(UnsafeItemInfo, &ItemInfo, Size);
5177 if (! NT_SUCCESS(Status))
5178 {
5180 return FALSE;
5181 }
5182 }
5183 }
5184
5185 return Ret;
5186}
5187
5190 PMENU Menu,
5191 PROSMENUINFO UnsafeMenuInfo,
5192 BOOL SetOrGet)
5193{
5194 BOOL Res;
5195 DWORD Size;
5198
5199 Status = MmCopyFromCaller(&Size, &UnsafeMenuInfo->cbSize, sizeof(DWORD));
5200 if (! NT_SUCCESS(Status))
5201 {
5203 return FALSE;
5204 }
5205 if ( Size < sizeof(MENUINFO) || Size > sizeof(ROSMENUINFO) )
5206 {
5208 return FALSE;
5209 }
5210 Status = MmCopyFromCaller(&MenuInfo, UnsafeMenuInfo, Size);
5211 if (! NT_SUCCESS(Status))
5212 {
5214 return FALSE;
5215 }
5216
5217 if(SetOrGet)
5218 {
5219 /* Set MenuInfo */
5220 Res = IntSetMenuInfo(Menu, &MenuInfo);
5221 }
5222 else
5223 {
5224 /* Get MenuInfo */
5225 Res = IntGetMenuInfo(Menu, &MenuInfo);
5226 if (Res)
5227 {
5228 Status = MmCopyToCaller(UnsafeMenuInfo, &MenuInfo, Size);
5229 if (! NT_SUCCESS(Status))
5230 {
5232 return FALSE;
5233 }
5234 }
5235 }
5236
5237 return Res;
5238}
5239
5242 PWND pWnd,
5243 PMENU Menu,
5244 UINT uItem,
5245 PRECTL Rect)
5246{
5247 LONG XMove, YMove;
5248 PITEM MenuItem;
5249 UINT I = uItem;
5250
5251 if ((MenuItem = MENU_FindItem (&Menu, &I, MF_BYPOSITION)))
5252 {
5253 Rect->left = MenuItem->xItem;
5254 Rect->top = MenuItem->yItem;
5255 Rect->right = MenuItem->cxItem; // Do this for now......
5256 Rect->bottom = MenuItem->cyItem;
5257 }
5258 else
5259 {
5260 ERR("Failed Item Lookup! %u\n", uItem);
5261 return FALSE;
5262 }
5263
5264 if (!pWnd)
5265 {
5266 HWND hWnd = Menu->hWnd;
5267 if (!(pWnd = UserGetWindowObject(hWnd))) return FALSE;
5268 }
5269
5270 if (Menu->fFlags & MNF_POPUP)
5271 {
5272 XMove = pWnd->rcClient.left;
5273 YMove = pWnd->rcClient.top;
5274 }
5275 else
5276 {
5277 XMove = pWnd->rcWindow.left;
5278 YMove = pWnd->rcWindow.top;
5279 }
5280
5281 Rect->left += XMove;
5282 Rect->top += YMove;
5283 Rect->right += XMove;
5284 Rect->bottom += YMove;
5285
5286 return TRUE;
5287}
5288
5290{
5291 PMENU Menu, NewMenu = NULL, SysMenu = NULL;
5292 HMENU hSysMenu, hNewMenu = NULL;
5293 ROSMENUITEMINFO ItemInfoSet = {0};
5294 ROSMENUITEMINFO ItemInfo = {0};
5295 UNICODE_STRING MenuName;
5296
5297 hSysMenu = UserCreateMenu(Window->head.rpdesk, FALSE);
5298 if (NULL == hSysMenu)
5299 {
5300 return NULL;
5301 }
5302 SysMenu = UserGetMenuObject(hSysMenu);
5303 if (NULL == SysMenu)
5304 {
5305 UserDestroyMenu(hSysMenu);
5306 return NULL;
5307 }
5308
5309 SysMenu->fFlags |= MNF_SYSMENU;
5310 SysMenu->hWnd = UserHMGetHandle(Window);
5311
5312 if (!Popup)
5313 {
5314 //hNewMenu = co_IntLoadSysMenuTemplate();
5315 if ( Window->ExStyle & WS_EX_MDICHILD )
5316 {
5317 RtlInitUnicodeString( &MenuName, L"SYSMENUMDI");
5318 hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
5319 }
5320 else
5321 {
5322 RtlInitUnicodeString( &MenuName, L"SYSMENU");
5323 hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
5324 //ERR("%wZ\n",&MenuName);
5325 }
5326 if (!hNewMenu)
5327 {
5328 ERR("No Menu!!\n");
5329 IntDestroyMenuObject(SysMenu, FALSE);
5330 return NULL;
5331 }
5332 Menu = UserGetMenuObject(hNewMenu);
5333 if (!Menu)
5334 {
5335 IntDestroyMenuObject(SysMenu, FALSE);
5336 return NULL;
5337 }
5338
5339 // Do the rest in here.
5340
5342
5343 ItemInfoSet.cbSize = sizeof( MENUITEMINFOW);
5344 ItemInfoSet.fMask = MIIM_BITMAP;
5345 ItemInfoSet.hbmpItem = HBMMENU_POPUP_CLOSE;
5346 IntMenuItemInfo(Menu, SC_CLOSE, FALSE, &ItemInfoSet, TRUE, NULL);
5347 ItemInfoSet.hbmpItem = HBMMENU_POPUP_RESTORE;
5348 IntMenuItemInfo(Menu, SC_RESTORE, FALSE, &ItemInfoSet, TRUE, NULL);
5349 ItemInfoSet.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
5350 IntMenuItemInfo(Menu, SC_MAXIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
5351 ItemInfoSet.hbmpItem = HBMMENU_POPUP_MINIMIZE;
5352 IntMenuItemInfo(Menu, SC_MINIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
5353
5354 NewMenu = IntCloneMenu(Menu);
5355 if (NewMenu == NULL)
5356 {
5358 IntDestroyMenuObject(SysMenu, FALSE);
5359 return NULL;
5360 }
5361
5362 IntReleaseMenuObject(NewMenu);
5364
5366 }
5367 else
5368 {
5369 NewMenu = Popup;
5370 }
5371 if (NewMenu)
5372 {
5373 NewMenu->fFlags |= MNF_SYSMENU | MNF_POPUP;
5374
5375 if (Window->pcls->style & CS_NOCLOSE)
5377
5378 ItemInfo.cbSize = sizeof(MENUITEMINFOW);
5380 ItemInfo.fType = MF_POPUP;
5381 ItemInfo.fState = MFS_ENABLED;
5382 ItemInfo.dwTypeData = NULL;
5383 ItemInfo.cch = 0;
5384 ItemInfo.hSubMenu = UserHMGetHandle(NewMenu);
5385 IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo, NULL);
5386
5387 return SysMenu;
5388 }
5389 ERR("failed to load system menu!\n");
5390 return NULL;
5391}
5392
5395{
5396 PMENU Menu;
5397
5398 if (bRevert)
5399 {
5400 if (Window->SystemMenu)
5401 {
5402 Menu = UserGetMenuObject(Window->SystemMenu);
5403 if (Menu && !(Menu->fFlags & MNF_SYSDESKMN))
5404 {
5406 Window->SystemMenu = NULL;
5407 }
5408 }
5409 }
5410 else
5411 {
5412 Menu = Window->SystemMenu ? UserGetMenuObject(Window->SystemMenu) : NULL;
5413 if ((!Menu || Menu->fFlags & MNF_SYSDESKMN) && Window->style & WS_SYSMENU)
5414 {
5416 Window->SystemMenu = Menu ? UserHMGetHandle(Menu) : NULL;
5417 }
5418 }
5419
5420 if (Window->SystemMenu)
5421 {
5422 HMENU hMenu = IntGetSubMenu( Window->SystemMenu, 0);
5423 /* Store the dummy sysmenu handle to facilitate the refresh */
5424 /* of the close button if the SC_CLOSE item change */
5425 Menu = UserGetMenuObject(hMenu);
5426 if (Menu)
5427 {
5428 Menu->spwndNotify = Window;
5429 Menu->fFlags |= MNF_SYSSUBMENU;
5430 }
5431 return Menu;
5432 }
5433 return NULL;
5434}
5435
5438{
5439 PMENU OldMenu;
5440
5441 if (!(Window->style & WS_SYSMENU)) return FALSE;
5442
5443 if (Window->SystemMenu)
5444 {
5445 OldMenu = UserGetMenuObject(Window->SystemMenu);
5446 if (OldMenu)
5447 {
5448 OldMenu->fFlags &= ~MNF_SYSMENU;
5449 IntDestroyMenuObject(OldMenu, TRUE);
5450 }
5451 }
5452
5453 OldMenu = MENU_GetSystemMenu(Window, Menu);
5454 if (OldMenu)
5455 { // Use spmenuSys too!
5456 Window->SystemMenu = UserHMGetHandle(OldMenu);
5457 }
5458 else
5459 Window->SystemMenu = NULL;
5460
5461 if (Menu && Window != Menu->spwndNotify)
5462 {
5463 Menu->spwndNotify = Window;
5464 }
5465
5466 return TRUE;
5467}
5468
5471 PWND Wnd,
5472 HMENU Menu,
5473 BOOL *Changed)
5474{
5475 PMENU OldMenu, NewMenu = NULL;
5476
5477 if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
5478 {
5479 ERR("SetMenu: Window is a Child 0x%p!\n",UserHMGetHandle(Wnd));
5481 return FALSE;
5482 }
5483
5484 *Changed = (UlongToHandle(Wnd->IDMenu) != Menu);
5485 if (! *Changed)
5486 {
5487 return TRUE;
5488 }
5489
5490 if (Wnd->IDMenu)
5491 {
5492 OldMenu = IntGetMenuObject(UlongToHandle(Wnd->IDMenu));
5493 ASSERT(NULL == OldMenu || OldMenu->hWnd == UserHMGetHandle(Wnd));
5494 }
5495 else
5496 {
5497 OldMenu = NULL;
5498 }
5499
5500 if (NULL != Menu)
5501 {
5502 NewMenu = IntGetMenuObject(Menu);
5503 if (NULL == NewMenu)
5504 {
5505 if (NULL != OldMenu)
5506 {
5507 IntReleaseMenuObject(OldMenu);
5508 }
5510 return FALSE;
5511 }
5512 if (NULL != NewMenu->hWnd)
5513 {
5514 /* Can't use the same menu for two windows */
5515 if (NULL != OldMenu)
5516 {
5517 IntReleaseMenuObject(OldMenu);
5518 }
5520 return FALSE;
5521 }
5522
5523 }
5524
5525 Wnd->IDMenu = (UINT_PTR) Menu;
5526 if (NULL != NewMenu)
5527 {
5528 NewMenu->hWnd = UserHMGetHandle(Wnd);
5529 IntReleaseMenuObject(NewMenu);
5530 }
5531 if (NULL != OldMenu)
5532 {
5533 OldMenu->hWnd = NULL;
5534 IntReleaseMenuObject(OldMenu);
5535 }
5536
5537 return TRUE;
5538}
5539
5540
5541/* FUNCTIONS *****************************************************************/
5542
5543/*
5544 * @implemented
5545 */
5546/* http://www.cyber-ta.org/releases/malware-analysis/public/SOURCES/b47155634ccb2c30630da7e3666d3d07/b47155634ccb2c30630da7e3666d3d07.trace.html#NtUserGetIconSize */
5547DWORD
5550 HWND hwnd,
5551 DWORD leftBorder,
5552 DWORD rightBorder,
5553 DWORD top,
5554 LPRECT prc )
5555{
5556 HDC hdc;
5557 PWND Window;
5558 RECT Rect;
5559 DWORD ret;
5560
5562
5564 {
5566 UserLeave();
5567 return 0;
5568 }
5569
5571 if (!hdc)
5572 {
5573 UserLeave();
5574 return 0;
5575 }
5576
5577 Rect.left = leftBorder;
5578 Rect.right = Window->rcWindow.right - Window->rcWindow.left - rightBorder;
5579 Rect.top = top;
5580 Rect.bottom = 0;
5581
5583
5584 UserReleaseDC( 0, hdc, FALSE );
5585
5586 UserLeave();
5587
5588 return ret;
5589}
5590
5591/*
5592 * @implemented
5593 */
5596 HMENU hMenu,
5597 UINT uIDCheckItem,
5598 UINT uCheck)
5599{
5600 PMENU Menu;
5601 DWORD Ret = (DWORD)-1;
5602
5603 TRACE("Enter NtUserCheckMenuItem\n");
5605
5606 Menu = UserGetMenuObject(hMenu);
5607 if (Menu)
5608 {
5609 Ret = IntCheckMenuItem(Menu, uIDCheckItem, uCheck);
5610 }
5611
5612 TRACE("Leave NtUserCheckMenuItem, ret=%lu\n", Ret);
5613 UserLeave();
5614 return Ret;
5615}
5616
5617/*
5618 * @implemented
5619 */
5622 HMENU hMenu,
5623 UINT uPosition,
5624 UINT uFlags)
5625{
5626 PMENU Menu;
5627 BOOL Ret = FALSE;
5628
5629 TRACE("Enter NtUserDeleteMenu\n");
5631
5632 Menu = UserGetMenuObject(hMenu);
5633 if (Menu)
5634 {
5635 Ret = IntRemoveMenuItem(Menu, uPosition, uFlags, TRUE);
5636 }
5637
5638 TRACE("Leave NtUserDeleteMenu, ret=%i\n", Ret);
5639 UserLeave();
5640 return Ret;
5641}
5642
5643/*
5644 * NtUserGetSystemMenu
5645 *
5646 * The NtUserGetSystemMenu function allows the application to access the
5647 * window menu (also known as the system menu or the control menu) for
5648 * copying and modifying.
5649 *
5650 * Parameters
5651 * hWnd
5652 * Handle to the window that will own a copy of the window menu.
5653 * bRevert
5654 * Specifies the action to be taken. If this parameter is FALSE,
5655 * NtUserGetSystemMenu returns a handle to the copy of the window menu
5656 * currently in use. The copy is initially identical to the window menu
5657 * but it can be modified.
5658 * If this parameter is TRUE, GetSystemMenu resets the window menu back
5659 * to the default state. The previous window menu, if any, is destroyed.
5660 *
5661 * Return Value
5662 * If the bRevert parameter is FALSE, the return value is a handle to a
5663 * copy of the window menu. If the bRevert parameter is TRUE, the return
5664 * value is NULL.
5665 *
5666 * Status
5667 * @implemented
5668 */
5669
5672{
5673 PWND Window;
5674 PMENU Menu;
5675 HMENU Ret = NULL;
5676
5677 TRACE("Enter NtUserGetSystemMenu\n");
5679
5681 {
5682 goto Exit; // Return NULL
5683 }
5684
5685 if (!(Menu = IntGetSystemMenu(Window, bRevert)))
5686 {
5687 goto Exit; // Return NULL
5688 }
5689
5690 Ret = UserHMGetHandle(Menu);
5691
5692Exit:
5693 TRACE("Leave NtUserGetSystemMenu, ret=%p\n", Ret);
5694 UserLeave();
5695 return Ret;
5696}
5697
5698/*
5699 * NtUserSetSystemMenu
5700 *
5701 * Status
5702 * @implemented
5703 */
5704
5707{
5708 BOOL Result = FALSE;
5709 PWND Window;
5710 PMENU Menu;
5711
5712 TRACE("Enter NtUserSetSystemMenu\n");
5714
5716 {
5717 goto Exit; // Return FALSE
5718 }
5719
5720 if (hMenu)
5721 {
5722 /*
5723 * Assign new menu handle and Up the Lock Count.
5724 */
5725 if (!(Menu = IntGetMenuObject(hMenu)))
5726 {
5727 goto Exit; // Return FALSE
5728 }
5729
5731 }
5732 else
5734
5735Exit:
5736 TRACE("Leave NtUserSetSystemMenu, ret=%i\n", Result);
5737 UserLeave();
5738 return Result;
5739}
5740
5741/*
5742 * @implemented
5743 */
5746 HWND hwnd,
5747 PTITLEBARINFO bti)
5748{
5749 PWND WindowObject;
5750 TITLEBARINFO bartitleinfo;
5751 BOOLEAN retValue = TRUE;
5752
5753 TRACE("Enter NtUserGetTitleBarInfo\n");
5755
5756 /* Vaildate the windows handle */
5757 if (!(WindowObject = UserGetWindowObject(hwnd)))
5758 {
5760 retValue = FALSE;
5761 }
5762
5763 _SEH2_TRY
5764 {
5765 /* Copy our usermode buffer bti to local buffer bartitleinfo */
5766 ProbeForRead(bti, sizeof(TITLEBARINFO), 1);
5767 RtlCopyMemory(&bartitleinfo, bti, sizeof(TITLEBARINFO));
5768 }
5770 {
5771 /* Fail copy the data */
5773 retValue = FALSE;
5774 }
5775 _SEH2_END
5776
5777 /* Get the tile bar info */
5778 if (retValue)
5779 {
5780 retValue = intGetTitleBarInfo(WindowObject, &bartitleinfo);
5781 if (retValue)
5782 {
5783 _SEH2_TRY
5784 {
5785 /* Copy our buffer to user mode buffer bti */
5786 ProbeForWrite(bti, sizeof(TITLEBARINFO), 1);
5787 RtlCopyMemory(bti, &bartitleinfo, sizeof(TITLEBARINFO));
5788 }
5790 {
5791 /* Fail copy the data */
5793 retValue = FALSE;
5794 }
5795 _SEH2_END
5796 }
5797 }
5798
5799 TRACE("Leave NtUserGetTitleBarInfo, ret=%u\n", retValue);
5800 UserLeave();
5801 return retValue;
5802}
5803
5804/*
5805 * @implemented
5806 */
5808{
5809 PMENU Menu;
5811
5812 if(!(Menu = UserGetMenuObject(hMenu)))
5813 {
5814 return FALSE;
5815 }
5816
5817 if (Menu->head.rpdesk != pti->rpdesk)
5818 {
5820 return FALSE;
5821 }
5822 return IntDestroyMenuObject(Menu, FALSE);
5823}
5824
5825/*
5826 * @implemented
5827 */
5830 HMENU hMenu)
5831{
5832 PMENU Menu;
5833 BOOL Ret = FALSE;
5834
5835 TRACE("Enter NtUserDestroyMenu\n");
5837
5838 if(!(Menu = UserGetMenuObject(hMenu)))
5839 {
5840 goto Exit; // Return FALSE
5841 }
5842 if (Menu->head.rpdesk != gptiCurrent->rpdesk)
5843 {
5845 goto Exit; // Return FALSE
5846 }
5847 Ret = IntDestroyMenuObject(Menu, TRUE);
5848
5849Exit:
5850 TRACE("Leave NtUserDestroyMenu, ret=%i\n", Ret);
5851 UserLeave();
5852 return Ret;
5853}
5854
5855/*
5856 * @implemented
5857 */
5860 HMENU hMenu,
5861 UINT uIDEnableItem,
5862 UINT uEnable)
5863{
5864 PMENU Menu;
5865 UINT Ret = (UINT)-1;
5866
5867 TRACE("Enter NtUserEnableMenuItem\n");
5869
5870 Menu = UserGetMenuObject(hMenu);
5871 if (Menu)
5872 {
5873 Ret = IntEnableMenuItem(Menu, uIDEnableItem, uEnable);
5874 }
5875
5876 TRACE("Leave NtUserEnableMenuItem, ret=%u\n", Ret);
5877 UserLeave();
5878 return Ret;
5879}
5880
5881/*
5882 * @implemented
5883 */
5886{
5887 //PWND pWnd;
5888 TRACE("Enter NtUserEndMenu\n");
5890 /* if ( gptiCurrent->pMenuState &&
5891 gptiCurrent->pMenuState->pGlobalPopupMenu )
5892 {
5893 pWnd = IntGetMSWND(gptiCurrent->pMenuState);
5894 if (pWnd)
5895 {
5896 UserPostMessage( UserHMGetHandle(pWnd), WM_CANCELMODE, 0, 0);
5897 }
5898 else
5899 gptiCurrent->pMenuState->fInsideMenuLoop = FALSE;
5900 }*/
5902 {
5905 }
5906 UserLeave();
5907 TRACE("Leave NtUserEndMenu\n");
5908 return TRUE;
5909}
5910
5911/*
5912 * @implemented
5913 */
5916 HWND hwnd,
5917 LONG idObject,
5918 LONG idItem,
5919 PMENUBARINFO pmbi)
5920{
5921 PWND pWnd;
5922 HMENU hMenu;
5923 MENUBARINFO kmbi;
5924 BOOL Ret = FALSE;
5925 PPOPUPMENU pPopupMenu;
5928 PMENU Menu = NULL;
5929
5930 TRACE("Enter NtUserGetMenuBarInfo\n");
5932
5933 if (!(pWnd = UserGetWindowObject(hwnd)))
5934 {
5936 goto Cleanup; // Return FALSE
5937 }
5938
5939 UserRefObjectCo(pWnd, &Ref);
5940
5942 kmbi.hMenu = NULL;
5943 kmbi.hwndMenu = NULL;
5944 kmbi.fBarFocused = FALSE;
5945 kmbi.fFocused = FALSE;
5946
5947 switch (idObject)
5948 {
5949 case OBJID_CLIENT:
5950 if (!pWnd->pcls->fnid)
5951 goto Cleanup; // Return FALSE
5952 if (pWnd->pcls->fnid != FNID_MENU)
5953 {
5954 WARN("called on invalid window: %u\n", pWnd->pcls->fnid);
5956 goto Cleanup; // Return FALSE
5957 }
5958 // Windows does this! Wine checks for Atom and uses GetWindowLongPtrW.
5959 hMenu = (HMENU)co_IntSendMessage(hwnd, MN_GETHMENU, 0, 0);
5960 pPopupMenu = ((PMENUWND)pWnd)->ppopupmenu;
5961 if (pPopupMenu && pPopupMenu->spmenu)
5962 {
5963 if (UserHMGetHandle(pPopupMenu->spmenu) != hMenu)
5964 {
5965 ERR("Window Pop Up hMenu %p not the same as Get hMenu %p!\n", UserHMGetHandle(pPopupMenu->spmenu), hMenu);
5966 }
5967 }
5968 break;
5969 case OBJID_MENU:
5970 if (pWnd->style & WS_CHILD)
5971 goto Cleanup; // Return FALSE
5972 hMenu = UlongToHandle(pWnd->IDMenu);
5973 TRACE("GMBI: OBJID_MENU hMenu %p\n",hMenu);
5974 break;
5975 case OBJID_SYSMENU:
5976 if (!(pWnd->style & WS_SYSMENU))
5977 goto Cleanup; // Return FALSE
5978 Menu = IntGetSystemMenu(pWnd, FALSE);
5979 hMenu = UserHMGetHandle(Menu);
5980 break;
5981 default:
5982 goto Cleanup; // Return FALSE
5983 }
5984
5985 if (!hMenu)
5986 goto Cleanup; // Return FALSE
5987
5988 _SEH2_TRY
5989 {
5990 ProbeForRead(pmbi, sizeof(MENUBARINFO), 1);
5991 kmbi.cbSize = pmbi->cbSize;
5992 }
5994 {
5995 kmbi.cbSize = 0;
5996 }
5997 _SEH2_END
5998
5999 if (kmbi.cbSize != sizeof(MENUBARINFO))
6000 {
6002 goto Cleanup; // Return FALSE
6003 }
6004
6005 if (!Menu)
6006 {
6007 Menu = UserGetMenuObject(hMenu);
6008 if (!Menu)
6009 goto Cleanup; // Return FALSE
6010 }
6011
6012 if ((idItem < 0) || ((ULONG)idItem > Menu->cItems))
6013 goto Cleanup; // Return FALSE
6014
6015 if (idItem == 0)
6016 {
6017 Ret = IntGetMenuItemRect(pWnd, Menu, 0, &kmbi.rcBar);
6018 kmbi.rcBar.right = kmbi.rcBar.left + Menu->cxMenu;
6019 kmbi.rcBar.bottom = kmbi.rcBar.top + Menu->cyMenu;
6020 TRACE("idItem a 0 %d\n",Ret);
6021 }
6022 else
6023 {
6024 Ret = IntGetMenuItemRect(pWnd, Menu, idItem-1, &kmbi.rcBar);
6025 TRACE("idItem b %d %d\n", idItem-1, Ret);
6026 }
6027
6028 kmbi.hMenu = hMenu;
6029 kmbi.fBarFocused = top_popup_hmenu == hMenu;
6030 TRACE("GMBI: top p hm %p hMenu %p\n",top_popup_hmenu, hMenu);
6031 if (idItem)
6032 {
6033 kmbi.fFocused = Menu->iItem == idItem-1;
6034 if (kmbi.fFocused && (Menu->rgItems[idItem - 1].spSubMenu))
6035 {
6036 kmbi.hwndMenu = Menu->rgItems[idItem - 1].spSubMenu->hWnd;
6037 }
6038 }
6039 else
6040 {
6041 kmbi.fFocused = kmbi.fBarFocused;
6042 }
6043
6044 _SEH2_TRY
6045 {
6046 ProbeForWrite(pmbi, sizeof(MENUBARINFO), 1);
6047 RtlCopyMemory(pmbi, &kmbi, sizeof(MENUBARINFO));
6048 }
6050 {
6052 }
6053 _SEH2_END
6054
6055 if (!NT_SUCCESS(Status))
6056 {
6058 Ret = FALSE;
6059 goto Cleanup;
6060 }
6061
6062 Ret = TRUE;
6063
6064Cleanup:
6065 if (pWnd) UserDerefObjectCo(pWnd);
6066 TRACE("Leave NtUserGetMenuBarInfo, ret=%i\n", Ret);
6067 UserLeave();
6068 return Ret;
6069}
6070
6071/*
6072 * @implemented
6073 */
6076 HMENU hMenu,
6077 HMENU hSubMenu)
6078{
6079 PMENU Menu, SubMenu;
6080 PITEM MenuItem;
6081 UINT i;
6082 UINT Ret = 0xFFFFFFFF;
6083
6084 TRACE("Enter NtUserGetMenuIndex\n");
6086
6087 if ( !(Menu = UserGetMenuObject(hMenu)) ||
6088 !(SubMenu = UserGetMenuObject(hSubMenu)) )
6089 goto Exit; // Return 0xFFFFFFFF
6090
6091 MenuItem = Menu->rgItems;
6092 for (i = 0; i < Menu->cItems; i++, MenuItem++)
6093 {
6094 if (MenuItem->spSubMenu == SubMenu)
6095 {
6096 Ret = MenuItem->wID;
6097 break;
6098 }
6099 }
6100
6101Exit:
6102 TRACE("Leave NtUserGetMenuIndex, ret=%u\n", Ret);
6103 UserLeave();
6104 return Ret;
6105}
6106
6107/*
6108 * @implemented
6109 */
6112 HWND hWnd,
6113 HMENU hMenu,
6114 UINT uItem,
6115 PRECTL lprcItem)
6116{
6117 PWND ReferenceWnd;
6118 LONG XMove, YMove;
6119 RECTL Rect;
6120 PMENU Menu;
6121 PITEM MenuItem;
6123 BOOL Ret = FALSE;
6124
6125 TRACE("Enter NtUserGetMenuItemRect\n");
6127
6128 if (!(Menu = UserGetMenuObject(hMenu)))
6129 {
6130 goto Exit; // Return FALSE
6131 }
6132
6133 if ((MenuItem = MENU_FindItem (&Menu, &uItem, MF_BYPOSITION)))
6134 {
6135 Rect.left = MenuItem->xItem;
6136 Rect.top = MenuItem->yItem;
6137 Rect.right = MenuItem->cxItem; // Do this for now......
6138 Rect.bottom = MenuItem->cyItem;
6139 }
6140 else
6141 goto Exit; // Return FALSE
6142
6143 if(!hWnd)
6144 {
6145 hWnd = Menu->hWnd;
6146 }
6147
6148 if (lprcItem == NULL)
6149 goto Exit; // Return FALSE
6150
6151 if (!(ReferenceWnd = UserGetWindowObject(hWnd)))
6152 goto Exit; // Return FALSE
6153
6154 if (Menu->fFlags & MNF_POPUP)
6155 {
6156 XMove = ReferenceWnd->rcClient.left;
6157 YMove = ReferenceWnd->rcClient.top;
6158 }
6159 else
6160 {
6161 XMove = ReferenceWnd->rcWindow.left;
6162 YMove = ReferenceWnd->rcWindow.top;
6163 }
6164
6165 Rect.left += XMove;
6166 Rect.top += YMove;
6167 Rect.right += XMove;
6168 Rect.bottom += YMove;
6169
6170 _SEH2_TRY
6171 {
6172 RtlCopyMemory(lprcItem, &Rect, sizeof(RECTL));
6173 }
6175 {
6177 }
6178 _SEH2_END
6179
6180 if (!NT_SUCCESS(Status))
6181 {
6183 goto Exit; // Return FALSE
6184 }
6185 Ret = TRUE;
6186
6187Exit:
6188 TRACE("Leave NtUserGetMenuItemRect, ret=%i\n", Ret);
6189 UserLeave();
6190 return Ret;
6191}
6192
6193/*
6194 * @implemented
6195 */
6198 HWND hWnd,
6199 HMENU hMenu,
6200 UINT uItemHilite,
6201 UINT uHilite)
6202{
6203 PMENU Menu;
6204 PWND Window;
6205 BOOL Ret = FALSE;
6206
6207 TRACE("Enter NtUserHiliteMenuItem\n");
6209
6211 {
6213 goto Exit; // Return FALSE
6214 }
6215
6216 if(!(Menu = UserGetMenuObject(hMenu)))
6217 {
6219 goto Exit; // Return FALSE
6220 }
6221
6222 Ret = IntHiliteMenuItem(Window, Menu, uItemHilite, uHilite);
6223
6224Exit:
6225 TRACE("Leave NtUserHiliteMenuItem, ret=%i\n", Ret);
6226 UserLeave();
6227 return Ret;
6228}
6229
6230/*
6231 * @implemented
6232 */
6233DWORD
6236 HWND hWnd,
6237 HDC hDC,
6238 PRECT pRect,
6239 HMENU hMenu,
6240 HFONT hFont)
6241{
6242 PMENU Menu;
6243 PWND Window;
6244 RECT Rect;
6246 DWORD Ret = 0;
6247
6248 ERR("Enter NtUserDrawMenuBarTemp\n");
6250
6252 {
6254 goto Exit; // Return 0
6255 }
6256
6257 if(!(Menu = UserGetMenuObject(hMenu)))
6258 {
6260 goto Exit; // Return 0
6261 }
6262
6263 _SEH2_TRY
6264 {
6265 ProbeForRead(pRect, sizeof(RECT), sizeof(ULONG));
6266 RtlCopyMemory(&Rect, pRect, sizeof(RECT));
6267 }
6269 {
6271 }
6272 _SEH2_END;
6273
6274 if (Status != STATUS_SUCCESS)
6275 {
6277 goto Exit; // Return 0
6278 }
6279
6280 Ret = IntDrawMenuBarTemp(Window, hDC, &Rect, Menu, hFont);
6281
6282Exit:
6283 ERR("Leave NtUserDrawMenuBarTemp, ret=%lu\n", Ret);
6284 UserLeave();
6285 return Ret;
6286}
6287
6288/*
6289 * @implemented
6290 */
6291int APIENTRY
6293 HWND hWnd,
6294 HMENU hMenu,
6295 DWORD X,
6296 DWORD Y)
6297{
6298 PMENU Menu;
6299 PWND Window = NULL;
6300 PITEM mi;
6301 ULONG i;
6302 int Ret = -1;
6303
6304 TRACE("Enter NtUserMenuItemFromPoint\n");
6306
6307 if (!(Menu = UserGetMenuObject(hMenu)))
6308 {
6309 goto Exit; // Return -1
6310 }
6311
6312 if (!(Window = UserGetWindowObject(Menu->hWnd)))
6313 {
6314 goto Exit; // Return -1
6315 }
6316
6317 X -= Window->rcWindow.left;
6318 Y -= Window->rcWindow.top;
6319
6320 mi = Menu->rgItems;
6321 for (i = 0; i < Menu->cItems; i++, mi++)
6322 {
6323 RECTL Rect;
6324
6325 Rect.left = mi->xItem;
6326 Rect.top = mi->yItem;
6327 Rect.right = mi->cxItem;
6328 Rect.bottom = mi->cyItem;
6329
6331
6332 if (RECTL_bPointInRect(&Rect, X, Y))
6333 {
6334 break;
6335 }
6336 }
6337
6338 Ret = (mi ? i : NO_SELECTED_ITEM);
6339
6340Exit:
6341 TRACE("Leave NtUserMenuItemFromPoint, ret=%i\n", Ret);
6342 UserLeave();
6343 return Ret;
6344}
6345
6346
6347DWORD
6350 HWND hWnd,
6351 HDC hDC,
6352 ULONG leftBorder,
6353 ULONG rightBorder,
6354 ULONG top,
6355 BOOL bActive)
6356{
6357 PWND Window;
6358 RECT Rect;
6359 DWORD ret;
6360
6362
6364 {
6366 UserLeave();
6367 return 0;
6368 }
6369
6370 Rect.left = leftBorder;
6371 Rect.right = Window->rcWindow.right - Window->rcWindow.left - rightBorder;
6372 Rect.top = top;
6373 Rect.bottom = 0;
6374
6376
6377 UserLeave();
6378
6379 return ret;
6380}
6381
6382/*
6383 * @implemented
6384 */
6387 HMENU hMenu,
6388 UINT uPosition,
6389 UINT uFlags)
6390{
6391 PMENU Menu;
6392 BOOL Ret = FALSE;
6393
6394 TRACE("Enter NtUserRemoveMenu\n");
6396
6397 Menu = UserGetMenuObject(hMenu);
6398 if (Menu)
6399 {
6400 Ret = IntRemoveMenuItem(Menu, uPosition, uFlags, FALSE);
6401 }
6402
6403 TRACE("Leave NtUserRemoveMenu, ret=%i\n", Ret);
6404 UserLeave();
6405 return Ret;
6406}
6407
6408/*
6409 * @implemented
6410 */
6413 HWND hWnd,
6414 HMENU Menu,
6415 BOOL Repaint)
6416{
6417 PWND Window;
6418 BOOL Changed;
6419 BOOL Ret = FALSE;
6420
6421 TRACE("Enter NtUserSetMenu\n");
6423
6425 {
6426 goto Exit; // Return FALSE
6427 }
6428
6429 if (!IntSetMenu(Window, Menu, &Changed))
6430 {
6431 goto Exit; // Return FALSE
6432 }
6433
6434 // Not minimized and please repaint!!!
6435 if (!(Window->style & WS_MINIMIZE) && (Repaint || Changed))
6436 {
6438 UserRefObjectCo(Window, &Ref);
6441 }
6442
6443 Ret = TRUE;
6444
6445Exit:
6446 TRACE("Leave NtUserSetMenu, ret=%i\n", Ret);
6447 UserLeave();
6448 return Ret;
6449}
6450
6451/*
6452 * @implemented
6453 */
6456 HMENU hMenu,
6457 DWORD dwContextHelpId)
6458{
6459 PMENU Menu;
6460 BOOL Ret = FALSE;
6461
6462 TRACE("Enter NtUserSetMenuContextHelpId\n");
6464
6465 Menu = UserGetMenuObject(hMenu);
6466 if (Menu)
6467 {
6468 Ret = IntSetMenuContextHelpId(Menu, dwContextHelpId);
6469 }
6470
6471 TRACE("Leave NtUserSetMenuContextHelpId, ret=%i\n", Ret);
6472 UserLeave();
6473 return Ret;
6474}
6475
6476/*
6477 * @implemented
6478 */
6481 HMENU hMenu,
6482 UINT uItem,
6483 UINT fByPos)
6484{
6485 PMENU Menu;
6486 BOOL Ret = FALSE;
6487
6488 TRACE("Enter NtUserSetMenuDefaultItem\n");
6490
6491 Menu = UserGetMenuObject(hMenu);
6492 if (Menu)
6493 {
6494 Ret = UserSetMenuDefaultItem(Menu, uItem, fByPos);
6495 }
6496
6497 TRACE("Leave NtUserSetMenuDefaultItem, ret=%i\n", Ret);
6498 UserLeave();
6499 return Ret;
6500}
6501
6502/*
6503 * @implemented
6504 */
6507 HMENU hMenu)
6508{
6509 PMENU Menu;
6510 BOOL Ret = FALSE;
6511
6512 TRACE("Enter NtUserSetMenuFlagRtoL\n");
6514
6515 Menu = UserGetMenuObject(hMenu);
6516 if (Menu)
6517 {
6518 Ret = IntSetMenuFlagRtoL(Menu);
6519 }
6520
6521 TRACE("Leave NtUserSetMenuFlagRtoL, ret=%i\n", Ret);
6522 UserLeave();
6523 return Ret;
6524}
6525
6526/*
6527 * @implemented
6528 */
6531 HMENU hMenu,
6532 LPCMENUINFO lpcmi)
6533{
6534 PMENU Menu;
6535 BOOL Ret = FALSE;
6536
6537 TRACE("Enter NtUserThunkedMenuInfo\n");
6539
6540 Menu = UserGetMenuObject(hMenu);
6541 if (Menu)
6542 {
6543 Ret = UserMenuInfo(Menu, (PROSMENUINFO)lpcmi, TRUE);
6544 }
6545
6546 TRACE("Leave NtUserThunkedMenuInfo, ret=%i\n", Ret);
6547 UserLeave();
6548 return Ret;
6549}
6550
6551/*
6552 * @implemented
6553 */
6556 HMENU hMenu,
6557 UINT uItem,
6558 BOOL fByPosition,
6559 BOOL bInsert,
6560 LPMENUITEMINFOW lpmii,
6561 PUNICODE_STRING lpszCaption)
6562{
6563 PMENU Menu;
6565 UNICODE_STRING lstrCaption;
6566 BOOL Ret = FALSE;
6567
6568 TRACE("Enter NtUserThunkedMenuItemInfo\n");
6570
6571 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
6572 if bInsert == TRUE call UserInsertMenuItem() else UserSetMenuItemInfo() */
6573
6574 RtlInitEmptyUnicodeString(&lstrCaption, NULL, 0);
6575
6576 if (!(Menu = UserGetMenuObject(hMenu)))
6577 {
6578 goto Cleanup; // Return FALSE
6579 }
6580
6581 /* Check if we got a Caption */
6582 if (lpszCaption && lpszCaption->Buffer)
6583 {
6584 /* Copy the string to kernel mode */
6585 Status = ProbeAndCaptureUnicodeString( &lstrCaption,
6586 UserMode,
6587 lpszCaption);
6588 if (!NT_SUCCESS(Status))
6589 {
6590 ERR("Failed to capture MenuItem Caption (status 0x%08x)\n",Status);
6592 goto Cleanup; // Return FALSE
6593 }
6594 }
6595
6596 if (bInsert)
6597 {
6598 Ret = UserInsertMenuItem(Menu, uItem, fByPosition, lpmii, &lstrCaption);
6599 goto Cleanup;
6600 }
6601
6602 Ret = UserMenuItemInfo(Menu, uItem, fByPosition, (PROSMENUITEMINFO)lpmii, TRUE, &lstrCaption);
6603
6604Cleanup:
6605 if (lstrCaption.Buffer)
6606 {
6608 }
6609
6610 TRACE("Leave NtUserThunkedMenuItemInfo, ret=%i\n", Ret);
6611 UserLeave();
6612 return Ret;
6613}
6614
6615/*
6616 * @implemented
6617 */
6620 HMENU hMenu,
6621 UINT fuFlags,
6622 int x,
6623 int y,
6624 HWND hWnd,
6625 LPTPMPARAMS lptpm)
6626{
6627 PMENU menu;
6628 PWND pWnd;
6629 TPMPARAMS tpm;
6630 BOOL Ret = FALSE;
6632
6633 TRACE("Enter NtUserTrackPopupMenuEx\n");
6635 /* Parameter check */
6636 if (!(menu = UserGetMenuObject( hMenu )))
6637 {
6638 ERR("TPME : Invalid Menu handle.\n");
6640 goto Exit;
6641 }
6642
6643 if (!(pWnd = UserGetWindowObject(hWnd)))
6644 {
6645 ERR("TPME : Invalid Window handle.\n");
6646 goto Exit;
6647 }
6648
6649 if (lptpm)
6650 {
6651 _SEH2_TRY
6652 {
6653 ProbeForRead(lptpm, sizeof(TPMPARAMS), sizeof(ULONG));
6654 tpm = *lptpm;
6655 }
6657 {
6658 _SEH2_YIELD(goto Exit);
6659 }
6660 _SEH2_END
6661 }
6662 UserRefObjectCo(pWnd, &Ref);
6663 Ret = IntTrackPopupMenuEx(menu, fuFlags, x, y, pWnd, lptpm ? &tpm : NULL);
6664 UserDerefObjectCo(pWnd);
6665
6666Exit:
6667 TRACE("Leave NtUserTrackPopupMenuEx, ret=%i\n",Ret);
6668 UserLeave();
6669 return Ret;
6670}
6671
6672/* EOF */
static HDC hDC
Definition: 3dtext.c:33
CDumExe dum
Definition: CComObject.cpp:71
DWORD Id
#define DCX_USESTYLE
Definition: GetDCEx.c:10
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static const size_t npos
Definition: _string_npos.h:26
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
Arabic default style
Definition: afstyles.h:94
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
HFONT hFont
Definition: main.c:53
#define U(x)
Definition: wordpad.c:45
BOOL Error
Definition: chkdsk.c:66
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define FIXME(fmt,...)
Definition: debug.h:114
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
HBRUSH APIENTRY IntGdiCreateSolidBrush(COLORREF crColor)
Definition: brush.cpp:290
static BOOL bInsert
Definition: cmdinput.c:121
WPARAM wParam
Definition: combotst.c:138
char * Text
Definition: combotst.c:136
LPARAM lParam
Definition: combotst.c:139
#define WM_SYSTIMER
Definition: comctl32.h:119
PEPROCESS gpepCSRSS
Definition: csr.c:15
COLORREF FASTCALL IntGdiSetBkColor(_In_ HDC hDC, _In_ COLORREF Color)
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL)
Definition: dclife.c:892
COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color)
Definition: dcutil.c:172
COLORREF FASTCALL IntSetDCPenColor(HDC, COLORREF)
Definition: dcutil.c:259
COLORREF FASTCALL GreGetBkColor(HDC)
Definition: dcutil.c:50
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode)
Definition: dcutil.c:124
int FASTCALL GreGetBkMode(HDC)
Definition: dcutil.c:35
COLORREF FASTCALL GreGetTextColor(HDC)
Definition: dcutil.c:80
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
ush Pos
Definition: deflate.h:92
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
@ Popup
Definition: console.h:35
#define APIENTRY
Definition: api.h:79
#define Y(I)
UINT uFlags
Definition: api.c:59
#define wcschr
Definition: compat.h:17
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
HANDLE HWND
Definition: compat.h:19
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
PSERVERINFO gpsi
Definition: imm.c:18
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
static const WCHAR Message[]
Definition: register.c:74
static const WCHAR Cleanup[]
Definition: register.c:80
#define pt(x, y)
Definition: drawing.c:79
#define RGB(r, g, b)
Definition: precomp.h:71
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
HWND FASTCALL co_UserSetCapture(HWND hWnd)
Definition: focus.c:1460
HWND APIENTRY IntGetCapture(VOID)
Definition: focus.c:1443
ULONG Handle
Definition: gdb_input.c:15
#define KeRosDumpStackFrames(Frames, Count)
Definition: gdidebug.h:11
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint color
Definition: glext.h:6243
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLfloat units
Definition: glext.h:11727
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLbyte ty
Definition: glext.h:8756
GLintptr offset
Definition: glext.h:5920
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
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
#define DbgPrint
Definition: hal.h:12
static const struct newhuff ht[]
Definition: huffman.h:296
#define cs
Definition: i386-dis.c:442
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _MENUWND * PMENUWND
#define MNF_SYSSUBMENU
Definition: ntuser.h:408
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:799
#define FNID_DESTROY
Definition: ntuser.h:898
#define MNF_POPUP
Definition: ntuser.h:402
#define WNDS_DESTROYED
Definition: ntuser.h:636
#define MNF_RTOL
Definition: ntuser.h:405
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct tagMENU MENU
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:805
@ OBI_UPARROW
Definition: ntuser.h:967
@ OBI_DNARROW
Definition: ntuser.h:969
@ OBI_MNARROW
Definition: ntuser.h:971
#define MNF_SYSMENU
Definition: ntuser.h:410
#define MFS_HBMMENUBMP
Definition: ntuser.h:368
#define MNF_SYSDESKMN
Definition: ntuser.h:407
#define MNF_INACTIVE
Definition: ntuser.h:404
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3584
@ TYPE_MENU
Definition: ntuser.h:42
#define FNID_MENU
Definition: ntuser.h:861
#define MNF_UNDERLINE
Definition: ntuser.h:403
#define NO_SELECTED_ITEM
Definition: ntuser.h:413
struct tagMENU * PMENU
HGDIOBJ FASTCALL IntGetSysColorBrush(INT Object)
Definition: stockobj.c:317
BOOL FASTCALL GreMoveTo(HDC hdc, INT x, INT y, LPPOINT pptOut)
Definition: line.c:108
DWORD FASTCALL IntGetSysColor(INT nIndex)
Definition: stockobj.c:323
#define I(s)
static real win[4][36]
if(dx< 0)
Definition: linetemp.h:194
#define IntReleaseMenuObject(MenuObj)
Definition: menu.h:130
#define MENU_ITEM_TYPE(flags)
Definition: menu.h:6
static const WCHAR dc[]
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define ASSERT(a)
Definition: mode.c:44
BITMAP bmp
Definition: alphablend.c:62
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
static LPCSTR lpstr
Definition: font.c:51
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
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
SIZE size
Definition: menu.c:78
LPCSTR text
Definition: menu.c:77
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
int other
Definition: msacm.c:1376
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2501
DWORD FASTCALL UserGetKeyState(DWORD dwKey)
Definition: msgqueue.c:221
#define QF_CAPTURELOCKED
Definition: msgqueue.h:111
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static int rop(int rop, int src, int dst)
Definition: nanoxwin.c:124
unsigned int UINT
Definition: ndis.h:50
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
#define UserMode
Definition: asm.h:35
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FASTCALL
Definition: nt_native.h:50
#define DWORD
Definition: nt_native.h:44
#define UNICODE_STRING_MAX_CHARS
BOOL FASTCALL GreSetViewportOrgEx(HDC hDC, int X, int Y, LPPOINT Point)
Definition: coord.c:915
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
_Out_ LPRECT prc
Definition: ntgdi.h:1658
__kernel_entry W32KAPI BOOL APIENTRY NtGdiBitBlt(_In_ HDC hdcDst, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD rop4, _In_ DWORD crBackColor, _In_ FLONG fl)
__kernel_entry W32KAPI HBRUSH APIENTRY NtGdiSelectBrush(_In_ HDC hdc, _In_ HBRUSH hbrush)
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetStockObject(_In_ INT iObject)
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiDeleteObjectApp(_In_ HANDLE hobj)
__kernel_entry W32KAPI HPEN APIENTRY NtGdiSelectPen(_In_ HDC hdc, _In_ HPEN hpen)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiLineTo(_In_ HDC hdc, _In_ INT x, _In_ INT y)
__kernel_entry W32KAPI HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
LRESULT FASTCALL IntDefWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: defwnd.c:535
BOOL UserPaintCaption(PWND pWnd, INT Flags)
Definition: defwnd.c:398
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:16
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1786
BOOL FASTCALL IntGetWindowRect(PWND Wnd, RECTL *Rect)
Definition: winpos.c:121
BOOL FASTCALL IntScreenToClient(PWND Wnd, LPPOINT lpPoint)
Definition: winpos.c:213
HWND hwndSAS
Definition: winsta.c:24
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:232
HINSTANCE hModClient
Definition: ntuser.c:25
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:235
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:224
#define L(x)
Definition: ntvdm.h:50
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define WS_CAPTION
Definition: pedump.c:624
#define WS_ICONIC
Definition: pedump.c:641
#define WS_MAXIMIZEBOX
Definition: pedump.c:632
#define WS_EX_DLGMODALFRAME
Definition: pedump.c:645
#define WS_MAXIMIZE
Definition: pedump.c:623
#define WS_SYSMENU
Definition: pedump.c:629
#define WS_BORDER
Definition: pedump.c:625
#define WS_POPUP
Definition: pedump.c:616
#define WS_MINIMIZE
Definition: pedump.c:622
DWORD * PDWORD
Definition: pedump.c:68
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
unsigned short USHORT
Definition: pedump.c:61
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define WS_THICKFRAME
Definition: pedump.c:630
#define MmCopyFromCaller
Definition: polytest.cpp:29
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define WM_PRINTCLIENT
Definition: richedit.h:70
BOOL FASTCALL IntScrollWindow(PWND, int, int, CONST RECT *, CONST RECT *)
Definition: scrollex.c:458
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define STATUS_SUCCESS
Definition: shellext.h:65
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
Definition: fontsub.cpp:36
LONG lfHeight
Definition: dimm.idl:59
LONG lfWeight
Definition: dimm.idl:63
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
LONG lfWidth
Definition: dimm.idl:60
BYTE lfCharSet
Definition: dimm.idl:67
Definition: menu.c:79
PMENU CurrentMenu
Definition: menu.c:81
PWND OwnerWnd
Definition: menu.c:83
PMENU TopMenu
Definition: menu.c:82
POINT Pt
Definition: menu.c:84
UINT TrackFlags
Definition: menu.c:80
menu info structure
Definition: window.h:276
Definition: window.c:28
Definition: bl.h:1331
UINT style
Definition: ntuser.h:580
DWORD fnid
Definition: ntuser.h:570
PVOID Win32WindowStation
Definition: pstypes.h:1308
RECT rcMonitor
Definition: monitor.h:18
struct _DESKTOP * rpdesk
Definition: ntuser.h:219
DWORD_PTR hTaskWow
Definition: ntuser.h:218
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
struct _DESKTOP * rpdesk
Definition: win32.h:92
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: object.h:4
Definition: ntuser.h:694
DWORD ExStyle
Definition: ntuser.h:704
PCLS pcls
Definition: ntuser.h:720
THRDESKHEAD head
Definition: ntuser.h:695
DWORD style
Definition: ntuser.h:706
DWORD fnid
Definition: ntuser.h:709
RECT rcClient
Definition: ntuser.h:717
HMENU SystemMenu
Definition: ntuser.h:728
DWORD state
Definition: ntuser.h:701
UINT_PTR IDMenu
Definition: ntuser.h:731
RECT rcWindow
Definition: ntuser.h:716
Definition: dhcpd.h:62
LPCWSTR lpszClass
Definition: winuser.h:2965
LPCWSTR lpszName
Definition: winuser.h:2964
LPVOID lpCreateParams
Definition: winuser.h:2955
HINSTANCE hInstance
Definition: winuser.h:2956
ULONG_PTR itemData
Definition: winuser.h:3093
POINT MousePos
Definition: winuser.h:3317
int iCtrlId
Definition: winuser.h:3314
DWORD_PTR dwContextId
Definition: winuser.h:3316
HANDLE hItemHandle
Definition: winuser.h:3315
int iContextType
Definition: winuser.h:3313
UINT cbSize
Definition: winuser.h:3312
HBITMAP hbmp
Definition: ntuser.h:388
INT cyBmp
Definition: ntuser.h:390
HANDLE hbmpChecked
Definition: ntuser.h:376
ULONG yItem
Definition: ntuser.h:382
DWORD_PTR dwItemData
Definition: ntuser.h:380
UINT wID
Definition: ntuser.h:374
ULONG dxTab
Definition: ntuser.h:385
UNICODE_STRING lpstr
Definition: ntuser.h:392
UINT fType
Definition: ntuser.h:372
USHORT * Xlpstr
Definition: ntuser.h:378
UINT fState
Definition: ntuser.h:373
ULONG xItem
Definition: ntuser.h:381
struct tagMENU * spSubMenu
Definition: ntuser.h:375
INT cxBmp
Definition: ntuser.h:389
HANDLE hbmpUnchecked
Definition: ntuser.h:377
ULONG cxItem
Definition: ntuser.h:383
ULONG cyItem
Definition: ntuser.h:384
ULONG cch
Definition: ntuser.h:379
HMENU hmenuNext
Definition: winuser.h:3636
HMENU hmenuIn
Definition: winuser.h:3635
ULONG_PTR itemData
Definition: winuser.h:3646
BOOL fBarFocused
Definition: winuser.h:3730
DWORD cbSize
Definition: winuser.h:3726
ULONG fFlags
Definition: ntuser.h:418
ULONG cyMenu
Definition: ntuser.h:423
struct _WND * spwndNotify
Definition: ntuser.h:425
PROCDESKHEAD head
Definition: ntuser.h:417
INT iItem
Definition: ntuser.h:419
UINT cItems
Definition: ntuser.h:421
DWORD dwContextHelpId
Definition: ntuser.h:428
DWORD dwArrowsOn
Definition: ntuser.h:434
BOOL TimeToHide
Definition: ntuser.h:438
DWORD_PTR dwMenuData
Definition: ntuser.h:430
HWND hWnd
Definition: ntuser.h:437
ULONG cxMenu
Definition: ntuser.h:422
ULONG cyMax
Definition: ntuser.h:429
INT iTop
Definition: ntuser.h:432
INT iMaxTop
Definition: ntuser.h:433
HBRUSH hbrBack
Definition: ntuser.h:431
ULONG cxTextAlign
Definition: ntuser.h:424
PITEM rgItems
Definition: ntuser.h:426
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
ULONG fRightButton
Definition: ntuser.h:449
PMENU spmenu
Definition: ntuser.h:473
ULONG fFirstClick
Definition: ntuser.h:452
struct _WND * spwndNotify
Definition: ntuser.h:469
ULONG fNoNotify
Definition: ntuser.h:454
ULONG fIsSysMenu
Definition: ntuser.h:445
ULONG fSynchronous
Definition: ntuser.h:451
UINT posSelectedItem
Definition: ntuser.h:478
struct _WND * spwndPopupMenu
Definition: ntuser.h:470
struct _WND * spwndActivePopup
Definition: ntuser.h:475
ULONG fDroppedLeft
Definition: ntuser.h:447
ULONG fIsTrackPopup
Definition: ntuser.h:446
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
INT iTop
Definition: menu.h:91
INT iMaxTop
Definition: menu.h:92
HMENU Self
Definition: menu.h:95
DWORD dwContextHelpID
Definition: menu.h:81
HBRUSH hbrBack
Definition: menu.h:80
UINT cItems
Definition: menu.h:86
UINT iItem
Definition: menu.h:85
DWORD dwStyle
Definition: menu.h:78
UINT cyMax
Definition: menu.h:79
HWND Wnd
Definition: menu.h:96
ULONG_PTR dwMenuData
Definition: menu.h:82
ULONG cxTextAlign
Definition: menu.h:89
ULONG fFlags
Definition: menu.h:84
BOOL TimeToHide
Definition: menu.h:97
PWND spwndNotify
Definition: menu.h:90
DWORD cbSize
Definition: menu.h:76
WORD cyMenu
Definition: menu.h:88
WORD cxMenu
Definition: menu.h:87
DWORD dwArrowsOn
Definition: menu.h:93
DWORD fMask
Definition: menu.h:77
HBITMAP hbmpItem
Definition: menu.h:114
HBITMAP hbmpUnchecked
Definition: menu.h:110
SIZE maxBmpSize
Definition: menu.h:119
HMENU hSubMenu
Definition: menu.h:108
LPWSTR dwTypeData
Definition: menu.h:112
LPWSTR lpstr
Definition: menu.h:118
HBITMAP hbmpChecked
Definition: menu.h:109
DWORD dwItemData
Definition: menu.h:111
DWORD rgstate[CCHILDREN_TITLEBAR+1]
Definition: winuser.h:3762
RECT rcExclude
Definition: winuser.h:3576
#define max(a, b)
Definition: svc.c:63
#define WINVER
Definition: targetver.h:11
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define towupper(c)
Definition: wctype.h:99
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
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define TPM_SYSTEM_MENU
Definition: undocuser.h:73
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define DFCS_MENUARROWUP
Definition: undocuser.h:158
#define DFCS_MENUARROWDOWN
Definition: undocuser.h:159
#define MN_SETHMENU
Definition: undocuser.h:53
#define LN_MESSAGE_BEEP
Definition: undocuser.h:120
#define WC_MENU
Definition: undocuser.h:9
HDC FASTCALL IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
Definition: painting.c:1441
BOOL FASTCALL IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
Definition: painting.c:1538
VOID FASTCALL co_IntUpdateWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
Definition: painting.c:519
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
FORCEINLINE PMENU UserGetMenuObject(HMENU hMenu)
Definition: userfuncs.h:4
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:122
PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
Definition: window.c:3341
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2853
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:918
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
int ret
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
HDC hdcMem
Definition: welcome.c:104
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
DWORD FASTCALL IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height)
Definition: font.c:329
HFONT FASTCALL GreCreateFontIndirectW(LOGFONTW *lplf)
Definition: font.c:23
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1255
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
INT NTAPI GreGetObject(IN HGDIOBJ hobj, IN INT cbCount, OUT PVOID pvBuffer)
Definition: gdiobj.c:1264
VOID FASTCALL RECTL_vInflateRect(_Inout_ RECTL *rect, _In_ INT dx, _In_ INT dy)
Definition: rect.c:101
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
FORCEINLINE BOOL RECTL_bPointInRect(_In_ const RECTL *prcl, _In_ INT x, _In_ INT y)
Definition: rect.h:52
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
FORCEINLINE VOID RECTL_vSetEmptyRect(_Out_ RECTL *prcl)
Definition: rect.h:20
BOOL FASTCALL GreTextOutW(HDC hdc, int nXStart, int nYStart, LPCWSTR lpString, int cchString)
Definition: text.c:61
VOID FASTCALL co_IntSetupOBM(VOID)
Definition: callback.c:1180
HMENU APIENTRY co_IntCallLoadMenu(HINSTANCE hModule, PUNICODE_STRING pMenuName)
Definition: callback.c:903
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
Definition: caret.c:226
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:262
BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags)
Definition: cursoricon.c:1689
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1386
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215
static __inline PVOID DesktopHeapReAlloc(IN PDESKTOP Desktop, IN PVOID lpMem, IN SIZE_T Bytes)
Definition: desktop.h:226
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:178
BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags)
Definition: keyboard.c:1276
UINT APIENTRY NtUserGetMenuIndex(HMENU hMenu, HMENU hSubMenu)
Definition: menu.c:6075
#define MAXMENUDEPTH
Definition: menu.c:43
BOOL FASTCALL UserMenuInfo(PMENU Menu, PROSMENUINFO UnsafeMenuInfo, BOOL SetOrGet)
Definition: menu.c:5189
DWORD APIENTRY NtUserCheckMenuItem(HMENU hMenu, UINT uIDCheckItem, UINT uCheck)
Definition: menu.c:5595
BOOL APIENTRY NtUserGetMenuBarInfo(HWND hwnd, LONG idObject, LONG idItem, PMENUBARINFO pmbi)
Definition: menu.c:5915
static void MENU_DrawScrollArrows(PMENU lppop, HDC hdc)
Definition: menu.c:2176
#define IS_SYSTEM_MENU(MenuInfo)
Definition: menu.c:60
DWORD FASTCALL UserInsertMenuItem(PMENU Menu, UINT uItem, BOOL fByPosition, LPCMENUITEMINFOW UnsafeItemInfo, PUNICODE_STRING lpstr)
Definition: menu.c:4946
HMENU APIENTRY NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
Definition: menu.c:5671
BOOL FASTCALL IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
Definition: menu.c:317
BOOL FASTCALL UserDestroyMenu(HMENU hMenu)
Definition: menu.c:5807
BOOL APIENTRY NtUserSetMenuContextHelpId(HMENU hMenu, DWORD dwContextHelpId)
Definition: menu.c:6455
#define TF_ENDMENU
Definition: menu.c:35
PMENU get_win_sys_menu(HWND hwnd)
Definition: menu.c:258
static LRESULT FASTCALL MENU_DoNextMenu(MTRACKER *pmt, UINT Vk, UINT wFlags)
Definition: menu.c:3730
PMENU FASTCALL IntGetSystemMenu(PWND Window, BOOL bRevert)
Definition: menu.c:5394
static INT FASTCALL MENU_ExecFocusedItem(MTRACKER *pmt, PMENU Menu, UINT Flags)
Definition: menu.c:3473
static UINT MENU_GetStartOfPrevColumn(PMENU menu)
Definition: menu.c:467
BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
Definition: draw.c:959
PMENU FASTCALL VerifyMenu(PMENU pMenu)
Definition: menu.c:201
#define IS_STRING_ITEM(flags)
Definition: menu.c:64
static void FASTCALL MENU_HideSubPopups(PWND pWndOwner, PMENU Menu, BOOL SendMenuSelect, UINT wFlags)
Definition: menu.c:3262
VOID FASTCALL MENU_AdjustMenuItemRect(PMENU menu, PRECTL rect)
Definition: menu.c:1462
BOOL FASTCALL UserSetMenuDefaultItem(PMENU MenuObject, UINT uItem, UINT fByPos)
Definition: menu.c:1274
BOOL APIENTRY NtUserRemoveMenu(HMENU hMenu, UINT uPosition, UINT uFlags)
Definition: menu.c:6386
#define FreeMenuText(Menu, MenuItem)
Definition: menu.c:183
DWORD APIENTRY NtUserCalcMenuBar(HWND hwnd, DWORD leftBorder, DWORD rightBorder, DWORD top, LPRECT prc)
Definition: menu.c:5549
static HMENU top_popup_hmenu
Definition: menu.c:23
BOOL FASTCALL IntGetMenuItemRect(PWND pWnd, PMENU Menu, UINT uItem, PRECTL Rect)
Definition: menu.c:5241
static ITEM * MENU_FindItemByCoords(MENU *menu, POINT pt, UINT *pos)
Definition: menu.c:1480
static BOOL MENU_InitPopup(PWND pWndOwner, PMENU menu, UINT flags)
Definition: menu.c:2781
DWORD APIENTRY NtUserDrawMenuBarTemp(HWND hWnd, HDC hDC, PRECT pRect, HMENU hMenu, HFONT hFont)
Definition: menu.c:6235
static void FASTCALL MENU_DrawPopupMenu(PWND wnd, HDC hdc, PMENU menu)
Definition: menu.c:2599
BOOL FASTCALL IntSetMenuInfo(PMENU Menu, PROSMENUINFO lpmi)
Definition: menu.c:914
#define MENU_COL_SPACE
Definition: menu.c:71
INT FASTCALL IntMenuItemFromPoint(PWND pWnd, HMENU hMenu, POINT ptScreen)
Definition: menu.c:1518
BOOL MenuInit(VOID)
Definition: menu.c:359
BOOL APIENTRY NtUserEndMenu(VOID)
Definition: menu.c:5885
static UINT MENU_GetStartOfNextColumn(PMENU menu)
Definition: menu.c:437
DWORD FASTCALL IntCheckMenuItem(PMENU MenuObject, UINT uIDCheckItem, UINT uCheck)
Definition: menu.c:1259
BOOL FASTCALL IntGetMenuInfo(PMENU Menu, PROSMENUINFO lpmi)
Definition: menu.c:879
static BOOL FASTCALL MENU_MouseMove(MTRACKER *pmt, PMENU PtMenu, UINT Flags)
Definition: menu.c:3687
BOOL FASTCALL IntIsMenu(HMENU Menu)
Definition: menu.c:240
BOOL FASTCALL IntSetMenuContextHelpId(PMENU Menu, DWORD dwContextHelpId)
Definition: menu.c:872
#define IS_MAGIC_BITMAP(id)
Definition: menu.c:63
static SIZE MenuCharSize
Definition: menu.c:18
void MENU_EnsureMenuItemVisible(PMENU lppop, UINT wIndex, HDC hdc)
Definition: menu.c:3097
BOOLEAN APIENTRY intGetTitleBarInfo(PWND pWindowObject, PTITLEBARINFO bti)
Definition: menu.c:4815
static void FASTCALL MENU_GetBitmapItemSize(PITEM lpitem, SIZE *size, PWND WndOwner)
Definition: menu.c:1588
#define MENUITEMINFO_TYPE_MASK
Definition: menu.c:47
BOOL APIENTRY NtUserDestroyMenu(HMENU hMenu)
Definition: menu.c:5829
static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC hdc, PITEM lpitem, UINT Height, BOOL menuBar, UINT odaction)
Definition: menu.c:2204
BOOL APIENTRY NtUserDeleteMenu(HMENU hMenu, UINT uPosition, UINT uFlags)
Definition: menu.c:5621
#define MM_SETMENUHANDLE
Definition: menu.c:30
PWND MENU_IsMenuActive(VOID)
Definition: menu.c:2650
BOOL APIENTRY NtUserGetMenuItemRect(HWND hWnd, HMENU hMenu, UINT uItem, PRECTL lprcItem)
Definition: menu.c:6111
#define UpdateMenuItemState(state, change)
Definition: menu.c:95
static BOOL FASTCALL MENU_SuspendPopup(MTRACKER *pmt, UINT uMsg)
Definition: menu.c:3872
static BOOL FASTCALL MENU_ExitTracking(PWND pWnd, BOOL bPopup, UINT wFlags)
Definition: menu.c:4459
BOOL APIENTRY NtUserSetMenu(HWND hWnd, HMENU Menu, BOOL Repaint)
Definition: menu.c:6412
static void FASTCALL MENU_MoveSelection(PWND pwndOwner, PMENU menu, INT offset)
Definition: menu.c:3226
static BOOL RECTL_Intersect(const RECT *pRect, INT x, INT y, UINT width, UINT height)
Definition: menu.c:2880
UINT FASTCALL IntFindSubMenu(HMENU *hMenu, HMENU hSubTarget)
Definition: menu.c:5026
UINT MENU_DrawMenuBar(HDC hDC, LPRECT lprect, PWND pWnd, BOOL suppress_draw)
Definition: menu.c:2742
static PMENU FASTCALL MENU_PtMenu(PMENU menu, POINT pt)
Definition: menu.c:3647
static void FASTCALL MENU_DrawBitmapItem(HDC hdc, PITEM lpitem, const RECT *rect, PMENU Menu, PWND WndOwner, UINT odaction, BOOL MenuBar)
Definition: menu.c:1653
void MENU_EndMenu(PWND pwnd)
Definition: menu.c:2662
PMENU FASTCALL IntCloneMenu(PMENU Source)
Definition: menu.c:822
BOOL FASTCALL IntSetMenu(PWND Wnd, HMENU Menu, BOOL *Changed)
Definition: menu.c:5470
PMENU FASTCALL IntCreateMenu(_Out_ PHANDLE Handle, _In_ BOOL IsMenuBar, _In_ PDESKTOP Desktop, _In_ PPROCESSINFO ppi)
Definition: menu.c:729
#define TF_SKIPREMOVE
Definition: menu.c:37
BOOL FASTCALL UserMenuItemInfo(PMENU Menu, UINT Item, BOOL ByPosition, PROSMENUITEMINFO UnsafeItemInfo, BOOL SetOrGet, PUNICODE_STRING lpstr)
Definition: menu.c:5115
static void FASTCALL MENU_KeyRight(MTRACKER *pmt, UINT Flags, UINT msg)
Definition: menu.c:3989
static PMENU MENU_GetSubPopup(PMENU menu)
Definition: menu.c:3711
DWORD WINAPI IntDrawMenuBarTemp(PWND pWnd, HDC hDC, LPRECT Rect, PMENU pMenu, HFONT Font)
Definition: menu.c:2685
static UINT FASTCALL MENU_FindItemByKey(PWND WndOwner, PMENU menu, WCHAR Key, BOOL ForceMenuChar)
Definition: menu.c:1535
#define TPM_POPUPMENU
Definition: menu.c:90
BOOL APIENTRY NtUserTrackPopupMenuEx(HMENU hMenu, UINT fuFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm)
Definition: menu.c:6619
BOOL APIENTRY NtUserThunkedMenuItemInfo(HMENU hMenu, UINT uItem, BOOL fByPosition, BOOL bInsert, LPMENUITEMINFOW lpmii, PUNICODE_STRING lpszCaption)
Definition: menu.c:6555
#define TPM_BUTTONDOWN
Definition: menu.c:89
#define TF_SUSPENDPOPUP
Definition: menu.c:36
static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT flags, INT x, INT y, const RECT *pExclude)
Definition: menu.c:2939
BOOLEAN UserDestroyMenuObject(PVOID Object)
Definition: menu.c:311
BOOL FASTCALL IntInsertMenuItem(_In_ PMENU MenuObject, UINT uItem, BOOL fByPosition, PROSMENUITEMINFO ItemInfo, PUNICODE_STRING lpstr)
Definition: menu.c:691
HFONT ghMenuFont
Definition: menu.c:16
HFONT ghMenuFontBold
Definition: menu.c:17
static INT FASTCALL MENU_ButtonUp(MTRACKER *pmt, PMENU PtMenu, UINT Flags)
Definition: menu.c:3598
BOOL FASTCALL IntSetMenuItemInfo(PMENU MenuObject, PITEM MenuItem, PROSMENUITEMINFO lpmii, PUNICODE_STRING lpstr)
Definition: menu.c:1033
BOOL WINAPI PopupMenuWndProc(PWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
Definition: menu.c:4642
void FASTCALL MENU_InitSysMenuPopup(PMENU menu, DWORD style, DWORD clsStyle, LONG HitTest)
Definition: menu.c:1362
int APIENTRY NtUserMenuItemFromPoint(HWND hWnd, HMENU hMenu, DWORD X, DWORD Y)
Definition: menu.c:6292
static void FASTCALL MENU_SelectItem(PWND pwndOwner, PMENU menu, UINT wIndex, BOOL sendMenuSelect, PMENU topmenu)
Definition: menu.c:3139
PMENU WINAPI IntGetMenu(HWND hWnd)
Definition: menu.c:248
BOOL APIENTRY NtUserSetMenuFlagRtoL(HMENU hMenu)
Definition: menu.c:6506
BOOL APIENTRY NtUserHiliteMenuItem(HWND hWnd, HMENU hMenu, UINT uItemHilite, UINT uHilite)
Definition: menu.c:6197
BOOL WINAPI IntTrackPopupMenuEx(PMENU menu, UINT wFlags, int x, int y, PWND pWnd, LPTPMPARAMS lpTpm)
Definition: menu.c:4572
static HWND top_popup
Definition: menu.c:22
BOOL FASTCALL IntGetMenuItemInfo(PMENU Menu, PITEM MenuItem, PROSMENUITEMINFO lpmii)
Definition: menu.c:962
BOOL APIENTRY NtUserSetMenuDefaultItem(HMENU hMenu, UINT uItem, UINT fByPos)
Definition: menu.c:6480
PMENU FASTCALL co_IntGetSubMenu(PMENU pMenu, int nPos)
Definition: menu.c:1348
BOOL FASTCALL IntSetSystemMenu(PWND Window, PMENU Menu)
Definition: menu.c:5437
PMENU FASTCALL MENU_GetSystemMenu(PWND Window, PMENU Popup)
Definition: menu.c:5289
BOOL fInsideMenuLoop
Definition: menu.c:25
static void MENU_MenuBarCalcSize(HDC hdc, LPRECT lprect, PMENU lppop, PWND pwndOwner)
Definition: menu.c:2101
static BOOL MENU_MoveRect(UINT flags, INT *x, INT *y, INT width, INT height, const RECT *pExclude, PMONITOR monitor)
Definition: menu.c:2888
UINT FASTCALL IntGetMenuDefaultItem(PMENU MenuObject, UINT fByPos, UINT gmdiFlags, DWORD *gismc)
Definition: menu.c:1315
#define ITEM_NEXT
Definition: menu.c:93
BOOL FASTCALL IntHiliteMenuItem(PWND WindowObject, PMENU MenuObject, UINT uItemHilite, UINT uHilite)
Definition: menu.c:4789
static BOOL FASTCALL MENU_ButtonDown(MTRACKER *pmt, PMENU PtMenu, UINT Flags)
Definition: menu.c:3553
BOOL IntDestroyMenu(PMENU pMenu, BOOL bRecurse)
Definition: menu.c:269
BOOL FASTCALL IntRemoveMenuItem(PMENU pMenu, UINT nPos, UINT wFlags, BOOL bRecurse)
Definition: menu.c:596
PMENU FASTCALL IntGetMenuObject(HMENU hMenu)
Definition: menu.c:192
BOOL FASTCALL IntSetMenuFlagRtoL(PMENU Menu)
Definition: menu.c:864
PITEM FASTCALL MENU_FindItem(PMENU *pmenu, UINT *nPos, UINT wFlags)
Definition: menu.c:507
static void FASTCALL MENU_KeyLeft(MTRACKER *pmt, UINT Flags, UINT msg)
Definition: menu.c:3941
static INT FASTCALL MENU_TrackMenu(PMENU pmenu, UINT wFlags, INT x, INT y, PWND pwnd)
Definition: menu.c:4045
int FASTCALL MENU_depth(PMENU pmenu, int depth)
Definition: menu.c:404
ITEM * MENU_InsertItem(PMENU menu, UINT pos, UINT flags, PMENU *submenu, UINT *npos)
Definition: menu.c:639
static UINT FASTCALL MENU_FindSubMenu(PMENU *menu, PMENU SubTarget)
Definition: menu.c:564
#define MNS_STYLE_MASK
Definition: menu.c:45
VOID MENU_TrackKbdMenuBar(PWND pwnd, UINT wParam, WCHAR wChar)
Definition: menu.c:4511
BOOL FASTCALL IntCloneMenuItems(PMENU Destination, PMENU Source)
Definition: menu.c:771
VOID MENU_TrackMouseMenuBar(PWND pWnd, ULONG ht, POINT pt)
Definition: menu.c:4481
#define MM_GETMENUHANDLE
Definition: menu.c:31
LONG IntGetDialogBaseUnits(VOID)
Definition: menu.c:1800
DWORD APIENTRY NtUserPaintMenuBar(HWND hWnd, HDC hDC, ULONG leftBorder, ULONG rightBorder, ULONG top, BOOL bActive)
Definition: menu.c:6349
#define ITEM_PREV
Definition: menu.c:92
static UINT MENU_GetMaxPopupHeight(PMENU lppop)
Definition: menu.c:1996
static PMENU FASTCALL MENU_ShowSubPopup(PWND WndOwner, PMENU Menu, BOOL SelectFirst, UINT Flags)
Definition: menu.c:3316
BOOL fInEndMenu
Definition: menu.c:26
UINT FASTCALL IntGetMenuState(HMENU hMenu, UINT uId, UINT uFlags)
Definition: menu.c:4986
UINT FASTCALL IntEnableMenuItem(PMENU MenuObject, UINT uIDEnableItem, UINT uEnable)
Definition: menu.c:1217
static BOOL FASTCALL MENU_KeyEscape(MTRACKER *pmt, UINT Flags)
Definition: menu.c:3908
HMENU FASTCALL UserCreateMenu(PDESKTOP Desktop, BOOL PopupMenu)
Definition: menu.c:5043
static void FASTCALL MENU_PopupMenuCalcSize(PMENU Menu, PWND WndOwner)
Definition: menu.c:2012
static void FASTCALL MENU_CalcItemSize(HDC hdc, PITEM lpitem, PMENU Menu, PWND pwndOwner, INT orgX, INT orgY, BOOL menuBar, BOOL textandbmp)
Definition: menu.c:1825
BOOL FASTCALL IntMenuItemInfo(PMENU Menu, UINT Item, BOOL ByPosition, PROSMENUITEMINFO ItemInfo, BOOL SetOrGet, PUNICODE_STRING lpstr)
Definition: menu.c:5087
static BOOL FASTCALL MENU_InitTracking(PWND pWnd, PMENU Menu, BOOL bPopup, UINT wFlags)
Definition: menu.c:4399
BOOL APIENTRY NtUserThunkedMenuInfo(HMENU hMenu, LPCMENUINFO lpcmi)
Definition: menu.c:6530
BOOL APIENTRY NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
Definition: menu.c:5706
UINT APIENTRY NtUserEnableMenuItem(HMENU hMenu, UINT uIDEnableItem, UINT uEnable)
Definition: menu.c:5859
static void FASTCALL MENU_SwitchTracking(MTRACKER *pmt, PMENU PtMenu, UINT Index, UINT wFlags)
Definition: menu.c:3528
BOOLEAN APIENTRY NtUserGetTitleBarInfo(HWND hwnd, PTITLEBARINFO bti)
Definition: menu.c:5745
HMENU FASTCALL IntGetSubMenu(HMENU hMenu, int nPos)
Definition: menu.c:5006
static void FASTCALL MENU_DrawPopupGlyph(HDC dc, LPRECT r, INT_PTR popupMagic, BOOL inactive, BOOL hilite)
Definition: menu.c:1398
BOOL FASTCALL IntCallMsgFilter(LPMSG lpmsg, INT code)
Definition: message.c:2140
LRESULT FASTCALL IntDispatchMessage(PMSG pMsg)
Definition: message.c:840
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1345
BOOL FASTCALL co_IntWaitMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax)
Definition: message.c:1130
BOOL APIENTRY co_IntGetPeekMessage(PMSG pMsg, HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, UINT RemoveMsg, BOOL bGMSG)
Definition: message.c:1176
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1445
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:213
PMONITOR FASTCALL UserMonitorFromPoint(IN POINT pt, IN DWORD dwFlags)
Definition: monitor.c:481
PCURICON_OBJECT FASTCALL NC_IconForWindow(PWND pWnd)
Definition: nonclient.c:705
DWORD FASTCALL GetNCHitEx(PWND pWnd, POINT pt)
Definition: nonclient.c:1954
BOOL UserDrawSysMenuButton(PWND pWnd, HDC hDC, LPRECT Rect, BOOL Down)
Definition: nonclient.c:736
void FASTCALL NC_GetSysPopupPos(PWND Wnd, RECT *Rect)
Definition: nonclient.c:117
void FASTCALL NC_GetInsideRect(PWND Wnd, RECT *rect)
Definition: nonclient.c:71
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:703
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:731
BOOL FASTCALL UserSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
Definition: sysparams.c:2105
PWND FASTCALL VerifyWnd(PWND pWnd)
Definition: window.c:86
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW *Cs, PUNICODE_STRING ClassName, PLARGE_STRING WindowName, PVOID acbiBuffer, DWORD dwVer)
Definition: window.c:2173
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:176
#define HAS_DLGFRAME(Style, ExStyle)
Definition: window.h:9
#define HAS_THINFRAME(Style, ExStyle)
Definition: window.h:17
#define HAS_THICKFRAME(Style, ExStyle)
Definition: window.h:13
VOID FASTCALL IntGetClientRect(PWND WindowObject, RECTL *Rect)
Definition: winpos.c:92
static MONITORINFO mi
Definition: win.c:7338
#define OBJID_MENU
Definition: winable.h:18
#define OBJID_SYSMENU
Definition: winable.h:16
#define OBJID_CLIENT
Definition: winable.h:19
#define OBJID_WINDOW
Definition: winable.h:15
#define CHILDID_SELF
Definition: winable.h:14
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
ENGAPI ULONG APIENTRY EngGetLastError(VOID)
Definition: error.c:9
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
_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
DWORD COLORREF
Definition: windef.h:300
#define WINAPI
Definition: msvc.h:6
#define ERROR_POPUP_ALREADY_ACTIVE
Definition: winerror.h:927
#define ERROR_MENU_ITEM_NOT_FOUND
Definition: winerror.h:937
#define ERROR_INVALID_MENU_HANDLE
Definition: winerror.h:882
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881
#define FW_BOLD
Definition: wingdi.h:378
#define DI_NORMAL
Definition: wingdi.h:72
#define DEFAULT_CHARSET
Definition: wingdi.h:384
#define TRANSPARENT
Definition: wingdi.h:950
#define SRCCOPY
Definition: wingdi.h:333
#define NULL_PEN
Definition: wingdi.h:904
#define BLACK_BRUSH
Definition: wingdi.h:896
#define FW_NORMAL
Definition: wingdi.h:373
#define FW_HEAVY
Definition: wingdi.h:381
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
#define NOTSRCCOPY
Definition: wingdi.h:325
#define WM_PAINT
Definition: winuser.h:1620
#define ODS_DISABLED
Definition: winuser.h:2547
#define WS_EX_LAYOUTRTL
Definition: winuser.h:390
#define MF_MOUSESELECT
Definition: winuser.h:145
#define WM_ERASEBKGND
Definition: winuser.h:1625
#define SM_MENUDROPALIGNMENT
Definition: winuser.h:1003
BOOL WINAPI EndMenu(void)
#define MAKEWPARAM(l, h)
Definition: winuser.h:4009
#define DFCS_MENUCHECK
Definition: winuser.h:486
#define WS_EX_STATICEDGE
Definition: winuser.h:403
int WINAPI FrameRect(_In_ HDC, _In_ LPCRECT, _In_ HBRUSH)
#define ODS_SELECTED
Definition: winuser.h:2545
#define SWP_NOACTIVATE
Definition: winuser.h:1242
#define MNS_NOTIFYBYPOS
Definition: winuser.h:759
#define MF_BYCOMMAND
Definition: winuser.h:202
#define WM_SYSCOMMAND
Definition: winuser.h:1741
#define BDR_SUNKENOUTER
Definition: winuser.h:443
#define MIIM_STRING
Definition: winuser.h:727
#define HBMMENU_SYSTEM
Definition: winuser.h:2631
#define SM_CYEDGE
Definition: winuser.h:1009
#define WM_MOUSEFIRST
Definition: winuser.h:1774
#define WM_NEXTMENU
Definition: winuser.h:1806
#define TPM_CENTERALIGN
Definition: winuser.h:2376
#define SWP_FRAMECHANGED
Definition: winuser.h:1240
#define MIIM_ID
Definition: winuser.h:722
#define HBMMENU_MBAR_RESTORE
Definition: winuser.h:2632
#define COLOR_MENU
Definition: winuser.h:917
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define MNS_MODELESS
Definition: winuser.h:756
#define WM_KEYUP
Definition: winuser.h:1716
#define COLOR_GRAYTEXT
Definition: winuser.h:932
#define MF_RIGHTJUSTIFY
Definition: winuser.h:144
#define WM_MOUSELAST
Definition: winuser.h:1801
#define DCX_CACHE
Definition: winuser.h:2114
#define COLOR_WINDOWFRAME
Definition: winuser.h:919
#define ODS_CHECKED
Definition: winuser.h:2548
#define SM_CYSCREEN
Definition: winuser.h:960
#define DT_CENTER
Definition: winuser.h:527
#define HTCAPTION
Definition: winuser.h:2476
#define ODA_DRAWENTIRE
Definition: winuser.h:2542
#define DCX_WINDOW
Definition: winuser.h:2113
#define HELPINFO_MENUITEM
Definition: winuser.h:1171
#define HWND_TOPMOST
Definition: winuser.h:1208
#define SM_CXEDGE
Definition: winuser.h:1008
#define MNC_EXECUTE
Definition: winuser.h:2568
#define VK_F10
Definition: winuser.h:2264
MENUINFO CONST * LPCMENUINFO
Definition: winuser.h:3744
#define HBMMENU_POPUP_RESTORE
Definition: winuser.h:2638
#define MF_MENUBARBREAK
Definition: winuser.h:133
#define TPM_RIGHTBUTTON
Definition: winuser.h:2380
#define SM_CXMENUCHECK
Definition: winuser.h:1031
#define SM_CYSIZE
Definition: winuser.h:992
#define WM_CREATE
Definition: winuser.h:1608
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
#define DFCS_CAPTIONMIN
Definition: winuser.h:481
#define DFCS_CAPTIONCLOSE
Definition: winuser.h:480
#define HBMMENU_POPUP_MINIMIZE
Definition: winuser.h:2640
#define MNS_DRAGDROP
Definition: winuser.h:757
#define HBMMENU_MBAR_MINIMIZE
Definition: winuser.h:2633
#define COLOR_HIGHLIGHT
Definition: winuser.h:926
#define MIIM_CHECKMARKS
Definition: winuser.h:724
#define HTERROR
Definition: winuser.h:2472
#define WM_CANCELMODE
Definition: winuser.h:1635
#define DT_SINGLELINE
Definition: winuser.h:540
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1778
#define SM_CXFRAME
Definition: winuser.h:994
#define SWP_NOMOVE
Definition: winuser.h:1244
#define WM_COMMAND
Definition: winuser.h:1740
#define GMDI_USEDISABLED
Definition: winuser.h:2126
#define TPM_BOTTOMALIGN
Definition: winuser.h:2385
#define DFCS_INACTIVE
Definition: winuser.h:502
#define MF_STRING
Definition: winuser.h:138
#define MIIM_FTYPE
Definition: winuser.h:729
#define VK_RBUTTON
Definition: winuser.h:2191
#define BF_LEFT
Definition: winuser.h:454
#define WM_KEYFIRST
Definition: winuser.h:1714
#define SM_CYMENU
Definition: winuser.h:976
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
#define WM_RBUTTONUP
Definition: winuser.h:1780
#define SM_CYSMICON
Definition: winuser.h:1013
#define VK_UP
Definition: winuser.h:2225
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1781
#define MFS_DISABLED
Definition: winuser.h:749
#define DFCS_MENUARROW
Definition: winuser.h:485
#define GA_PARENT
Definition: winuser.h:2788
#define EDGE_ETCHED
Definition: winuser.h:452
#define MF_CHECKED
Definition: winuser.h:132
#define SWP_NOSIZE
Definition: winuser.h:1245
#define WM_MOUSEMOVE
Definition: winuser.h:1775
#define MN_GETHMENU
Definition: winuser.h:1773
#define SC_TASKLIST
Definition: winuser.h:2599
#define TPM_RIGHTALIGN
Definition: winuser.h:2378
#define CCHILDREN_TITLEBAR
Definition: winuser.h:3757
#define WM_INITMENU
Definition: winuser.h:1745
#define MF_SYSMENU
Definition: winuser.h:141
#define TPM_NONOTIFY
Definition: winuser.h:2386
#define MA_NOACTIVATE
Definition: winuser.h:2503
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
#define HBMMENU_MBAR_MINIMIZE_D
Definition: winuser.h:2636
#define MFT_SEPARATOR
Definition: winuser.h:744
#define MNS_CHECKORBMP
Definition: winuser.h:760
#define VK_F1
Definition: winuser.h:2255
#define TPM_VCENTERALIGN
Definition: winuser.h:2384
#define SM_CXSIZE
Definition: winuser.h:991
#define MF_POPUP
Definition: winuser.h:136
#define SM_CYFRAME
Definition: winuser.h:996
#define WM_DRAWITEM
Definition: winuser.h:1645
#define DFC_CAPTION
Definition: winuser.h:473
#define WS_EX_PALETTEWINDOW
Definition: winuser.h:399
#define WM_NCCREATE
Definition: winuser.h:1683
#define HTMENU
Definition: winuser.h:2480
#define MIIM_STATE
Definition: winuser.h:721
#define MF_DEFAULT
Definition: winuser.h:140
#define SC_SIZE
Definition: winuser.h:2584
#define MFS_DEFAULT
Definition: winuser.h:748
#define WM_RBUTTONDOWN
Definition: winuser.h:1779
#define MFT_OWNERDRAW
Definition: winuser.h:741
#define SC_MINIMIZE
Definition: winuser.h:2586
#define GMDI_GOINTOPOPUPS
Definition: winuser.h:2125
#define SM_CYBORDER
Definition: winuser.h:965
#define SM_CXSMICON
Definition: winuser.h:1012
#define DT_LEFT
Definition: winuser.h:534
#define WM_SYSCHAR
Definition: winuser.h:1721
#define WM_ENTERMENULOOP
Definition: winuser.h:1804
#define SM_CYMENUCHECK
Definition: winuser.h:1032
#define VK_RETURN
Definition: winuser.h:2201
#define STATE_SYSTEM_FOCUSABLE
Definition: winuser.h:2882
#define WS_EX_MDICHILD
Definition: winuser.h:394
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
#define MIIM_SUBMENU
Definition: winuser.h:723
#define HBMMENU_POPUP_CLOSE
Definition: winuser.h:2637
#define MF_MENUBREAK
Definition: winuser.h:134
#define WM_MENUCHAR
Definition: winuser.h:1748
#define WM_INITMENUPOPUP
Definition: winuser.h:1746
#define MF_ENABLED
Definition: winuser.h:128
#define MFS_GRAYED
Definition: winuser.h:751
#define MF_SEPARATOR
Definition: winuser.h:137
#define PM_NOYIELD
Definition: winuser.h:1197
#define BF_TOP
Definition: winuser.h:455
#define RDW_ALLCHILDREN
Definition: winuser.h:1221
#define MIIM_BITMAP
Definition: winuser.h:728
#define WM_TIMER
Definition: winuser.h:1742
#define VK_END
Definition: winuser.h:2222
#define TPM_LEFTALIGN
Definition: winuser.h:2377
#define VK_HOME
Definition: winuser.h:2223
#define MF_BYPOSITION
Definition: winuser.h:203
#define SM_CXBORDER
Definition: winuser.h:964
#define DFCS_CAPTIONRESTORE
Definition: winuser.h:483
#define MSGF_MENU
Definition: winuser.h:1175
#define PM_REMOVE
Definition: winuser.h:1196
#define MFT_BITMAP
Definition: winuser.h:738
#define STATE_SYSTEM_INVISIBLE
Definition: winuser.h:2877
#define MNC_CLOSE
Definition: winuser.h:2567
#define MFT_RIGHTJUSTIFY
Definition: winuser.h:743
#define SWP_SHOWWINDOW
Definition: winuser.h:1248
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:927
#define WM_EXITMENULOOP
Definition: winuser.h:1805
#define TPM_VERTICAL
Definition: winuser.h:2382
#define MFS_CHECKED
Definition: winuser.h:747
#define HTNOWHERE
Definition: winuser.h:2474
#define SC_CLOSE
Definition: winuser.h:2592
#define SC_MOVE
Definition: winuser.h:2585
struct tagHELPINFO HELPINFO
#define WM_MOUSEACTIVATE
Definition: winuser.h:1637
#define SM_DBCSENABLED
Definition: winuser.h:1005
#define TPM_LEFTBUTTON
Definition: winuser.h:2379
#define WM_MEASUREITEM
Definition: winuser.h:1646
#define COLOR_BTNSHADOW
Definition: winuser.h:930
#define SM_CXDLGFRAME
Definition: winuser.h:966
#define MFS_ENABLED
Definition: winuser.h:750
#define MNS_AUTODISMISS
Definition: winuser.h:758
#define WM_LBUTTONUP
Definition: winuser.h:1777
#define WM_CHAR
Definition: winuser.h:1717
#define DT_VCENTER
Definition: winuser.h:543
#define HBMMENU_MBAR_CLOSE
Definition: winuser.h:2634
#define STATE_SYSTEM_UNAVAILABLE
Definition: winuser.h:2862
#define VK_LEFT
Definition: winuser.h:2224
#define MNS_NOCHECK
Definition: winuser.h:755
#define WM_NCDESTROY
Definition: winuser.h:1684
#define VK_RIGHT
Definition: winuser.h:2226
#define ODA_SELECT
Definition: winuser.h:2543
#define VK_DOWN
Definition: winuser.h:2227
#define ODS_GRAYED
Definition: winuser.h:2546
#define WM_SETCURSOR
Definition: winuser.h:1636
#define SM_CYSMCAPTION
Definition: winuser.h:1014
#define MF_HILITE
Definition: winuser.h:205
#define SM_CYDLGFRAME
Definition: winuser.h:968
#define MFT_STRING
Definition: winuser.h:746
#define HBMMENU_MBAR_CLOSE_D
Definition: winuser.h:2635
#define WM_DESTROY
Definition: winuser.h:1609
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define HBMMENU_POPUP_MAXIMIZE
Definition: winuser.h:2639
#define WM_KEYDOWN
Definition: winuser.h:1715
#define WS_EX_CONTEXTHELP
Definition: winuser.h:386
#define DT_RIGHT
Definition: winuser.h:538
#define SM_CYMENUSIZE
Definition: winuser.h:1018
#define COLOR_MENUTEXT
Definition: winuser.h:920
#define TPM_RETURNCMD
Definition: winuser.h:2387
#define SWP_NOZORDER
Definition: winuser.h:1247
#define DFCS_MENUBULLET
Definition: winuser.h:487
#define DT_CALCRECT
Definition: winuser.h:526
#define HTSYSMENU
Definition: winuser.h:2477
#define COLOR_BTNHIGHLIGHT
Definition: winuser.h:935
#define BF_RECT
Definition: winuser.h:462
#define MF_OWNERDRAW
Definition: winuser.h:135
#define WM_KEYLAST
Definition: winuser.h:1728
#define WM_MENUSELECT
Definition: winuser.h:1747
#define VK_ESCAPE
Definition: winuser.h:2214
#define SC_RESTORE
Definition: winuser.h:2598
#define WM_ENTERIDLE
Definition: winuser.h:1749
#define ODT_MENU
Definition: winuser.h:2537
#define DFCS_PUSHED
Definition: winuser.h:503
#define SM_CYCAPTION
Definition: winuser.h:963
#define MFS_HILITE
Definition: winuser.h:752
#define HBMMENU_CALLBACK
Definition: winuser.h:2630
#define PM_NOREMOVE
Definition: winuser.h:1195
#define CS_NOCLOSE
Definition: winuser.h:654
#define MIIM_DATA
Definition: winuser.h:726
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define MIIM_TYPE
Definition: winuser.h:725
#define MFT_MENUBREAK
Definition: winuser.h:740
#define SC_MAXIMIZE
Definition: winuser.h:2588
struct tagMENUITEMINFOW MENUITEMINFOW
#define VK_MENU
Definition: winuser.h:2204
#define MFT_RADIOCHECK
Definition: winuser.h:742
#define MFT_MENUBARBREAK
Definition: winuser.h:739
#define MF_GRAYED
Definition: winuser.h:129
#define COLOR_3DFACE
Definition: winuser.h:929
#define VK_LBUTTON
Definition: winuser.h:2190
#define MF_DISABLED
Definition: winuser.h:130
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define NT_ASSERT
Definition: rtlfuncs.h:3310
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185