From 8e9189e36efe2baa914fc6c57550a4ea45be4dfc Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 16 Mar 2010 22:21:20 +0000 Subject: [PATCH] [USER32] reduce diff to wine svn path=/trunk/; revision=46231 --- reactos/dll/win32/user32/windows/menu.c | 2278 +++++++++++------------ 1 file changed, 1074 insertions(+), 1204 deletions(-) diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 3f3916c6481..badf2d923c1 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -12,15 +12,25 @@ /* INCLUDES ******************************************************************/ #include - #include -WINE_DEFAULT_DEBUG_CHANNEL(user32); LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active); +WINE_DEFAULT_DEBUG_CHANNEL(menu); + /* internal popup menu window messages */ -#define MM_SETMENUHANDLE (WM_USER + 0) -#define MM_GETMENUHANDLE (WM_USER + 1) + +#define MM_SETMENUHANDLE (WM_USER + 0) +#define MM_GETMENUHANDLE (WM_USER + 1) + +/* internal flags for menu tracking */ + +#define TF_ENDMENU 0x10000 +#define TF_SUSPENDPOPUP 0x20000 +#define TF_SKIPREMOVE 0x40000 + +#define ITEM_PREV -1 +#define ITEM_NEXT 1 /* Internal MenuTrackMenu() flags */ #define TPM_INTERNAL 0xF0000000 @@ -28,13 +38,14 @@ LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active); #define TPM_BUTTONDOWN 0x40000000 /* menu was clicked before tracking */ #define TPM_POPUPMENU 0x20000000 /* menu is a popup menu */ -/* TYPES *********************************************************************/ #define MENU_TYPE_MASK (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR) #define MENU_ITEM_TYPE(flags) ((flags) & MENU_TYPE_MASK) + +/* macro to test that flags do not indicate bitmap, ownerdraw or separator */ #define IS_STRING_ITEM(flags) (MF_STRING == MENU_ITEM_TYPE(flags)) -#define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags)) +#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1)) #define IS_SYSTEM_MENU(MenuInfo) \ (0 == ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU)) @@ -42,27 +53,25 @@ LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active); #define IS_SYSTEM_POPUP(MenuInfo) \ (0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU)) -#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1)) +#define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags)) + +/* Use global popup window because there's no way 2 menus can + * be tracked at the same time. */ +static HWND TopPopup; + +/* Flag set by EndMenu() to force an exit from menu tracking */ +static BOOL fEndMenu = FALSE; #define MENU_ITEM_HBMP_SPACE (5) #define MENU_BAR_ITEMS_SPACE (12) #define SEPARATOR_HEIGHT (5) #define MENU_TAB_SPACE (8) -#define ITEM_PREV -1 -#define ITEM_NEXT 1 - #define MAKEINTATOMA(atom) ((LPCSTR)((ULONG_PTR)((WORD)(atom)))) #define MAKEINTATOMW(atom) ((LPCWSTR)((ULONG_PTR)((WORD)(atom)))) #define POPUPMENU_CLASS_ATOMA MAKEINTATOMA(32768) /* PopupMenu */ #define POPUPMENU_CLASS_ATOMW MAKEINTATOMW(32768) /* PopupMenu */ -/* internal flags for menu tracking */ - -#define TF_ENDMENU 0x0001 -#define TF_SUSPENDPOPUP 0x0002 -#define TF_SKIPREMOVE 0x0004 - typedef struct { UINT TrackFlags; @@ -72,8 +81,6 @@ typedef struct POINT Pt; } MTRACKER; -//static LRESULT WINAPI PopupMenuWndProcA(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); -//static LRESULT WINAPI PopupMenuWndProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /********************************************************************* * PopupMenu class descriptor @@ -89,14 +96,6 @@ const struct builtin_class_descr POPUPMENU_builtin_class = (HBRUSH)(COLOR_MENU + 1) /* brush */ }; - -/* INTERNAL FUNCTIONS ********************************************************/ - -/* Rip the fun and easy to use and fun WINE unicode string manipulation routines. - * Of course I didnt copy the ASM code because we want this to be portable - * and it needs to go away. - */ - #ifndef GET_WORD #define GET_WORD(ptr) (*(WORD *)(ptr)) #endif @@ -107,13 +106,6 @@ const struct builtin_class_descr POPUPMENU_builtin_class = HFONT hMenuFont = NULL; HFONT hMenuFontBold = NULL; -/* Flag set by EndMenu() to force an exit from menu tracking */ -static BOOL fEndMenu = FALSE; - -/* Use global popup window because there's no way 2 menus can - * be tracked at the same time. */ -static HWND TopPopup; - /* Dimension of the menu bitmaps */ static HBITMAP BmpSysMenu = NULL; @@ -293,71 +285,6 @@ MenuLoadBitmaps(VOID) } } -/*********************************************************************** - * MenuGetBitmapItemSize - * - * Get the size of a bitmap item. - */ -static void FASTCALL -MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *Size, HWND WndOwner) -{ - BITMAP Bm; - HBITMAP Bmp = lpitem->hbmpItem; - - Size->cx = Size->cy = 0; - - /* check if there is a magic menu item associated with this item */ - if (IS_MAGIC_BITMAP(Bmp)) - { - switch((INT_PTR) Bmp) - { - case (INT_PTR)HBMMENU_CALLBACK: - { - MEASUREITEMSTRUCT measItem; - measItem.CtlType = ODT_MENU; - measItem.CtlID = 0; - measItem.itemID = lpitem->wID; - measItem.itemWidth = lpitem->Rect.right - lpitem->Rect.left; - measItem.itemHeight = lpitem->Rect.bottom - lpitem->Rect.top; - measItem.itemData = lpitem->dwItemData; - SendMessageW( WndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem); - Size->cx = measItem.itemWidth; - Size->cy = measItem.itemHeight; - return; - } - break; - - case (INT_PTR) HBMMENU_SYSTEM: - if (0 != lpitem->dwItemData) - { - Bmp = (HBITMAP) lpitem->dwItemData; - break; - } - /* fall through */ - case (INT_PTR) HBMMENU_MBAR_RESTORE: - case (INT_PTR) HBMMENU_MBAR_MINIMIZE: - case (INT_PTR) HBMMENU_MBAR_CLOSE: - case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D: - case (INT_PTR) HBMMENU_MBAR_CLOSE_D: - case (INT_PTR) HBMMENU_POPUP_CLOSE: - case (INT_PTR) HBMMENU_POPUP_RESTORE: - case (INT_PTR) HBMMENU_POPUP_MAXIMIZE: - case (INT_PTR) HBMMENU_POPUP_MINIMIZE: - /* FIXME: Why we need to subtract these magic values? */ - /* to make them smaller than the menu bar? */ - Size->cx = GetSystemMetrics(SM_CXSIZE) - 2; - Size->cy = GetSystemMetrics(SM_CYSIZE) - 4; - return; - } - } - - if (GetObjectW(Bmp, sizeof(BITMAP), &Bm)) - { - Size->cx = Bm.bmWidth; - Size->cy = Bm.bmHeight; - } -} - /*********************************************************************** * MenuDrawPopupGlyph * @@ -423,95 +350,224 @@ MenuDrawPopupGlyph(HDC dc, LPRECT r, INT_PTR popupMagic, BOOL inactive, BOOL hil } /*********************************************************************** - * MenuDrawBitmapItem + * MenuFindItemByKey * - * Draw a bitmap item. + * Find the menu item selected by a key press. + * Return item id, -1 if none, -2 if we should close the menu. */ -static void FASTCALL -MenuDrawBitmapItem(HDC Dc, PROSMENUITEMINFO Item, const RECT *Rect, - HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar) +static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo, + WCHAR Key, BOOL ForceMenuChar) +{ + ROSMENUINFO SysMenuInfo; + PROSMENUITEMINFO Items, ItemInfo; + LRESULT MenuChar; + UINT i; + + TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo); + + if (NULL == MenuInfo || ! IsMenu(MenuInfo->Self)) + { + if (MenuGetRosMenuInfo(&SysMenuInfo, GetSystemMenu(WndOwner, FALSE))) + { + MenuInfo = &SysMenuInfo; + } + else + { + MenuInfo = NULL; + } + } + + if (NULL != MenuInfo) + { + if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &Items) <= 0) + { + return -1; + } + if (! ForceMenuChar) + { + Key = toupperW(Key); + ItemInfo = Items; + for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++) + { + if ((ItemInfo->Text) && NULL != ItemInfo->dwTypeData) + { + WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2; + do + { + p = strchrW(p + 2, '&'); + } + while (NULL != p && L'&' == p[1]); + if (NULL != p && (toupperW(p[1]) == Key)) + { + return i; + } + } + } + } + + MenuChar = SendMessageW(WndOwner, WM_MENUCHAR, + MAKEWPARAM(Key, MenuInfo->Flags), (LPARAM) MenuInfo->Self); + if (2 == HIWORD(MenuChar)) + { + return LOWORD(MenuChar); + } + if (1 == HIWORD(MenuChar)) + { + return (UINT) (-2); + } + } + + return (UINT)(-1); +} + +/*********************************************************************** + * MenuGetBitmapItemSize + * + * Get the size of a bitmap item. + */ +static void FASTCALL MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *size, + HWND WndOwner) { - BITMAP Bm; - DWORD Rop; - HDC DcMem; - HBITMAP Bmp; - int w = Rect->right - Rect->left; - int h = Rect->bottom - Rect->top; - int BmpXoffset = 0; - int Left, Top; - HBITMAP hbmpToDraw = (HBITMAP) Item->hbmpItem; - Bmp = hbmpToDraw; - - /* Check if there is a magic menu item associated with this item */ - if (IS_MAGIC_BITMAP(hbmpToDraw)) - { - UINT Flags = 0; - RECT r; - - r = *Rect; - switch ((INT_PTR)hbmpToDraw) + BITMAP bm; + HBITMAP bmp = lpitem->hbmpItem; + + size->cx = size->cy = 0; + + /* check if there is a magic menu item associated with this item */ + if (IS_MAGIC_BITMAP(bmp)) + { + switch((INT_PTR) bmp) { + case (INT_PTR)HBMMENU_CALLBACK: + { + MEASUREITEMSTRUCT measItem; + measItem.CtlType = ODT_MENU; + measItem.CtlID = 0; + measItem.itemID = lpitem->wID; + measItem.itemWidth = lpitem->Rect.right - lpitem->Rect.left; + measItem.itemHeight = lpitem->Rect.bottom - lpitem->Rect.top; + measItem.itemData = lpitem->dwItemData; + SendMessageW( WndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem); + size->cx = measItem.itemWidth; + size->cy = measItem.itemHeight; + return; + } + break; + case (INT_PTR) HBMMENU_SYSTEM: - if (NULL != Item->dwTypeData) + if (0 != lpitem->dwItemData) { - Bmp = (HBITMAP)Item->dwTypeData; - if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm)) - { - return; - } + bmp = (HBITMAP) lpitem->dwItemData; + break; } + /* fall through */ + case (INT_PTR) HBMMENU_MBAR_RESTORE: + case (INT_PTR) HBMMENU_MBAR_MINIMIZE: + case (INT_PTR) HBMMENU_MBAR_CLOSE: + case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D: + case (INT_PTR) HBMMENU_MBAR_CLOSE_D: + case (INT_PTR) HBMMENU_POPUP_CLOSE: + case (INT_PTR) HBMMENU_POPUP_RESTORE: + case (INT_PTR) HBMMENU_POPUP_MAXIMIZE: + case (INT_PTR) HBMMENU_POPUP_MINIMIZE: + /* FIXME: Why we need to subtract these magic values? */ + /* to make them smaller than the menu bar? */ + size->cx = GetSystemMetrics(SM_CXSIZE) - 2; + size->cy = GetSystemMetrics(SM_CYSIZE) - 4; + return; + } + } + + if (GetObjectW(bmp, sizeof(BITMAP), &bm)) + { + size->cx = bm.bmWidth; + size->cy = bm.bmHeight; + } +} + +/*********************************************************************** + * MenuDrawBitmapItem + * + * Draw a bitmap item. + */ +static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const RECT *rect, + HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar) +{ + BITMAP bm; + DWORD rop; + HDC hdcMem; + HBITMAP bmp; + int w = rect->right - rect->left; + int h = rect->bottom - rect->top; + int bmp_xoffset = 0; + int left, top; + HBITMAP hbmToDraw = lpitem->hbmpItem; + bmp = hbmToDraw; + + /* Check if there is a magic menu item associated with this item */ + if (IS_MAGIC_BITMAP(hbmToDraw)) + { + UINT flags = 0; + RECT r; + + r = *rect; + switch ((INT_PTR)hbmToDraw) + { + case (INT_PTR)HBMMENU_SYSTEM: + if (lpitem->dwTypeData) + { + bmp = (HBITMAP)lpitem->dwTypeData; + if (!GetObjectW( bmp, sizeof(bm), &bm )) return; + } else - { + { if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); - Bmp = BmpSysMenu; - if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm)) - { - return; - } + bmp = BmpSysMenu; + if (! GetObjectW(bmp, sizeof(bm), &bm)) return; /* only use right half of the bitmap */ - BmpXoffset = Bm.bmWidth / 2; - Bm.bmWidth -= BmpXoffset; - } + bmp_xoffset = bm.bmWidth / 2; + bm.bmWidth -= bmp_xoffset; + } goto got_bitmap; - case (INT_PTR) HBMMENU_MBAR_RESTORE: - Flags = DFCS_CAPTIONRESTORE; + case (INT_PTR)HBMMENU_MBAR_RESTORE: + flags = DFCS_CAPTIONRESTORE; break; - case (INT_PTR) HBMMENU_MBAR_MINIMIZE: + case (INT_PTR)HBMMENU_MBAR_MINIMIZE: r.right += 1; - Flags = DFCS_CAPTIONMIN; + flags = DFCS_CAPTIONMIN; break; - case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D: + case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D: r.right += 1; - Flags = DFCS_CAPTIONMIN | DFCS_INACTIVE; + flags = DFCS_CAPTIONMIN | DFCS_INACTIVE; break; - case (INT_PTR) HBMMENU_MBAR_CLOSE: - Flags = DFCS_CAPTIONCLOSE; + case (INT_PTR)HBMMENU_MBAR_CLOSE: + flags = DFCS_CAPTIONCLOSE; break; - case (INT_PTR) HBMMENU_MBAR_CLOSE_D: - Flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE; + case (INT_PTR)HBMMENU_MBAR_CLOSE_D: + flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE; break; - case (INT_PTR) HBMMENU_CALLBACK: + case (INT_PTR)HBMMENU_CALLBACK: { DRAWITEMSTRUCT drawItem; POINT origorg; drawItem.CtlType = ODT_MENU; drawItem.CtlID = 0; - drawItem.itemID = Item->wID; + drawItem.itemID = lpitem->wID; drawItem.itemAction = odaction; - drawItem.itemState = (Item->fState & MF_CHECKED)?ODS_CHECKED:0; - drawItem.itemState |= (Item->fState & MF_DEFAULT)?ODS_DEFAULT:0; - drawItem.itemState |= (Item->fState & MF_DISABLED)?ODS_DISABLED:0; - drawItem.itemState |= (Item->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0; - drawItem.itemState |= (Item->fState & MF_HILITE)?ODS_SELECTED:0; + drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0; + drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0; + drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0; + drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0; + drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0; drawItem.hwndItem = (HWND)hmenu; - drawItem.hDC = Dc; - drawItem.rcItem = *Rect; - drawItem.itemData = Item->dwItemData; + drawItem.hDC = hdc; + drawItem.rcItem = *rect; + drawItem.itemData = lpitem->dwItemData; /* some applications make this assumption on the DC's origin */ - SetViewportOrgEx( Dc, Item->Rect.left, Item->Rect.top, &origorg); - OffsetRect( &drawItem.rcItem, - Item->Rect.left, - Item->Rect.top); + SetViewportOrgEx( hdc, lpitem->Rect.left, lpitem->Rect.top, &origorg); + OffsetRect( &drawItem.rcItem, - lpitem->Rect.left, - lpitem->Rect.top); SendMessageW( WndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem); - SetViewportOrgEx( Dc, origorg.x, origorg.y, NULL); + SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL); return; } break; @@ -520,396 +576,736 @@ MenuDrawBitmapItem(HDC Dc, PROSMENUITEMINFO Item, const RECT *Rect, case (INT_PTR) HBMMENU_POPUP_RESTORE: case (INT_PTR) HBMMENU_POPUP_MAXIMIZE: case (INT_PTR) HBMMENU_POPUP_MINIMIZE: - MenuDrawPopupGlyph(Dc, &r, (INT_PTR)hbmpToDraw, Item->fState & MF_GRAYED, Item->fState & MF_HILITE); + MenuDrawPopupGlyph(hdc, &r, (INT_PTR)hbmToDraw, lpitem->fState & MF_GRAYED, lpitem->fState & MF_HILITE); return; } InflateRect(&r, -1, -1); - if (0 != (Item->fState & MF_HILITE)) - { - Flags |= DFCS_PUSHED; - } - DrawFrameControl(Dc, &r, DFC_CAPTION, Flags); + if (0 != (lpitem->fState & MF_HILITE)) + { + flags |= DFCS_PUSHED; + } + DrawFrameControl(hdc, &r, DFC_CAPTION, flags); return; } - if (NULL == Bmp || ! GetObjectW(Bmp, sizeof(BITMAP), &Bm)) - { - return; - } + if (!bmp || !GetObjectW( bmp, sizeof(bm), &bm )) return; -got_bitmap: - DcMem = CreateCompatibleDC(Dc); - SelectObject(DcMem, Bmp); + got_bitmap: + hdcMem = CreateCompatibleDC( hdc ); + SelectObject( hdcMem, bmp ); - /* handle fontsize > bitmap_height */ - Top = (Bm.bmHeight < h) ? Rect->top + (h - Bm.bmHeight) / 2 : Rect->top; - Left = Rect->left; - Rop= ((Item->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmpToDraw)) ? NOTSRCCOPY : SRCCOPY; - if ((Item->fState & MF_HILITE) && Item->hbmpItem) - { - SetBkColor(Dc, GetSysColor(COLOR_HIGHLIGHT)); - } - BitBlt(Dc, Left, Top, w, h, DcMem, BmpXoffset, 0, Rop); - DeleteDC(DcMem); + /* handle fontsize > bitmap_height */ + top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top; + left=rect->left; + rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY; + if ((lpitem->fState & MF_HILITE) && lpitem->hbmpItem) + SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); + BitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop ); + DeleteDC( hdcMem ); } /*********************************************************************** - * MenuDrawMenuItem + * MenuCalcItemSize * - * Draw a single menu item. + * Calculate the size of the menu item and store it in lpitem->rect. */ -static void FASTCALL -MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC Dc, - PROSMENUITEMINFO Item, UINT Height, BOOL MenuBar, UINT Action) +static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMENUINFO MenuInfo, HWND hwndOwner, + INT orgX, INT orgY, BOOL menuBar) { - RECT Rect; - PWCHAR Text; - BOOL flat_menu = FALSE; - int bkgnd; - PWND Wnd = ValidateHwnd(hWnd); + WCHAR *p; + UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); + INT itemheight = 0; - if (!Wnd) - return; + TRACE("dc=%x owner=%x (%d,%d)\n", hdc, hwndOwner, orgX, orgY); - if (0 != (Item->fType & MF_SYSMENU)) + MenuCharSize.cx = GdiGetCharDimensions( hdc, NULL, &MenuCharSize.cy ); + + SetRect( &lpitem->Rect, orgX, orgY, orgX, orgY ); + + if (lpitem->fType & MF_OWNERDRAW) { - if ( (Wnd->style & WS_MINIMIZE)) - { - UserGetInsideRectNC(Wnd, &Rect); - UserDrawSysMenuButton(hWnd, Dc, &Rect, - Item->fState & (MF_HILITE | MF_MOUSESELECT)); - } - return; + MEASUREITEMSTRUCT mis; + mis.CtlType = ODT_MENU; + mis.CtlID = 0; + mis.itemID = lpitem->wID; + mis.itemData = lpitem->dwItemData; + mis.itemHeight = HIWORD( GetDialogBaseUnits()); + mis.itemWidth = 0; + SendMessageW( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)&mis ); + /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average + * width of a menufont character to the width of an owner-drawn menu. + */ + lpitem->Rect.right += mis.itemWidth + 2 * MenuCharSize.cx; + + if (menuBar) { + /* under at least win95 you seem to be given a standard + height for the menu and the height value is ignored */ + lpitem->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE); + } else + lpitem->Rect.bottom += mis.itemHeight; + + TRACE("id=%04lx size=%dx%d\n", + lpitem->wID, mis.itemWidth, mis.itemHeight); + return; } - SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); - bkgnd = (MenuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU; + if (lpitem->fType & MF_SEPARATOR) + { + lpitem->Rect.bottom += SEPARATOR_HEIGHT; + if( !menuBar) + lpitem->Rect.right += check_bitmap_width + MenuCharSize.cx; + return; + } - /* Setup colors */ + lpitem->XTab = 0; - if (0 != (Item->fState & MF_HILITE)) + if (lpitem->hbmpItem) { - if (MenuBar && !flat_menu) - { - SetTextColor(Dc, GetSysColor(COLOR_MENUTEXT)); - SetBkColor(Dc, GetSysColor(COLOR_MENU)); - } - else - { - if (0 != (Item->fState & MF_GRAYED)) + SIZE size; + + if (!menuBar) { + MenuGetBitmapItemSize(lpitem, &size, hwndOwner ); + /* Keep the size of the bitmap in callback mode to be able + * to draw it correctly */ + lpitem->Rect.right = lpitem->Rect.left + size.cx; + if (MenuInfo->maxBmpSize.cx < abs(size.cx) + MENU_ITEM_HBMP_SPACE || + MenuInfo->maxBmpSize.cy < abs(size.cy)) { - SetTextColor(Dc, GetSysColor(COLOR_GRAYTEXT)); + MenuInfo->maxBmpSize.cx = abs(size.cx) + MENU_ITEM_HBMP_SPACE; + MenuInfo->maxBmpSize.cy = abs(size.cy); } - else - { - SetTextColor(Dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + MenuSetRosMenuInfo(MenuInfo); + itemheight = size.cy + 2; + + if( !(MenuInfo->dwStyle & MNS_NOCHECK)) + lpitem->Rect.right += 2 * check_bitmap_width; + lpitem->Rect.right += 4 + MenuCharSize.cx; + lpitem->XTab = lpitem->Rect.right; + lpitem->Rect.right += check_bitmap_width; + } else /* hbmpItem & MenuBar */ { + MenuGetBitmapItemSize(lpitem, &size, hwndOwner ); + lpitem->Rect.right += size.cx; + if( lpitem->Text) lpitem->Rect.right += 2; + itemheight = size.cy; + + /* Special case: Minimize button doesn't have a space behind it. */ + if (lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE || + lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE_D) + lpitem->Rect.right -= 1; + } + } + else if (!menuBar) { + if( !(MenuInfo->dwStyle & MNS_NOCHECK)) + lpitem->Rect.right += check_bitmap_width; + lpitem->Rect.right += 4 + MenuCharSize.cx; + lpitem->XTab = lpitem->Rect.right; + lpitem->Rect.right += check_bitmap_width; + } + + /* it must be a text item - unless it's the system menu */ + if (!(lpitem->fType & MF_SYSMENU) && lpitem->Text) { + HFONT hfontOld = NULL; + RECT rc = lpitem->Rect; + LONG txtheight, txtwidth; + + if ( lpitem->fState & MFS_DEFAULT ) { + hfontOld = SelectObject( hdc, hMenuFontBold ); + } + if (menuBar) { + txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc, + DT_SINGLELINE|DT_CALCRECT); + lpitem->Rect.right += rc.right - rc.left; + itemheight = max( max( itemheight, txtheight), + GetSystemMetrics( SM_CYMENU) - 1); + lpitem->Rect.right += 2 * MenuCharSize.cx; + } else { + if ((p = strchrW( lpitem->dwTypeData, '\t' )) != NULL) { + RECT tmprc = rc; + LONG tmpheight; + int n = (int)( p - lpitem->dwTypeData); + /* Item contains a tab (only meaningful in popup menus) */ + /* get text size before the tab */ + txtheight = DrawTextW( hdc, lpitem->dwTypeData, n, &rc, + DT_SINGLELINE|DT_CALCRECT); + txtwidth = rc.right - rc.left; + p += 1; /* advance past the Tab */ + /* get text size after the tab */ + tmpheight = DrawTextW( hdc, p, -1, &tmprc, + DT_SINGLELINE|DT_CALCRECT); + lpitem->XTab += txtwidth; + txtheight = max( txtheight, tmpheight); + txtwidth += MenuCharSize.cx + /* space for the tab */ + tmprc.right - tmprc.left; /* space for the short cut */ + } else { + txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc, + DT_SINGLELINE|DT_CALCRECT); + txtwidth = rc.right - rc.left; + lpitem->XTab += txtwidth; } - SetBkColor(Dc, GetSysColor(COLOR_HIGHLIGHT)); + lpitem->Rect.right += 2 + txtwidth; + itemheight = max( itemheight, + max( txtheight + 2, MenuCharSize.cy + 4)); } + if (hfontOld) SelectObject (hdc, hfontOld); + } else if( menuBar) { + itemheight = max( itemheight, GetSystemMetrics(SM_CYMENU)-1); } - else + lpitem->Rect.bottom += itemheight; + TRACE("(%ld,%ld)-(%ld,%ld)\n", lpitem->Rect.left, lpitem->Rect.top, lpitem->Rect.right, lpitem->Rect.bottom); +} + +/*********************************************************************** + * MenuPopupMenuCalcSize + * + * Calculate the size of a popup menu. + */ +static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) +{ + ROSMENUITEMINFO lpitem; + HDC hdc; + int start, i; + int orgX, orgY, maxX, maxTab, maxTabWidth; + + MenuInfo->Width = MenuInfo->Height = 0; + if (MenuInfo->MenuItemCount == 0) { - if (0 != (Item->fState & MF_GRAYED)) - { - SetTextColor(Dc, GetSysColor(COLOR_GRAYTEXT)); - } - else - { - SetTextColor(Dc, GetSysColor(COLOR_MENUTEXT)); + MenuSetRosMenuInfo(MenuInfo); + return; + } + + hdc = GetDC(NULL); + SelectObject( hdc, hMenuFont ); + + start = 0; + maxX = 2 + 1; + + MenuInfo->maxBmpSize.cx = 0; + MenuInfo->maxBmpSize.cy = 0; + + MenuInitRosMenuItemInfo(&lpitem); + while (start < MenuInfo->MenuItemCount) + { + orgX = maxX; + orgY = 2; + + maxTab = maxTabWidth = 0; + + /* Parse items until column break or end of menu */ + for (i = start; i < MenuInfo->MenuItemCount; i++) + { + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &lpitem)) + { + MenuCleanupRosMenuItemInfo(&lpitem); + MenuSetRosMenuInfo(MenuInfo); + return; + } + if (i != start && + (lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; + + MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE); + if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &lpitem)) + { + MenuCleanupRosMenuItemInfo(&lpitem); + MenuSetRosMenuInfo(MenuInfo); + return; + } +// Not sure here,, The patch from wine removes this. +// if ((lpitem.fType & MF_MENUBARBREAK) != 0) +// { +// OrgX++; +// } + maxX = max(maxX, lpitem.Rect.right); + orgY = lpitem.Rect.bottom; + if ((lpitem.Text) && lpitem.XTab ) + { + maxTab = max( maxTab, lpitem.XTab ); + maxTabWidth = max(maxTabWidth, lpitem.Rect.right - lpitem.XTab); + } } - SetBkColor(Dc, GetSysColor(bkgnd)); - } - - Rect = Item->Rect; - - if (Item->fType & MF_OWNERDRAW) - { - /* - ** Experimentation under Windows reveals that an owner-drawn - ** menu is given the rectangle which includes the space it requested - ** in its response to WM_MEASUREITEM _plus_ width for a checkmark - ** and a popup-menu arrow. This is the value of lpitem->rect. - ** Windows will leave all drawing to the application except for - ** the popup-menu arrow. Windows always draws that itself, after - ** the menu owner has finished drawing. - */ - DRAWITEMSTRUCT dis; - - dis.CtlType = ODT_MENU; - dis.CtlID = 0; - dis.itemID = Item->wID; - dis.itemData = (DWORD)Item->dwItemData; - dis.itemState = 0; - if (0 != (Item->fState & MF_CHECKED)) + + /* Finish the column (set all items to the largest width found) */ + maxX = max( maxX, maxTab + maxTabWidth ); + while (start < i) { - dis.itemState |= ODS_CHECKED; - } - if (0 != (Item->fState & MF_GRAYED)) + if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem)) + { + lpitem.Rect.right = maxX; + if ((lpitem.Text) && 0 != lpitem.XTab) + { + lpitem.XTab = maxTab; + } + MenuSetRosMenuItemInfo(MenuInfo->Self, start, &lpitem); + } + start++; + } + MenuInfo->Height = max(MenuInfo->Height, orgY); + } + + MenuInfo->Width = maxX; + + /* space for 3d border */ + MenuInfo->Height += 2; + MenuInfo->Width += 2; + + MenuCleanupRosMenuItemInfo(&lpitem); + MenuSetRosMenuInfo(MenuInfo); + ReleaseDC( 0, hdc ); +} + +/*********************************************************************** + * MenuMenuBarCalcSize + * + * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap + * height is off by 1 pixel which causes lengthy window relocations when + * active document window is maximized/restored. + * + * Calculate the size of the menu bar. + */ +static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect, + PROSMENUINFO MenuInfo, HWND hwndOwner ) +{ + ROSMENUITEMINFO ItemInfo; + int start, i, orgX, orgY, maxY, helpPos; + + if ((lprect == NULL) || (MenuInfo == NULL)) return; + if (MenuInfo->MenuItemCount == 0) return; + TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom); + MenuInfo->Width = lprect->right - lprect->left; + MenuInfo->Height = 0; + maxY = lprect->top + 1; + start = 0; + helpPos = -1; + + MenuInfo->maxBmpSize.cx = 0; + MenuInfo->maxBmpSize.cy = 0; + + MenuInitRosMenuItemInfo(&ItemInfo); + while (start < MenuInfo->MenuItemCount) + { + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo)) { - dis.itemState |= ODS_GRAYED | ODS_DISABLED; + MenuCleanupRosMenuItemInfo(&ItemInfo); + return; } - if (0 != (Item->fState & MF_HILITE)) + orgX = lprect->left; + orgY = maxY; + + /* Parse items until line break or end of menu */ + for (i = start; i < MenuInfo->MenuItemCount; i++) + { + if ((helpPos == -1) && (ItemInfo.fType & MF_RIGHTJUSTIFY)) helpPos = i; + if ((i != start) && + (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; + + TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY); + MenuCalcItemSize(hdc, &ItemInfo, MenuInfo, hwndOwner, orgX, orgY, TRUE); + if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo)) + { + MenuCleanupRosMenuItemInfo(&ItemInfo); + return; + } + + if (ItemInfo.Rect.right > lprect->right) + { + if (i != start) break; + else ItemInfo.Rect.right = lprect->right; + } + maxY = max( maxY, ItemInfo.Rect.bottom ); + orgX = ItemInfo.Rect.right; + if (i + 1 < MenuInfo->MenuItemCount) + { + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo)) + { + MenuCleanupRosMenuItemInfo(&ItemInfo); + return; + } + } + } + +/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the +HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */ +#if 0 + /* Finish the line (set all items to the largest height found) */ + while (start < i) { - dis.itemState |= ODS_SELECTED; + if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo)) + { + ItemInfo.Rect.bottom = maxY; + MenuSetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo); + } + start++; } - dis.itemAction = Action; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */ - dis.hwndItem = (HWND) MenuInfo->Self; - dis.hDC = Dc; - dis.rcItem = Rect; - TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, " - "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", hWnd, - dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem, - dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right, - dis.rcItem.bottom); - SendMessageW(WndOwner, WM_DRAWITEM, 0, (LPARAM) &dis); - /* Draw the popup-menu arrow */ - if (0 != (Item->fType & MF_POPUP)) +#else + start = i; /* This works! */ +#endif + } + + lprect->bottom = maxY; + MenuInfo->Height = lprect->bottom - lprect->top; + MenuSetRosMenuInfo(MenuInfo); + + if (helpPos != -1) + { + /* Flush right all items between the MF_RIGHTJUSTIFY and */ + /* the last item (if several lines, only move the last line) */ + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo)) { - RECT rectTemp; - CopyRect(&rectTemp, &Rect); - rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK); - DrawFrameControl(Dc, &rectTemp, DFC_MENU, DFCS_MENUARROW); + MenuCleanupRosMenuItemInfo(&ItemInfo); + return; } - return; + orgY = ItemInfo.Rect.top; + orgX = lprect->right; + for (i = MenuInfo->MenuItemCount - 1; helpPos <= i; i--) + { + if (i < helpPos) + { + break; /* done */ + } + if (ItemInfo.Rect.top != orgY) + { + break; /* Other line */ + } + if (orgX <= ItemInfo.Rect.right) + { + break; /* Too far right already */ + } + ItemInfo.Rect.left += orgX - ItemInfo.Rect.right; + ItemInfo.Rect.right = orgX; + orgX = ItemInfo.Rect.left; + MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo); + if (helpPos + 1 <= i && + ! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo)) + { + MenuCleanupRosMenuItemInfo(&ItemInfo); + return; + } + } } - TRACE("rect={%ld,%ld,%ld,%ld}\n", Item->Rect.left, Item->Rect.top, - Item->Rect.right, Item->Rect.bottom); + MenuCleanupRosMenuItemInfo(&ItemInfo); +} - if (MenuBar && 0 != (Item->fType & MF_SEPARATOR)) - { - return; - } +/*********************************************************************** + * MenuDrawMenuItem + * + * Draw a single menu item. + */ +static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC hdc, + PROSMENUITEMINFO lpitem, UINT Height, BOOL menuBar, UINT odaction) +{ + RECT rect; + PWCHAR Text; + BOOL flat_menu = FALSE; + int bkgnd; + PWND Wnd = ValidateHwnd(hWnd); - if (Item->fState & MF_HILITE) - { - if (flat_menu) + if (!Wnd) + return; + + if (lpitem->fType & MF_SYSMENU) + { + if ( (Wnd->style & WS_MINIMIZE)) + { + UserGetInsideRectNC(Wnd, &rect); + UserDrawSysMenuButton(hWnd, hdc, &rect, + lpitem->fState & (MF_HILITE | MF_MOUSESELECT)); + } + return; + } + + SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); + bkgnd = (menuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU; + + /* Setup colors */ + + if (lpitem->fState & MF_HILITE) { - InflateRect (&Rect, -1, -1); - FillRect(Dc, &Rect, GetSysColorBrush(COLOR_MENUHILIGHT)); - InflateRect (&Rect, 1, 1); - FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT)); + if(menuBar && !flat_menu) { + SetTextColor(hdc, GetSysColor(COLOR_MENUTEXT)); + SetBkColor(hdc, GetSysColor(COLOR_MENU)); + } else { + if (lpitem->fState & MF_GRAYED) + SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); + else + SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); + } } else { - if (MenuBar) - { - DrawEdge(Dc, &Rect, BDR_SUNKENOUTER, BF_RECT); - } - else - { - FillRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT)); - } + if (lpitem->fState & MF_GRAYED) + SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) ); + else + SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) ); + SetBkColor( hdc, GetSysColor( bkgnd ) ); + } + + rect = lpitem->Rect; + + if (lpitem->fType & MF_OWNERDRAW) + { + /* + ** Experimentation under Windows reveals that an owner-drawn + ** menu is given the rectangle which includes the space it requested + ** in its response to WM_MEASUREITEM _plus_ width for a checkmark + ** and a popup-menu arrow. This is the value of lpitem->rect. + ** Windows will leave all drawing to the application except for + ** the popup-menu arrow. Windows always draws that itself, after + ** the menu owner has finished drawing. + */ + DRAWITEMSTRUCT dis; + + dis.CtlType = ODT_MENU; + dis.CtlID = 0; + dis.itemID = lpitem->wID; + dis.itemData = (DWORD)lpitem->dwItemData; + dis.itemState = 0; + if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED; + if (lpitem->fState & MF_GRAYED) dis.itemState |= ODS_GRAYED | ODS_DISABLED; + if (lpitem->fState & MF_HILITE) dis.itemState |= ODS_SELECTED; + dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */ + dis.hwndItem = (HWND) MenuInfo->Self; + dis.hDC = hdc; + dis.rcItem = rect; + TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, " + "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", hWnd, + dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem, + dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right, + dis.rcItem.bottom); + SendMessageW(WndOwner, WM_DRAWITEM, 0, (LPARAM) &dis); + /* Draw the popup-menu arrow */ + if (lpitem->fType & MF_POPUP) + { + RECT rectTemp; + CopyRect(&rectTemp, &rect); + rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK); + DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW); + } + return; } - } - else - { - FillRect(Dc, &Rect, GetSysColorBrush(bkgnd)); - } - SetBkMode(Dc, TRANSPARENT); + if (menuBar && (lpitem->fType & MF_SEPARATOR)) return; - /* vertical separator */ - if (! MenuBar && 0 != (Item->fType & MF_MENUBARBREAK)) - { - HPEN oldPen; - RECT rc = Rect; - rc.left -= 3; - rc.top = 3; - rc.bottom = Height - 3; - if (flat_menu) - { - oldPen = SelectObject( Dc, GetStockObject(DC_PEN) ); - SetDCPenColor(Dc, GetSysColor(COLOR_BTNSHADOW)); - MoveToEx( Dc, rc.left, rc.top, NULL ); - LineTo( Dc, rc.left, rc.bottom ); - SelectObject( Dc, oldPen ); + if (lpitem->fState & MF_HILITE) + { + if (flat_menu) + { + InflateRect (&rect, -1, -1); + FillRect(hdc, &rect, GetSysColorBrush(COLOR_MENUHILIGHT)); + InflateRect (&rect, 1, 1); + FrameRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT)); + } + else + { + if(menuBar) + DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT); + else + FillRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT)); + } } else - DrawEdge(Dc, &rc, EDGE_ETCHED, BF_LEFT); - } + FillRect( hdc, &rect, GetSysColorBrush(bkgnd) ); - /* horizontal separator */ - if (0 != (Item->fType & MF_SEPARATOR)) - { - HPEN oldPen; - RECT rc = Rect; - rc.left++; - rc.right--; - rc.top += SEPARATOR_HEIGHT / 2; - if (flat_menu) - { - oldPen = SelectObject( Dc, GetStockObject(DC_PEN) ); - SetDCPenColor(Dc, GetSysColor(COLOR_BTNSHADOW)); - MoveToEx( Dc, rc.left, rc.top, NULL ); - LineTo( Dc, rc.right, rc.top ); - SelectObject( Dc, oldPen ); + SetBkMode( hdc, TRANSPARENT ); + + /* vertical separator */ + if (!menuBar && (lpitem->fType & MF_MENUBARBREAK)) + { + HPEN oldPen; + RECT rc = rect; + + rc.left -= 3; + rc.top = 3; + rc.bottom = Height - 3; + if (flat_menu) + { + oldPen = SelectObject( hdc, GetStockObject(DC_PEN) ); + SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW)); + MoveToEx( hdc, rc.left, rc.top, NULL ); + LineTo( hdc, rc.left, rc.bottom ); + SelectObject( hdc, oldPen ); + } + else + DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT); + } + + /* horizontal separator */ + if (lpitem->fType & MF_SEPARATOR) + { + HPEN oldPen; + RECT rc = rect; + + rc.left++; + rc.right--; + rc.top += SEPARATOR_HEIGHT / 2; + if (flat_menu) + { + oldPen = SelectObject( hdc, GetStockObject(DC_PEN) ); + SetDCPenColor( hdc, GetSysColor(COLOR_BTNSHADOW)); + MoveToEx( hdc, rc.left, rc.top, NULL ); + LineTo( hdc, rc.right, rc.top ); + SelectObject( hdc, oldPen ); + } + else + DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP); + return; } - else - DrawEdge(Dc, &rc, EDGE_ETCHED, BF_TOP); - return; - } #if 0 - /* helper lines for debugging */ - /* This is a very good test tool when hacking menus! (JT) 07/16/2006 */ - FrameRect(Dc, &Rect, GetStockObject(BLACK_BRUSH)); - SelectObject(Dc, GetStockObject(DC_PEN)); - SetDCPenColor(Dc, GetSysColor(COLOR_WINDOWFRAME)); - MoveToEx(Dc, Rect.left, (Rect.top + Rect.bottom) / 2, NULL); - LineTo(Dc, Rect.right, (Rect.top + Rect.bottom) / 2); + /* helper lines for debugging */ + /* This is a very good test tool when hacking menus! (JT) 07/16/2006 */ + FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH)); + SelectObject(hdc, GetStockObject(DC_PEN)); + SetDCPenColor(hdc, GetSysColor(COLOR_WINDOWFRAME)); + MoveToEx(hdc, rect.left, (rect.top + rect.bottom) / 2, NULL); + LineTo(hdc, rect.right, (rect.top + rect.bottom) / 2); #endif - if (! MenuBar) - { - INT y = Rect.top + Rect.bottom; - RECT Rc = Rect; - UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK); - UINT CheckBitmapHeight = GetSystemMetrics(SM_CYMENUCHECK); - int checked = FALSE; - /* Draw the check mark - * - * FIXME: - * Custom checkmark bitmaps are monochrome but not always 1bpp. - */ - if( !(MenuInfo->dwStyle & MNS_NOCHECK)) - { - HBITMAP bm = 0 != (Item->fState & MF_CHECKED) ? Item->hbmpChecked : Item->hbmpUnchecked; - if (NULL != bm) /* we have a custom bitmap */ + if (!menuBar) + { + HBITMAP bm; + INT y = rect.top + rect.bottom; + RECT rc = rect; + int checked = FALSE; + UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); + UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK ); + /* Draw the check mark + * + * FIXME: + * Custom checkmark bitmaps are monochrome but not always 1bpp. + */ + if( !(MenuInfo->dwStyle & MNS_NOCHECK)) { + bm = (lpitem->fState & MF_CHECKED) ? lpitem->hbmpChecked : + lpitem->hbmpUnchecked; + if (bm) /* we have a custom bitmap */ + { + HDC hdcMem = CreateCompatibleDC( hdc ); + + SelectObject( hdcMem, bm ); + BitBlt( hdc, rc.left, (y - check_bitmap_height) / 2, + check_bitmap_width, check_bitmap_height, + hdcMem, 0, 0, SRCCOPY ); + DeleteDC( hdcMem ); + checked = TRUE; + } + else if (lpitem->fState & MF_CHECKED) /* standard bitmaps */ + { + RECT r; + CopyRect(&r, &rect); + r.right = r.left + GetSystemMetrics(SM_CXMENUCHECK); + DrawFrameControl( hdc, &r, DFC_MENU, + (lpitem->fType & MFT_RADIOCHECK) ? + DFCS_MENUBULLET : DFCS_MENUCHECK); + checked = TRUE; + } + } + if ( lpitem->hbmpItem ) { - HDC DcMem = CreateCompatibleDC(Dc); - SelectObject(DcMem, bm); - BitBlt(Dc, Rc.left, (y - CheckBitmapHeight) / 2, - CheckBitmapWidth, CheckBitmapHeight, - DcMem, 0, 0, SRCCOPY); - DeleteDC(DcMem); - checked = TRUE; + RECT bmpRect; + CopyRect(&bmpRect, &rect); + if (!(MenuInfo->dwStyle & MNS_CHECKORBMP) && !(MenuInfo->dwStyle & MNS_NOCHECK)) + bmpRect.left += check_bitmap_width + 2; + if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP))) + { + bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx; + MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo->Self, WndOwner, odaction, menuBar); + } } - else if (0 != (Item->fState & MF_CHECKED)) /* standard bitmaps */ + /* Draw the popup-menu arrow */ + if (lpitem->fType & MF_POPUP) { - RECT rectTemp; - CopyRect(&rectTemp, &Rect); - rectTemp.right = rectTemp.left + GetSystemMetrics(SM_CXMENUCHECK); - DrawFrameControl(Dc, &rectTemp, DFC_MENU, - 0 != (Item->fType & MFT_RADIOCHECK) ? - DFCS_MENUBULLET : DFCS_MENUCHECK); - checked = TRUE; + RECT rectTemp; + CopyRect(&rectTemp, &rect); + rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK); + DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW); } - } - if (Item->hbmpItem) - { - RECT bmpRect; - CopyRect(&bmpRect, &Rect); - if (!(MenuInfo->dwStyle & MNS_CHECKORBMP) && !(MenuInfo->dwStyle & MNS_NOCHECK)) - bmpRect.left += CheckBitmapWidth + 2; - if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP))) - { - bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx; - MenuDrawBitmapItem(Dc, Item, &bmpRect, MenuInfo->Self, WndOwner, Action, MenuBar); - } - } - /* Draw the popup-menu arrow */ - if (0 != (Item->fType & MF_POPUP)) - { - RECT rectTemp; - CopyRect(&rectTemp, &Rect); - rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK); - DrawFrameControl(Dc, &rectTemp, DFC_MENU, DFCS_MENUARROW); - } - Rect.left += 4; - if( !(MenuInfo->dwStyle & MNS_NOCHECK)) - Rect.left += CheckBitmapWidth; - Rect.right -= CheckBitmapWidth; - } - else if (Item->hbmpItem) /* Draw the bitmap */ - { - MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar); - } + rect.left += 4; + if( !(MenuInfo->dwStyle & MNS_NOCHECK)) + rect.left += check_bitmap_width; + rect.right -= check_bitmap_width; + } + else if( lpitem->hbmpItem) + { /* Draw the bitmap */ + MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo->Self, WndOwner, odaction, menuBar); + } - /* No bitmap - process text if present */ - if (Item->Text) - { - register int i = 0; - HFONT FontOld = NULL; + /* process text if present */ + if (lpitem->Text) + { + register int i = 0; + HFONT hfontOld = 0; - UINT uFormat = MenuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE - : DT_LEFT | DT_VCENTER | DT_SINGLELINE; + UINT uFormat = menuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE + : DT_LEFT | DT_VCENTER | DT_SINGLELINE; - if(MenuInfo->dwStyle & MNS_CHECKORBMP) - Rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK)); - else - Rect.left += MenuInfo->maxBmpSize.cx; + if(MenuInfo->dwStyle & MNS_CHECKORBMP) + rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK)); + else + rect.left += MenuInfo->maxBmpSize.cx; - if (0 != (Item->fState & MFS_DEFAULT)) + if ( lpitem->fState & MFS_DEFAULT ) { - FontOld = SelectObject(Dc, hMenuFontBold); + hfontOld = SelectObject(hdc, hMenuFontBold); } - if (MenuBar) - { - Rect.left += MENU_BAR_ITEMS_SPACE / 2; - Rect.right -= MENU_BAR_ITEMS_SPACE / 2; + if (menuBar) { + rect.left += MENU_BAR_ITEMS_SPACE / 2; + rect.right -= MENU_BAR_ITEMS_SPACE / 2; } - Text = (PWCHAR) Item->dwTypeData; - if(Text) - { - for (i = 0; L'\0' != Text[i]; i++) + Text = (PWCHAR) lpitem->dwTypeData; + if(Text) { - if (L'\t' == Text[i] || L'\b' == Text[i]) - { - break; - } + for (i = 0; L'\0' != Text[i]; i++) + if (Text[i] == L'\t' || Text[i] == L'\b') + break; } - } - if (0 != (Item->fState & MF_GRAYED)) - { - if (0 == (Item->fState & MF_HILITE)) - { - ++Rect.left; ++Rect.top; ++Rect.right; ++Rect.bottom; - SetTextColor(Dc, RGB(0xff, 0xff, 0xff)); - DrawTextW(Dc, Text, i, &Rect, uFormat); - --Rect.left; --Rect.top; --Rect.right; --Rect.bottom; - } - SetTextColor(Dc, RGB(0x80, 0x80, 0x80)); + if(lpitem->fState & MF_GRAYED) + { + if (!(lpitem->fState & MF_HILITE) ) + { + ++rect.left; ++rect.top; ++rect.right; ++rect.bottom; + SetTextColor(hdc, RGB(0xff, 0xff, 0xff)); + DrawTextW( hdc, Text, i, &rect, uFormat ); + --rect.left; --rect.top; --rect.right; --rect.bottom; + } + SetTextColor(hdc, RGB(0x80, 0x80, 0x80)); } - DrawTextW(Dc, Text, i, &Rect, uFormat); + DrawTextW( hdc, Text, i, &rect, uFormat); - /* paint the shortcut text */ - if (! MenuBar && L'\0' != Text[i]) /* There's a tab or flush-right char */ + /* paint the shortcut text */ + if (!menuBar && L'\0' != Text[i]) /* There's a tab or flush-right char */ { - if (L'\t' == Text[i]) + if (L'\t' == Text[i]) { - Rect.left = Item->XTab; - uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE; + rect.left = lpitem->XTab; + uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE; } - else + else { - Rect.right = Item->XTab; - uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE; + rect.right = lpitem->XTab; + uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE; } - if (0 != (Item->fState & MF_GRAYED)) + if (lpitem->fState & MF_GRAYED) { - if (0 == (Item->fState & MF_HILITE)) + if (!(lpitem->fState & MF_HILITE) ) { - ++Rect.left; ++Rect.top; ++Rect.right; ++Rect.bottom; - SetTextColor(Dc, RGB(0xff, 0xff, 0xff)); - DrawTextW(Dc, Text + i + 1, -1, &Rect, uFormat); - --Rect.left; --Rect.top; --Rect.right; --Rect.bottom; + ++rect.left; ++rect.top; ++rect.right; ++rect.bottom; + SetTextColor(hdc, RGB(0xff, 0xff, 0xff)); + DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat); + --rect.left; --rect.top; --rect.right; --rect.bottom; } - SetTextColor(Dc, RGB(0x80, 0x80, 0x80)); - } - DrawTextW(Dc, Text + i + 1, -1, &Rect, uFormat); + SetTextColor(hdc, RGB(0x80, 0x80, 0x80)); + } + DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat ); } - if (NULL != FontOld) - { - SelectObject(Dc, FontOld); - } - } + if (hfontOld) + SelectObject (hdc, hfontOld); + } } /*********************************************************************** @@ -917,59 +1313,185 @@ MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC Dc, * * Paint a popup menu. */ -static void FASTCALL -MenuDrawPopupMenu(HWND Wnd, HDC Dc, HMENU Menu) +static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu ) { - HBRUSH PrevBrush = NULL; - HPEN PrevPen; - RECT Rect; - ROSMENUINFO MenuInfo; - ROSMENUITEMINFO ItemInfo; - UINT u; + HBRUSH hPrevBrush = 0; + RECT rect; - TRACE("wnd=%x dc=%x menu=%x\n", Wnd, Dc, Menu); + TRACE("wnd=%p dc=%p menu=%p\n", hwnd, hdc, hmenu); - GetClientRect(Wnd, &Rect); + GetClientRect( hwnd, &rect ); - if (NULL != (PrevBrush = SelectObject(Dc, GetSysColorBrush(COLOR_MENU))) - && NULL != SelectObject(Dc, hMenuFont)) + if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) )) + && (SelectObject( hdc, hMenuFont))) { - Rectangle(Dc, Rect.left, Rect.top, Rect.right, Rect.bottom); + HPEN hPrevPen; - PrevPen = SelectObject(Dc, GetStockObject(NULL_PEN)); - if (NULL != PrevPen) - { - BOOL flat_menu = FALSE; + Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom ); - SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); - if (flat_menu) - FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_BTNSHADOW)); - else - DrawEdge(Dc, &Rect, EDGE_RAISED, BF_RECT); + hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) ); + if ( hPrevPen ) + { + BOOL flat_menu = FALSE; + ROSMENUINFO MenuInfo; + ROSMENUITEMINFO ItemInfo; - /* draw menu items */ + SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); + if (flat_menu) + FrameRect(hdc, &rect, GetSysColorBrush(COLOR_BTNSHADOW)); + else + DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT); - if (MenuGetRosMenuInfo(&MenuInfo, Menu) && 0 != MenuInfo.MenuItemCount) + /* draw menu items */ + if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.MenuItemCount) { - MenuInitRosMenuItemInfo(&ItemInfo); + UINT u; + + MenuInitRosMenuItemInfo(&ItemInfo); - for (u = 0; u < MenuInfo.MenuItemCount; u++) + for (u = 0; u < MenuInfo.MenuItemCount; u++) { - if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo)) + if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo)) { - MenuDrawMenuItem(Wnd, &MenuInfo, MenuInfo.WndOwner, Dc, &ItemInfo, - MenuInfo.Height, FALSE, ODA_DRAWENTIRE); + MenuDrawMenuItem(hwnd, &MenuInfo, MenuInfo.WndOwner, hdc, &ItemInfo, + MenuInfo.Height, FALSE, ODA_DRAWENTIRE); } } - MenuCleanupRosMenuItemInfo(&ItemInfo); - } - } - else + MenuCleanupRosMenuItemInfo(&ItemInfo); + } + } else + { + SelectObject( hdc, hPrevBrush ); + } + } +} + +/*********************************************************************** + * MenuDrawMenuBar + * + * Paint a menu bar. Returns the height of the menu bar. + * called from [windows/nonclient.c] + */ +UINT MenuDrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd, + BOOL suppress_draw) +{ + ROSMENUINFO lppop; + HFONT hfontOld = 0; + HMENU hMenu = GetMenu(hwnd); + + if (! MenuGetRosMenuInfo(&lppop, hMenu) || lprect == NULL) + { + return GetSystemMetrics(SM_CYMENU); + } + + if (suppress_draw) + { + hfontOld = SelectObject(hDC, hMenuFont); + + MenuMenuBarCalcSize(hDC, lprect, &lppop, hwnd); + + lprect->bottom = lprect->top + lppop.Height; + + if (hfontOld) SelectObject( hDC, hfontOld); + return lppop.Height; + } + else + return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL); +} + +/*********************************************************************** + * MenuShowPopup + * + * Display a popup menu. + */ +static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT flags, + INT x, INT y, INT xanchor, INT yanchor ) +{ + ROSMENUINFO MenuInfo; + ROSMENUITEMINFO ItemInfo; + UINT width, height; + POINT pt; + HMONITOR monitor; + MONITORINFO info; + + TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", + hwndOwner, hmenu, id, x, y, xanchor, yanchor); + + if (! MenuGetRosMenuInfo(&MenuInfo, hmenu)) return FALSE; + if (MenuInfo.FocusedItem != NO_SELECTED_ITEM) + { + MenuInitRosMenuItemInfo(&ItemInfo); + if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo)) { - SelectObject(Dc, PrevBrush); - } + ItemInfo.fMask |= MIIM_STATE; + ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT); + MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo); + } + MenuCleanupRosMenuItemInfo(&ItemInfo); + MenuInfo.FocusedItem = NO_SELECTED_ITEM; } + + /* store the owner for DrawItem */ + MenuInfo.WndOwner = hwndOwner; + MenuSetRosMenuInfo(&MenuInfo); + + MenuPopupMenuCalcSize(&MenuInfo, hwndOwner); + + /* adjust popup menu pos so that it fits within the desktop */ + + width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER); + height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER); + + /* FIXME: should use item rect */ + pt.x = x; + pt.y = y; + monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST ); + info.cbSize = sizeof(info); + GetMonitorInfoW( monitor, &info ); + + if( flags & TPM_RIGHTALIGN ) x -= width; + if( flags & TPM_CENTERALIGN ) x -= width / 2; + + if( flags & TPM_BOTTOMALIGN ) y -= height; + if( flags & TPM_VCENTERALIGN ) y -= height / 2; + + if( x + width > info.rcWork.right) + { + if( xanchor && x >= width - xanchor ) + x -= width - xanchor; + + if( x + width > info.rcWork.right) + x = info.rcWork.right - width; + } + if( x < info.rcWork.left ) x = info.rcWork.left; + + if( y + height > info.rcWork.bottom) + { + if( yanchor && y >= height + yanchor ) + y -= height + yanchor; + + if( y + height > info.rcWork.bottom) + y = info.rcWork.bottom - height; + } + if( y < info.rcWork.top ) y = info.rcWork.top; + + /* NOTE: In Windows, top menu popup is not owned. */ + MenuInfo.Wnd = CreateWindowExW( 0, POPUPMENU_CLASS_ATOMW, NULL, + WS_POPUP, x, y, width, height, + hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE), + (LPVOID) MenuInfo.Self); + if ( !MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) return FALSE; + if (!TopPopup) { + TopPopup = MenuInfo.Wnd; + } + + /* Display the window */ + + SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + UpdateWindow( MenuInfo.Wnd ); + return TRUE; } LRESULT WINAPI @@ -1284,486 +1806,56 @@ User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength) } -BOOL -MenuInit(VOID) -{ - NONCLIENTMETRICSW ncm; - - /* get the menu font */ - if(!hMenuFont || !hMenuFontBold) - { - ncm.cbSize = sizeof(ncm); - if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)) - { - DbgPrint("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n"); - return FALSE; - } - - hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont); - if(hMenuFont == NULL) - { - DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n"); - return FALSE; - } - - ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000); - hMenuFontBold = CreateFontIndirectW(&ncm.lfMenuFont); - if(hMenuFontBold == NULL) - { - DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n"); - DeleteObject(hMenuFont); - hMenuFont = NULL; - return FALSE; - } - } - - return TRUE; -} - - -VOID -MenuCleanup(VOID) -{ - if (hMenuFont) - { - DeleteObject(hMenuFont); - hMenuFont = NULL; - } - - if (hMenuFontBold) - { - DeleteObject(hMenuFontBold); - hMenuFontBold = NULL; - } -} - - - -/*********************************************************************** - * MenuCalcItemSize - * - * Calculate the size of the menu item and store it in ItemInfo->rect. - */ -static void FASTCALL -MenuCalcItemSize(HDC Dc, PROSMENUITEMINFO ItemInfo, PROSMENUINFO MenuInfo, HWND WndOwner, - INT OrgX, INT OrgY, BOOL MenuBar) -{ - PWCHAR p; - INT itemheight = 0; - UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK); - - TRACE("dc=%x owner=%x (%d,%d)\n", Dc, WndOwner, OrgX, OrgY); - - MenuCharSize.cx = GdiGetCharDimensions( Dc, NULL, &MenuCharSize.cy ); - - SetRect(&ItemInfo->Rect, OrgX, OrgY, OrgX, OrgY); - - if (0 != (ItemInfo->fType & MF_OWNERDRAW)) - { - /* - ** Experimentation under Windows reveals that an owner-drawn - ** menu is expected to return the size of the content part of - ** the menu item, not including the checkmark nor the submenu - ** arrow. Windows adds those values itself and returns the - ** enlarged rectangle on subsequent WM_DRAWITEM messages. - */ - MEASUREITEMSTRUCT mis; - mis.CtlType = ODT_MENU; - mis.CtlID = 0; - mis.itemID = ItemInfo->wID; - mis.itemData = (DWORD)ItemInfo->dwItemData; - mis.itemHeight = HIWORD( GetDialogBaseUnits()); - mis.itemWidth = 0; - SendMessageW(WndOwner, WM_MEASUREITEM, 0, (LPARAM) &mis); - /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average - * width of a menufont character to the width of an owner-drawn menu. - */ - ItemInfo->Rect.right += mis.itemWidth + 2 * MenuCharSize.cx; - - if (MenuBar) - { - /* under at least win95 you seem to be given a standard - height for the menu and the height value is ignored */ - ItemInfo->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE); - } - else - { - ItemInfo->Rect.bottom += mis.itemHeight; - } - - TRACE("id=%04x size=%dx%d\n", ItemInfo->wID, mis.itemWidth, mis.itemHeight); - return; - } - - if (0 != (ItemInfo->fType & MF_SEPARATOR)) - { - ItemInfo->Rect.bottom += SEPARATOR_HEIGHT; - if( !MenuBar) - ItemInfo->Rect.right += CheckBitmapWidth + MenuCharSize.cx; - return; - } - - ItemInfo->XTab = 0; - - if (ItemInfo->hbmpItem) - { - SIZE Size; - - if (!MenuBar) /* hbmpItem */ - { - MenuGetBitmapItemSize(ItemInfo, &Size, WndOwner ); - /* Keep the size of the bitmap in callback mode to be able - * to draw it correctly */ - ItemInfo->Rect.right = ItemInfo->Rect.left + Size.cx; - if (MenuInfo->maxBmpSize.cx < abs(Size.cx) + MENU_ITEM_HBMP_SPACE || - MenuInfo->maxBmpSize.cy < abs(Size.cy)) - { - MenuInfo->maxBmpSize.cx = abs(Size.cx) + MENU_ITEM_HBMP_SPACE; - MenuInfo->maxBmpSize.cy = abs(Size.cy); - } - MenuSetRosMenuInfo(MenuInfo); - itemheight = Size.cy + 2; - - if( !(MenuInfo->dwStyle & MNS_NOCHECK)) - ItemInfo->Rect.right += 2 * CheckBitmapWidth; - ItemInfo->Rect.right += 4 + MenuCharSize.cx; - ItemInfo->XTab = ItemInfo->Rect.right; - ItemInfo->Rect.right += CheckBitmapWidth; - } - else /* hbmpItem & MenuBar */ - { - MenuGetBitmapItemSize(ItemInfo, &Size, WndOwner ); - ItemInfo->Rect.right += Size.cx; - if( ItemInfo->Text) ItemInfo->Rect.right += 2; - itemheight = Size.cy; - - /* Special case: Minimize button doesn't have a space behind it. */ - if (ItemInfo->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE || - ItemInfo->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE_D) - ItemInfo->Rect.right -= 1; - } - } - else if (!MenuBar) - { - if( !(MenuInfo->dwStyle & MNS_NOCHECK)) - ItemInfo->Rect.right += CheckBitmapWidth; - ItemInfo->Rect.right += 4 + MenuCharSize.cx; - ItemInfo->XTab = ItemInfo->Rect.right; - ItemInfo->Rect.right += CheckBitmapWidth; - } - - /* it must be a text item - unless it's the system menu */ - if (0 == (ItemInfo->fType & MF_SYSMENU) && ItemInfo->Text) - { - HFONT hfontOld = NULL; - RECT rc = ItemInfo->Rect; - LONG txtheight, txtwidth; - - if ( ItemInfo->fState & MFS_DEFAULT ) - { - hfontOld = SelectObject( Dc, hMenuFontBold ); - } - if (MenuBar) - { - txtheight = DrawTextW( Dc, ItemInfo->dwTypeData, -1, &rc, - DT_SINGLELINE|DT_CALCRECT); - ItemInfo->Rect.right += rc.right - rc.left; - itemheight = max( max( itemheight, txtheight), - GetSystemMetrics( SM_CYMENU) - 1); - ItemInfo->Rect.right += 2 * MenuCharSize.cx; - } - else - { - if ((p = strchrW( ItemInfo->dwTypeData, '\t' )) != NULL) - { - RECT tmprc = rc; - LONG tmpheight; - int n = (int)( p - ItemInfo->dwTypeData); - /* Item contains a tab (only meaningful in popup menus) */ - /* get text size before the tab */ - txtheight = DrawTextW( Dc, ItemInfo->dwTypeData, n, &rc, - DT_SINGLELINE|DT_CALCRECT); - txtwidth = rc.right - rc.left; - p += 1; /* advance past the Tab */ - /* get text size after the tab */ - tmpheight = DrawTextW( Dc, p, -1, &tmprc, DT_SINGLELINE|DT_CALCRECT); - ItemInfo->XTab += txtwidth; - txtheight = max( txtheight, tmpheight); - txtwidth += MenuCharSize.cx + /* space for the tab */ - tmprc.right - tmprc.left; /* space for the short cut */ - } - else - { - txtheight = DrawTextW( Dc, ItemInfo->dwTypeData, -1, &rc, - DT_SINGLELINE|DT_CALCRECT); - txtwidth = rc.right - rc.left; - ItemInfo->XTab += txtwidth; - } - ItemInfo->Rect.right += 2 + txtwidth; - itemheight = max( itemheight, max( txtheight + 2, MenuCharSize.cy + 4)); - } - if (hfontOld) SelectObject (Dc, hfontOld); - } - else if( MenuBar) - { - itemheight = max( itemheight, GetSystemMetrics(SM_CYMENU)-1); - } - ItemInfo->Rect.bottom += itemheight; - TRACE("(%ld,%ld)-(%ld,%ld)\n", ItemInfo->Rect.left, ItemInfo->Rect.top, ItemInfo->Rect.right, ItemInfo->Rect.bottom); -} - -/*********************************************************************** - * MenuPopupMenuCalcSize - * - * Calculate the size of a popup menu. - */ -static void FASTCALL -MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) -{ - ROSMENUITEMINFO ItemInfo; - HDC Dc; - int Start, i; - int OrgX, OrgY, MaxX, MaxTab, MaxTabWidth; - - MenuInfo->Width = MenuInfo->Height = 0; - if (0 == MenuInfo->MenuItemCount) - { - MenuSetRosMenuInfo(MenuInfo); - return; - } - - Dc = GetDC(NULL); - SelectObject(Dc, hMenuFont); - - Start = 0; - MaxX = 2 + 1; - - MenuInfo->maxBmpSize.cx = 0; - MenuInfo->maxBmpSize.cy = 0; - - MenuInitRosMenuItemInfo(&ItemInfo); - while (Start < MenuInfo->MenuItemCount) - { - OrgX = MaxX; - OrgY = 2; - - MaxTab = MaxTabWidth = 0; - - /* Parse items until column break or end of menu */ - for (i = Start; i < MenuInfo->MenuItemCount; i++) - { - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - MenuSetRosMenuInfo(MenuInfo); - return; - } - if (i != Start && - 0 != (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) - { - break; - } - MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, FALSE); - if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - MenuSetRosMenuInfo(MenuInfo); - return; - } -// Not sure here,, The patch from wine removes this. -// if (0 != (ItemInfo.fType & MF_MENUBARBREAK)) -// { -// OrgX++; -// } - MaxX = max(MaxX, ItemInfo.Rect.right); - OrgY = ItemInfo.Rect.bottom; - if ((ItemInfo.Text) && 0 != ItemInfo.XTab) - { - MaxTab = max(MaxTab, ItemInfo.XTab); - MaxTabWidth = max(MaxTabWidth, ItemInfo.Rect.right - ItemInfo.XTab); - } - } - - /* Finish the column (set all items to the largest width found) */ - MaxX = max(MaxX, MaxTab + MaxTabWidth); - while (Start < i) - { - if (MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo)) - { - ItemInfo.Rect.right = MaxX; - if ((ItemInfo.Text) && 0 != ItemInfo.XTab) - { - ItemInfo.XTab = MaxTab; - } - MenuSetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo); - } - Start++; - } - MenuInfo->Height = max(MenuInfo->Height, OrgY); - } - - MenuInfo->Width = MaxX; - - /* space for 3d border */ - MenuInfo->Height += 2; - MenuInfo->Width += 2; - - ReleaseDC(NULL, Dc); - MenuCleanupRosMenuItemInfo(&ItemInfo); - MenuSetRosMenuInfo(MenuInfo); -} - -/*********************************************************************** - * MenuMenuBarCalcSize - * - * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap - * height is off by 1 pixel which causes lengthy window relocations when - * active document window is maximized/restored. - * - * Calculate the size of the menu bar. - */ -static void FASTCALL -MenuMenuBarCalcSize(HDC Dc, LPRECT Rect, PROSMENUINFO MenuInfo, HWND WndOwner) -{ - ROSMENUITEMINFO ItemInfo; - int Start, i, OrgX, OrgY, MaxY, HelpPos; - - if (NULL == Rect || NULL == MenuInfo) - { - return; - } - if (0 == MenuInfo->MenuItemCount) - { - return; - } - - TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", - Rect->left, Rect->top, Rect->right, Rect->bottom); - MenuInfo->Width = Rect->right - Rect->left; - MenuInfo->Height = 0; - MaxY = Rect->top + 1; - Start = 0; - HelpPos = -1; - - MenuInfo->maxBmpSize.cx = 0; - MenuInfo->maxBmpSize.cy = 0; - - MenuInitRosMenuItemInfo(&ItemInfo); - while (Start < MenuInfo->MenuItemCount) - { - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - return; - } - OrgX = Rect->left; - OrgY = MaxY; - - /* Parse items until line break or end of menu */ - for (i = Start; i < MenuInfo->MenuItemCount; i++) - { - if (-1 == HelpPos && 0 != (ItemInfo.fType & MF_RIGHTJUSTIFY)) - { - HelpPos = i; - } - if (i != Start && - 0 != (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) - { - break; - } - - TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", OrgX, OrgY); - MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, TRUE); - if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - return; - } - - if (ItemInfo.Rect.right > Rect->right) - { - if (i != Start) - { - break; - } - else - { - ItemInfo.Rect.right = Rect->right; - } - } - MaxY = max(MaxY, ItemInfo.Rect.bottom ); - OrgX = ItemInfo.Rect.right; - if (i + 1 < MenuInfo->MenuItemCount) - { - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - return; - } - } - } - -/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the -HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */ -#if 0 - /* Finish the line (set all items to the largest height found) */ - while (Start < i) - { - if (MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo)) - { - ItemInfo.Rect.bottom = MaxY; - MenuSetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo); - } - Start++; - } -#else - Start = i; /* This works! */ -#endif +BOOL +MenuInit(VOID) +{ + NONCLIENTMETRICSW ncm; + + /* get the menu font */ + if(!hMenuFont || !hMenuFontBold) + { + ncm.cbSize = sizeof(ncm); + if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)) + { + DbgPrint("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n"); + return FALSE; } - Rect->bottom = MaxY; - MenuInfo->Height = Rect->bottom - Rect->top; - MenuSetRosMenuInfo(MenuInfo); + hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont); + if(hMenuFont == NULL) + { + DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n"); + return FALSE; + } - if (-1 != HelpPos) + ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000); + hMenuFontBold = CreateFontIndirectW(&ncm.lfMenuFont); + if(hMenuFontBold == NULL) { - /* Flush right all items between the MF_RIGHTJUSTIFY and */ - /* the last item (if several lines, only move the last line) */ - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - return; - } - OrgY = ItemInfo.Rect.top; - OrgX = Rect->right; - for (i = MenuInfo->MenuItemCount - 1; HelpPos <= i; i--) - { - if (i < HelpPos) - { - break; /* done */ - } - if (ItemInfo.Rect.top != OrgY) - { - break; /* Other line */ - } - if (OrgX <= ItemInfo.Rect.right) - { - break; /* Too far right already */ - } - ItemInfo.Rect.left += OrgX - ItemInfo.Rect.right; - ItemInfo.Rect.right = OrgX; - OrgX = ItemInfo.Rect.left; - MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo); - if (HelpPos + 1 <= i && - ! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo)) - { - MenuCleanupRosMenuItemInfo(&ItemInfo); - return; - } - } + DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n"); + DeleteObject(hMenuFont); + hMenuFont = NULL; + return FALSE; } + } - MenuCleanupRosMenuItemInfo(&ItemInfo); + return TRUE; +} + +VOID +MenuCleanup(VOID) +{ + if (hMenuFont) + { + DeleteObject(hMenuFont); + hMenuFont = NULL; + } + + if (hMenuFontBold) + { + DeleteObject(hMenuFontBold); + hMenuFontBold = NULL; + } } /*********************************************************************** @@ -1843,44 +1935,6 @@ DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font) return MenuInfo.Height; } - -/*********************************************************************** - * MenuDrawMenuBar - * - * Paint a menu bar. Returns the height of the menu bar. - * called from [windows/nonclient.c] - */ -UINT MenuDrawMenuBar(HDC DC, LPRECT Rect, HWND Wnd, BOOL SuppressDraw) -{ - ROSMENUINFO MenuInfo; - HFONT FontOld = NULL; - HMENU Menu = GetMenu(Wnd); - - if (NULL == Rect || ! MenuGetRosMenuInfo(&MenuInfo, Menu)) - { - return GetSystemMetrics(SM_CYMENU); - } - - if (SuppressDraw) - { - FontOld = SelectObject(DC, hMenuFont); - - MenuMenuBarCalcSize(DC, Rect, &MenuInfo, Wnd); - - Rect->bottom = Rect->top + MenuInfo.Height; - - if (NULL != FontOld) - { - SelectObject(DC, FontOld); - } - return MenuInfo.Height; - } - else - { - return DrawMenuBarTemp(Wnd, DC, Rect, Menu, NULL); - } -} - /*********************************************************************** * MenuInitTracking */ @@ -1929,112 +1983,6 @@ MenuInitTracking(HWND Wnd, HMENU Menu, BOOL Popup, UINT Flags) return TRUE; } - -/*********************************************************************** - * MenuShowPopup - * - * Display a popup menu. - */ -static BOOL FASTCALL -MenuShowPopup(HWND WndOwner, HMENU Menu, UINT Id, UINT flags, - INT X, INT Y, INT XAnchor, INT YAnchor ) -{ - ROSMENUINFO MenuInfo; - ROSMENUITEMINFO ItemInfo; - UINT Width, Height; - POINT pt; - HMONITOR monitor; - MONITORINFO info; - - TRACE("owner=%x hmenu=%x id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", - WndOwner, Menu, Id, X, Y, XAnchor, YAnchor); - - if (! MenuGetRosMenuInfo(&MenuInfo, Menu)) - { - return FALSE; - } - - if (NO_SELECTED_ITEM != MenuInfo.FocusedItem) - { - MenuInitRosMenuItemInfo(&ItemInfo); - if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo)) - { - ItemInfo.fMask |= MIIM_STATE; - ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT); - MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo); - } - MenuCleanupRosMenuItemInfo(&ItemInfo); - MenuInfo.FocusedItem = NO_SELECTED_ITEM; - } - - /* store the owner for DrawItem */ - MenuInfo.WndOwner = WndOwner; - MenuSetRosMenuInfo(&MenuInfo); - - MenuPopupMenuCalcSize(&MenuInfo, WndOwner); - - /* adjust popup menu pos so that it fits within the desktop */ - - Width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER); - Height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER); - - /* FIXME: should use item rect */ - pt.x = X; - pt.y = Y; - monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST ); - info.cbSize = sizeof(info); - GetMonitorInfoW( monitor, &info ); - - if( flags & TPM_RIGHTALIGN ) X -= Width; - if( flags & TPM_CENTERALIGN ) X -= Width / 2; - - if( flags & TPM_BOTTOMALIGN ) Y -= Height; - if( flags & TPM_VCENTERALIGN ) Y -= Height / 2; - - if (X + Width > info.rcWork.right) - { - if ( XAnchor && X >= Width - XAnchor) - X -= Width - XAnchor; - - if ( X + Width > info.rcWork.right) - X = info.rcWork.right - Width; - } - - if ( X < info.rcWork.left ) X = info.rcWork.left; - - if (Y + Height > info.rcWork.bottom) - { - if ( YAnchor && Y >= Height + YAnchor) - Y -= Height + YAnchor; - - if ( Y + Height > info.rcWork.bottom) - Y = info.rcWork.bottom - Height; - } - - if ( Y < info.rcWork.top ) Y = info.rcWork.top; - - /* NOTE: In Windows, top menu popup is not owned. */ - MenuInfo.Wnd = CreateWindowExW(0, POPUPMENU_CLASS_ATOMW, NULL, - WS_POPUP, X, Y, Width, Height, - WndOwner, 0, (HINSTANCE) GetWindowLongPtrW(WndOwner, GWLP_HINSTANCE), - (LPVOID) MenuInfo.Self); - if (NULL == MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) - { - return FALSE; - } - if (NULL == TopPopup) - { - TopPopup = MenuInfo.Wnd; - } - - /* Display the window */ - SetWindowPos(MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); - UpdateWindow(MenuInfo.Wnd); - - return TRUE; -} - /*********************************************************************** * MenuFindSubMenu * @@ -3280,78 +3228,6 @@ MenuKeyRight(MTRACKER *Mt, UINT Flags) } } -/*********************************************************************** - * MenuFindItemByKey - * - * Find the menu item selected by a key press. - * Return item id, -1 if none, -2 if we should close the menu. - */ -static UINT FASTCALL -MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo, - WCHAR Key, BOOL ForceMenuChar) -{ - ROSMENUINFO SysMenuInfo; - PROSMENUITEMINFO Items, ItemInfo; - LRESULT MenuChar; - UINT i; - - TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo); - - if (NULL == MenuInfo || ! IsMenu(MenuInfo->Self)) - { - if (MenuGetRosMenuInfo(&SysMenuInfo, GetSystemMenu(WndOwner, FALSE))) - { - MenuInfo = &SysMenuInfo; - } - else - { - MenuInfo = NULL; - } - } - - if (NULL != MenuInfo) - { - if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &Items) <= 0) - { - return -1; - } - if (! ForceMenuChar) - { - Key = toupperW(Key); - ItemInfo = Items; - for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++) - { - if ((ItemInfo->Text) && NULL != ItemInfo->dwTypeData) - { - WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2; - do - { - p = strchrW(p + 2, '&'); - } - while (NULL != p && L'&' == p[1]); - if (NULL != p && (toupperW(p[1]) == Key)) - { - return i; - } - } - } - } - - MenuChar = SendMessageW(WndOwner, WM_MENUCHAR, - MAKEWPARAM(Key, MenuInfo->Flags), (LPARAM) MenuInfo->Self); - if (2 == HIWORD(MenuChar)) - { - return LOWORD(MenuChar); - } - if (1 == HIWORD(MenuChar)) - { - return (UINT) (-2); - } - } - - return (UINT)(-1); -} - /*********************************************************************** * MenuTrackMenu * @@ -3437,7 +3313,7 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y, } /* check if EndMenu() tried to cancel us, by posting this message */ - if (WM_CANCELMODE == Msg.message) + if (Msg.message == WM_CANCELMODE) { /* we are now out of the loop */ fEndMenu = TRUE; @@ -3452,13 +3328,13 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y, TranslateMessage(&Msg); Mt.Pt = Msg.pt; - if (Msg.hwnd == MenuInfo.Wnd || WM_TIMER != Msg.message) + if (Msg.hwnd == MenuInfo.Wnd || Msg.message != WM_TIMER) { EnterIdleSent = FALSE; } fRemove = FALSE; - if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST) + if ((Msg.message >= WM_MOUSEFIRST) && (Msg.message <= WM_MOUSELAST)) { /* * Use the mouse coordinates in lParam instead of those in the MSG @@ -3477,10 +3353,7 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y, case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: - if (0 == (Flags & TPM_RIGHTBUTTON)) - { - break; - } + if (!(Flags & TPM_RIGHTBUTTON)) break; /* fall through */ case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: @@ -3491,14 +3364,11 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y, break; case WM_RBUTTONUP: - if (0 == (Flags & TPM_RIGHTBUTTON)) - { - break; - } + if (0 == (Flags & TPM_RIGHTBUTTON)) break; /* fall through */ case WM_LBUTTONUP: /* Check if a menu was selected by the mouse */ - if (NULL != Menu) + if (Menu) { ExecutedMenuId = MenuButtonUp(&Mt, Menu, Flags); @@ -3518,13 +3388,13 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y, case WM_MOUSEMOVE: if (Menu) { - fEndMenu |= ! MenuMouseMove(&Mt, Menu, Flags); + fEndMenu |= !MenuMouseMove(&Mt, Menu, Flags); } break; } /* switch(Msg.message) - mouse */ } - else if (WM_KEYFIRST <= Msg.message && Msg.message <= WM_KEYLAST) + else if ((Msg.message >= WM_KEYFIRST) && (Msg.message <= WM_KEYLAST)) { fRemove = TRUE; /* Keyboard messages are always removed */ switch(Msg.message) -- 2.17.1