Author: jimtabor Date: Mon Jul 31 09:18:08 2006 New Revision: 23386
URL: http://svn.reactos.org/svn/reactos?rev=23386&view=rev Log: Sync menu changes.
Modified: branches/ros-branch-0_3_0/reactos/dll/win32/user32/include/menu.h branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/defwnd.c branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/menu.c branches/ros-branch-0_3_0/reactos/include/reactos/win32k/ntusrtyp.h branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/menu.c
Modified: branches/ros-branch-0_3_0/reactos/dll/win32/user32/include/menu.h URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_0/reactos/dll/win... ============================================================================== --- branches/ros-branch-0_3_0/reactos/dll/win32/user32/include/menu.h (original) +++ branches/ros-branch-0_3_0/reactos/dll/win32/user32/include/menu.h Mon Jul 31 09:18:08 2006 @@ -17,6 +17,6 @@ VOID MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt); VOID -MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key); +MenuTrackKbdMenuBar(HWND hWnd, UINT wParam, WCHAR wChar);
#endif /* __LIB_USER32_INCLUDE_MENU_H */
Modified: branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/defwnd.c URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_0/reactos/dll/win... ============================================================================== --- branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/defwnd.c (original) +++ branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/defwnd.c Mon Jul 31 09:18:08 2006 @@ -766,9 +766,10 @@
LRESULT -DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt) +DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { WINDOWPLACEMENT wp; + POINT Pt;
switch (wParam & 0xfff0) { @@ -804,16 +805,24 @@ SendMessageA(hWnd, WM_CLOSE, 0, 0); break; case SC_MOUSEMENU: - MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt); + { + Pt.x = (short)LOWORD(lParam); + Pt.y = (short)HIWORD(lParam); + MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt); + } break; case SC_KEYMENU: - MenuTrackKbdMenuBar(hWnd, wParam, Pt.x); + MenuTrackKbdMenuBar(hWnd, wParam, (WCHAR)lParam); break; case SC_VSCROLL: case SC_HSCROLL: - DefWndTrackScrollBar(hWnd, wParam, Pt); + { + Pt.x = (short)LOWORD(lParam); + Pt.y = (short)HIWORD(lParam); + DefWndTrackScrollBar(hWnd, wParam, Pt); + } break; - + default: /* FIXME: Implement */ UNIMPLEMENTED; @@ -1305,13 +1314,7 @@ }
case WM_SYSCOMMAND: - { - POINT Pt; - Pt.x = GET_X_LPARAM(lParam); - Pt.y = GET_Y_LPARAM(lParam); - return (DefWndHandleSysCommand(hWnd, wParam, Pt)); - } - + return (DefWndHandleSysCommand(hWnd, wParam, lParam));
case WM_KEYDOWN: if(wParam == VK_F10) iF10Key = VK_F10; @@ -1539,7 +1542,23 @@ { case WM_NCCREATE: { - return TRUE; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam; + /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) + * may have child window IDs instead of window name */ + + if(cs->lpszName) + { + RtlInitAnsiString(&AnsiString, (LPSTR)cs->lpszName); + RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE); + NtUserDefSetText(hWnd, &UnicodeString); + RtlFreeUnicodeString(&UnicodeString); + } + else + NtUserDefSetText(hWnd, NULL); + + return (1); }
case WM_GETTEXTLENGTH: @@ -1618,7 +1637,16 @@ { case WM_NCCREATE: { - return TRUE; + UNICODE_STRING UnicodeString; + LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam; + /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) + * may have child window IDs instead of window name */ + + if(cs->lpszName) + RtlInitUnicodeString(&UnicodeString, (LPWSTR)cs->lpszName); + + NtUserDefSetText( hWnd, (cs->lpszName ? &UnicodeString : NULL)); + return (1); }
case WM_GETTEXTLENGTH:
Modified: branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/menu.c URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_0/reactos/dll/win... ============================================================================== --- branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/menu.c (original) +++ branches/ros-branch-0_3_0/reactos/dll/win32/user32/windows/menu.c Mon Jul 31 09:18:08 2006 @@ -1,34 +1,12 @@ -/* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * Partly based on Wine code - * Copyright 1993 Martin Ayotte - * Copyright 1994 Alexandre Julliard - * Copyright 1997 Morten Welinder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ /* $Id$ * + * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll - * FILE: lib/user32/windows/menu.c + * FILE: user32/windows/menu.c * PURPOSE: Menus - * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * UPDATE HISTORY: - * 09-05-2001 CSH Created + * + * PROGRAMMERS: Casper S. Hornstrup + * James Tabor */
/* INCLUDES ******************************************************************/ @@ -62,6 +40,7 @@ (0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
#define IS_MAGIC_ITEM(Bmp) ((int) Bmp <12) +#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
#define MENU_ITEM_HBMP_SPACE (5) #define MENU_BAR_ITEMS_SPACE (12) @@ -138,6 +117,8 @@ static HBITMAP StdMnArrow = NULL; static HBITMAP BmpSysMenu = NULL;
+static SIZE MenuCharSize; + /*********************************************************************** * MenuGetRosMenuInfo * @@ -155,7 +136,7 @@ /*********************************************************************** * MenuSetRosMenuInfo * - * Set full information about menu + * Set full information about menu */ static BOOL FASTCALL MenuSetRosMenuInfo(PROSMENUINFO MenuInfo) @@ -186,13 +167,16 @@ static BOOL FASTCALL MenuGetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo) { + UINT Save_Mask = ItemInfo->fMask; /* Save the org mask bits. */ + if (ItemInfo->dwTypeData != NULL) { HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData); } +
ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE - | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE; + | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE; ItemInfo->dwTypeData = NULL;
if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE)) @@ -217,14 +201,14 @@ return FALSE; } } - + ItemInfo->fMask = Save_Mask; return TRUE; }
/*********************************************************************** * MenuSetRosMenuItemInfo * - * Set full information about a menu item + * Set selected information about a menu item, need to set the mask bits. */ static BOOL FASTCALL MenuSetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo) @@ -234,12 +218,8 @@ if (MENU_ITEM_TYPE(ItemInfo->fType) == MF_STRING && ItemInfo->dwTypeData != NULL) { - ItemInfo->cch = wcslen(ItemInfo->dwTypeData); + ItemInfo->cch = strlenW(ItemInfo->dwTypeData); } - ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE - | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE; - - Ret = NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, TRUE);
return Ret; @@ -331,35 +311,51 @@ * Get the size of a bitmap item. */ static void FASTCALL -MenuGetBitmapItemSize(UINT Id, DWORD Data, SIZE *Size) +MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *Size, HWND WndOwner) { BITMAP Bm; - HBITMAP Bmp = (HBITMAP) Id; + HBITMAP Bmp = lpitem->hbmpItem;
Size->cx = Size->cy = 0;
/* check if there is a magic menu item associated with this item */ - if (0 != Id && IS_MAGIC_ITEM(Id)) - { - switch((INT_PTR) LOWORD(Id)) - { + if (0 != Bmp && IS_MAGIC_ITEM((INT)(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 != Data) + if (0 != lpitem->dwItemData) { - Bmp = (HBITMAP) Data; + 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: case (INT_PTR) HBMMENU_MBAR_CLOSE_D: /* 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; - case (INT_PTR) HBMMENU_CALLBACK: case (INT_PTR) HBMMENU_POPUP_CLOSE: case (INT_PTR) HBMMENU_POPUP_RESTORE: case (INT_PTR) HBMMENU_POPUP_MAXIMIZE: @@ -383,30 +379,33 @@ * Draw a bitmap item. */ static void FASTCALL -MenuDrawBitmapItem(HDC Dc, PROSMENUITEMINFO Item, const RECT *Rect, BOOL MenuBar) +MenuDrawBitmapItem(HDC Dc, PROSMENUITEMINFO Item, const RECT *Rect, + HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar) { BITMAP Bm; DWORD Rop; HDC DcMem; - HBITMAP Bmp = (HBITMAP) Item->hbmpItem; + 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_ITEM(Item->hbmpItem)) + if (IS_MAGIC_ITEM(hbmpToDraw)) { UINT Flags = 0; RECT r;
r = *Rect; - switch ((int) Item->hbmpItem) + switch ((INT_PTR)hbmpToDraw) { case (INT_PTR) HBMMENU_SYSTEM: - if (NULL != Item->hbmpItem) + if (NULL != Item->dwTypeData) { - Bmp = Item->hbmpItem; + Bmp = (HBITMAP)Item->dwTypeData; if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm)) { return; @@ -414,6 +413,7 @@ } else { + if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); Bmp = BmpSysMenu; if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm)) { @@ -442,6 +442,31 @@ Flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE; break; case (INT_PTR) HBMMENU_CALLBACK: + { + DRAWITEMSTRUCT drawItem; + POINT origorg; + drawItem.CtlType = ODT_MENU; + drawItem.CtlID = 0; + drawItem.itemID = Item->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.hwndItem = (HWND)hmenu; + drawItem.hDC = Dc; + drawItem.rcItem = *Rect; + drawItem.itemData = Item->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); + SendMessageW( WndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem); + SetViewportOrgEx( Dc, origorg.x, origorg.y, NULL); + return; + } + break; + case (INT_PTR) HBMMENU_POPUP_CLOSE: case (INT_PTR) HBMMENU_POPUP_RESTORE: case (INT_PTR) HBMMENU_POPUP_MAXIMIZE: @@ -471,8 +496,8 @@ /* handle fontsize > bitmap_height */ Top = (Bm.bmHeight < h) ? Rect->top + (h - Bm.bmHeight) / 2 : Rect->top; Left = Rect->left; - Rop = (0 != (Item->fState & MF_HILITE) && ! IS_MAGIC_ITEM(Item->hbmpItem)) ? NOTSRCCOPY : SRCCOPY; - if (0 != (Item->fState & MF_HILITE) && IS_BITMAP_ITEM(Item->fType)) + Rop= ((Item->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmpToDraw)) ? NOTSRCCOPY : SRCCOPY; + if ((Item->fState & MF_HILITE) && Item->hbmpItem) { SetBkColor(Dc, GetSysColor(COLOR_HIGHLIGHT)); } @@ -491,7 +516,9 @@ { RECT Rect; PWCHAR Text; - + BOOL flat_menu = FALSE; + int bkgnd; + if (0 != (Item->fType & MF_SYSMENU)) { if (! IsIconic(Wnd)) @@ -500,15 +527,17 @@ UserDrawSysMenuButton(Wnd, Dc, &Rect, Item->fState & (MF_HILITE | MF_MOUSESELECT)); } - return; }
+ SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); + bkgnd = (MenuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU; + /* Setup colors */
if (0 != (Item->fState & MF_HILITE)) { - if (MenuBar) + if (MenuBar && !flat_menu) { SetTextColor(Dc, GetSysColor(COLOR_MENUTEXT)); SetBkColor(Dc, GetSysColor(COLOR_MENU)); @@ -536,10 +565,12 @@ { SetTextColor(Dc, GetSysColor(COLOR_MENUTEXT)); } - SetBkColor(Dc, GetSysColor(COLOR_MENU)); - } - - if (0 != (Item->fType & MF_OWNERDRAW)) + SetBkColor(Dc, GetSysColor(bkgnd)); + } + + Rect = Item->Rect; + + if (Item->fType & MF_OWNERDRAW) { /* ** Experimentation under Windows reveals that an owner-drawn @@ -572,150 +603,13 @@ dis.itemAction = Action; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */ dis.hwndItem = (HWND) MenuInfo->Self; dis.hDC = Dc; - dis.rcItem = Item->Rect; + dis.rcItem = Rect; DPRINT("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, " "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", Wnd, 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); - /* Fall through to draw popup-menu arrow */ - } - - DPRINT("rect={%ld,%ld,%ld,%ld}\n", Item->Rect.left, Item->Rect.top, - Item->Rect.right, Item->Rect.bottom); - - if (MenuBar && 0 != (Item->fType & MF_SEPARATOR)) - { - return; - } - - Rect = Item->Rect; - - if (0 == (Item->fType & MF_OWNERDRAW)) - { - if (Item->fState & MF_HILITE) - { - if (MenuBar) - { - DrawEdge(Dc, &Rect, BDR_SUNKENOUTER, BF_RECT); - } - else - { - FillRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT)); - } - } - else - { - FillRect(Dc, &Rect, GetSysColorBrush(COLOR_MENU)); - } - } - - SetBkMode(Dc, TRANSPARENT); - - if (0 == (Item->fType & MF_OWNERDRAW)) - { - /* vertical separator */ - if (! MenuBar && 0 != (Item->fType & MF_MENUBARBREAK)) - { - RECT rc = Rect; - rc.top = 3; - rc.bottom = Height - 3; - DrawEdge(Dc, &rc, EDGE_ETCHED, BF_LEFT); - } - - /* horizontal separator */ - if (0 != (Item->fType & MF_SEPARATOR)) - { - RECT rc = Rect; - rc.left++; - rc.right--; - rc.top += SEPARATOR_HEIGHT / 2; - DrawEdge(Dc, &rc, EDGE_ETCHED, BF_TOP); - - return; - } - } - -#if 0 - /* helper lines for debugging */ - FrameRect(Dc, &Rect, GetStockObject(BLACK_BRUSH)); - SelectObject(Dc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME)); - MoveToEx(Dc, Rect.left, (Rect.top + Rect.bottom) / 2, NULL); - LineTo(Dc, Rect.right, (Rect.top + Rect.bottom) / 2); -#endif - - if (! MenuBar) - { - INT y = Rect.top + Rect.bottom; - UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK); - UINT CheckBitmapHeight = GetSystemMetrics(SM_CYMENUCHECK); - - if (0 == (Item->fType & MF_OWNERDRAW)) - { - /* Draw the check mark - * - * FIXME: - * Custom checkmark bitmaps are monochrome but not always 1bpp. - */ - HBITMAP bm = 0 != (Item->fState & MF_CHECKED) ? Item->hbmpChecked : Item->hbmpUnchecked; - if (NULL != bm) /* we have a custom bitmap */ - { - HDC DcMem = CreateCompatibleDC(Dc); - SelectObject(DcMem, bm); - BitBlt(Dc, Rect.left, (y - CheckBitmapHeight) / 2, - CheckBitmapWidth, CheckBitmapHeight, - DcMem, 0, 0, SRCCOPY); - DeleteDC(DcMem); - } - else if (0 != (Item->fState & MF_CHECKED)) /* standard bitmaps */ - { - RECT r; - HBITMAP bm = CreateBitmap(CheckBitmapWidth, CheckBitmapHeight, 1, 1, NULL); - HDC DcMem = CreateCompatibleDC(Dc); - SelectObject(DcMem, bm); - SetRect( &r, 0, 0, CheckBitmapWidth, CheckBitmapHeight); - DrawFrameControl(DcMem, &r, DFC_MENU, - 0 != (Item->fType & MFT_RADIOCHECK) ? - DFCS_MENUBULLET : DFCS_MENUCHECK); - BitBlt(Dc, Rect.left, (y - r.bottom) / 2, r.right, r.bottom, - DcMem, 0, 0, SRCCOPY ); - DeleteDC(DcMem); - DeleteObject(bm); - } - if (Item->hbmpItem) - { - if (Item->hbmpItem == HBMMENU_CALLBACK) - { - DRAWITEMSTRUCT drawItem; - POINT origorg; - drawItem.CtlType = ODT_MENU; - drawItem.CtlID = 0; - drawItem.itemID = Item->wID; - drawItem.itemAction = Action; - 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.hwndItem = (HWND) MenuInfo->Self; - drawItem.hDC = Dc; - drawItem.rcItem = Item->Rect; - drawItem.itemData = Item->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); - SendMessageW( WndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem); - SetViewportOrgEx( Dc, origorg.x, origorg.y, NULL); - } - else - { - MenuDrawBitmapItem(Dc, Item, &Rect, MenuBar); - return; - } - } - } - /* Draw the popup-menu arrow */ if (0 != (Item->fType & MF_POPUP)) { @@ -724,36 +618,180 @@
OrigBitmap = SelectObject(DcMem, StdMnArrow); BitBlt(Dc, Rect.right - ArrowBitmapWidth - 1, - (y - ArrowBitmapHeight) / 2, + ((Rect.top + Rect.bottom) - ArrowBitmapHeight) / 2, ArrowBitmapWidth, ArrowBitmapHeight, DcMem, 0, 0, SRCCOPY); SelectObject(DcMem, OrigBitmap); DeleteDC(DcMem); } - + return; + } + + DPRINT("rect={%ld,%ld,%ld,%ld}\n", Item->Rect.left, Item->Rect.top, + Item->Rect.right, Item->Rect.bottom); + + if (MenuBar && 0 != (Item->fType & MF_SEPARATOR)) + { + return; + } + + if (Item->fState & MF_HILITE) + { + if (flat_menu) + { + InflateRect (&Rect, -1, -1); + FillRect(Dc, &Rect, GetSysColorBrush(COLOR_MENUHILIGHT)); + InflateRect (&Rect, 1, 1); + FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT)); + } + else + { + if (MenuBar) + { + DrawEdge(Dc, &Rect, BDR_SUNKENOUTER, BF_RECT); + } + else + { + FillRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT)); + } + } + } + else + { + FillRect(Dc, &Rect, GetSysColorBrush(bkgnd)); + } + + SetBkMode(Dc, TRANSPARENT); + + /* vertical separator */ + if (! MenuBar && 0 != (Item->fType & MF_MENUBARBREAK)) + { + HPEN oldPen; + RECT rc = Rect; + rc.top = 3; + rc.bottom = Height - 3; + if (flat_menu) + { + oldPen = SelectObject( Dc, GetSysColorPen(COLOR_BTNSHADOW) ); + MoveToEx( Dc, rc.left, rc.top, NULL ); + LineTo( Dc, rc.left, rc.bottom ); + SelectObject( Dc, oldPen ); + } + else + DrawEdge(Dc, &rc, EDGE_ETCHED, BF_LEFT); + } + + /* 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, GetSysColorPen(COLOR_BTNSHADOW) ); + MoveToEx( Dc, rc.left, rc.top, NULL ); + LineTo( Dc, rc.right, rc.top ); + SelectObject( Dc, oldPen ); + } + 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, GetSysColorPen(COLOR_WINDOWFRAME)); + MoveToEx(Dc, Rect.left, (Rect.top + Rect.bottom) / 2, NULL); + LineTo(Dc, 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 */ + { + HDC DcMem = CreateCompatibleDC(Dc); + SelectObject(DcMem, bm); + BitBlt(Dc, Rc.left, (y - CheckBitmapHeight) / 2, + CheckBitmapWidth, CheckBitmapHeight, + DcMem, 0, 0, SRCCOPY); + DeleteDC(DcMem); + checked = TRUE; + } + else if (0 != (Item->fState & MF_CHECKED)) /* standard bitmaps */ + { + RECT r; + HBITMAP bm = CreateBitmap(CheckBitmapWidth, CheckBitmapHeight, 1, 1, NULL); + HDC DcMem = CreateCompatibleDC(Dc); + SelectObject(DcMem, bm); + SetRect( &r, 0, 0, CheckBitmapWidth, CheckBitmapHeight); + DrawFrameControl(DcMem, &r, DFC_MENU, + 0 != (Item->fType & MFT_RADIOCHECK) ? + DFCS_MENUBULLET : DFCS_MENUCHECK); + BitBlt(Dc, Rc.left, (y - r.bottom) / 2, r.right, r.bottom, + DcMem, 0, 0, SRCCOPY ); + DeleteDC(DcMem); + DeleteObject(bm); + checked = TRUE; + } + } + if ((Item->hbmpItem)&& !( checked && (MenuInfo->dwStyle & MNS_CHECKORBMP))) + { + MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar); + } + /* Draw the popup-menu arrow */ + if (0 != (Item->fType & MF_POPUP)) + { + HDC DcMem = CreateCompatibleDC(Dc); + HBITMAP OrigBitmap; + + OrigBitmap = SelectObject(DcMem, StdMnArrow); + BitBlt(Dc, Rect.right - ArrowBitmapWidth - 1, + (y - ArrowBitmapHeight) / 2, + ArrowBitmapWidth, ArrowBitmapHeight, + DcMem, 0, 0, SRCCOPY); + SelectObject(DcMem, OrigBitmap); + DeleteDC(DcMem); + } + Rect.left += 4; + if( !(MenuInfo->dwStyle & MNS_NOCHECK)) Rect.left += CheckBitmapWidth; - Rect.right -= ArrowBitmapWidth; + Rect.right -= ArrowBitmapWidth; } - else if( Item->hbmpItem && !(Item->fType & MF_OWNERDRAW)) - { /* Draw the bitmap */ - MenuDrawBitmapItem(Dc, Item, &Rect, MenuBar); + else if (Item->hbmpItem) /* Draw the bitmap */ + { + MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar); } - - /* Done for owner-drawn */ - if (0 != (Item->fType & MF_OWNERDRAW)) - { - return; - } - - /* process text if present */ - if (!(Item->fType & MF_SYSMENU) && Item->dwTypeData) - { - register int i; + + /* No bitmap - process text if present */ + if (Item->Text) + { + register int i = 0; HFONT FontOld = NULL;
UINT uFormat = MenuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE : DT_LEFT | DT_VCENTER | DT_SINGLELINE;
+ if( !(MenuInfo->dwStyle & MNS_CHECKORBMP)) + Rect.left += MenuInfo->maxBmpSize.cx; + if (0 != (Item->fState & MFS_DEFAULT)) { FontOld = SelectObject(Dc, hMenuFontBold); @@ -771,13 +809,16 @@ }
Text = (PWCHAR) Item->dwTypeData; - for (i = 0; L'\0' != Text[i]; i++) + if(Text) + { + for (i = 0; L'\0' != Text[i]; i++) { if (L'\t' == Text[i] || L'\b' == Text[i]) { break; } } + }
if (0 != (Item->fState & MF_GRAYED)) { @@ -790,6 +831,7 @@ } SetTextColor(Dc, RGB(0x80, 0x80, 0x80)); } + DrawTextW(Dc, Text, i, &Rect, uFormat);
/* paint the shortcut text */ @@ -802,6 +844,7 @@ } else { + Rect.right = Item->XTab; uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE; }
@@ -823,7 +866,7 @@ { SelectObject(Dc, FontOld); } - } + } }
/*********************************************************************** @@ -853,7 +896,13 @@ PrevPen = SelectObject(Dc, GetStockObject(NULL_PEN)); if (NULL != PrevPen) { - DrawEdge(Dc, &Rect, EDGE_RAISED, BF_RECT); + BOOL flat_menu = FALSE; + + SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); + if (flat_menu) + FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_BTNSHADOW)); + else + DrawEdge(Dc, &Rect, EDGE_RAISED, BF_RECT);
/* draw menu items */
@@ -890,7 +939,7 @@ case WM_CREATE: { CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; - SetWindowLongW(Wnd, 0, (LONG) cs->lpCreateParams); + SetWindowLongPtrW(Wnd, 0, (LONG) cs->lpCreateParams); return 0; }
@@ -901,7 +950,7 @@ { PAINTSTRUCT ps; BeginPaint(Wnd, &ps); - MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongW(Wnd, 0)); + MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrW(Wnd, 0)); EndPaint(Wnd, &ps); return 0; } @@ -920,23 +969,23 @@ case WM_SHOWWINDOW: if (0 != wParam) { - if (0 == GetWindowLongW(Wnd, 0)) + if (0 == GetWindowLongPtrW(Wnd, 0)) { OutputDebugStringA("no menu to display\n"); } } else { - SetWindowLongW(Wnd, 0, 0); + SetWindowLongPtrW(Wnd, 0, 0); } break;
case MM_SETMENUHANDLE: - SetWindowLongW(Wnd, 0, wParam); + SetWindowLongPtrW(Wnd, 0, wParam); break;
case MM_GETMENUHANDLE: - return GetWindowLongW(Wnd, 0); + return GetWindowLongPtrW(Wnd, 0);
default: return DefWindowProcW(Wnd, Message, wParam, lParam); @@ -962,7 +1011,7 @@ MENUITEMINFOW mii;
mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE; + mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE; mii.fType = GET_DWORD(res); res += sizeof(DWORD); mii.fState = GET_DWORD(res); @@ -974,7 +1023,7 @@ /* Align the text on a word boundary. */ res += (~((int)res - 1)) & 1; mii.dwTypeData = (LPWSTR) res; - res += (1 + wcslen(mii.dwTypeData)) * sizeof(WCHAR); + res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR); /* Align the following fields on a dword boundary. */ res += (~((int)res - 1)) & 3;
@@ -995,8 +1044,6 @@ } else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR)) { - DbgPrint("WARN: Converting NULL menu item %04x, type %04x to SEPARATOR\n", - mii.wID, mii.fType); mii.fType |= MF_SEPARATOR; } InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii); @@ -1039,7 +1086,7 @@ if(!unicode) res += strlen(str) + 1; else - res += (wcslen((LPCWSTR)str) + 1) * sizeof(WCHAR); + res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR); if (flags & MF_POPUP) { hSubMenu = CreatePopupMenu(); @@ -1139,9 +1186,12 @@ INT OrgX, INT OrgY, BOOL MenuBar) { PWCHAR p; + INT itemheight = 0; UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK);
DPRINT("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);
@@ -1159,19 +1209,19 @@ mis.CtlID = 0; mis.itemID = ItemInfo->wID; mis.itemData = (DWORD)ItemInfo->dwItemData; - mis.itemHeight = 0; + mis.itemHeight = HIWORD( GetDialogBaseUnits()); mis.itemWidth = 0; SendMessageW(WndOwner, WM_MEASUREITEM, 0, (LPARAM) &mis); - ItemInfo->Rect.right += mis.itemWidth; + /* 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) { - ItemInfo->Rect.right += MENU_BAR_ITEMS_SPACE; - /* 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_CYMENU) - 1; + ItemInfo->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE); } else { @@ -1179,107 +1229,124 @@ }
DPRINT("id=%04x size=%dx%d\n", ItemInfo->wID, mis.itemWidth, mis.itemHeight); - /* Fall through to get check/arrow width calculation. */ + return; }
if (0 != (ItemInfo->fType & MF_SEPARATOR)) { ItemInfo->Rect.bottom += SEPARATOR_HEIGHT; + if( !MenuBar) + ItemInfo->Rect.right += ArrowBitmapWidth + MenuCharSize.cx; return; } - - if (0 != (ItemInfo->fType & MF_OWNERDRAW)) - { - return; - } - - if (! MenuBar) + + ItemInfo->XTab = 0; + + if (ItemInfo->hbmpItem) { - if (ItemInfo->hbmpItem) + SIZE Size; + + if (!MenuBar) /* hbmpItem */ { - if (ItemInfo->hbmpItem == HBMMENU_CALLBACK) - { - MEASUREITEMSTRUCT measItem; - measItem.CtlType = ODT_MENU; - measItem.CtlID = 0; - measItem.itemID = ItemInfo->wID; - measItem.itemWidth = ItemInfo->Rect.right - ItemInfo->Rect.left; - measItem.itemHeight = ItemInfo->Rect.bottom - ItemInfo->Rect.top; - measItem.itemData = ItemInfo->dwItemData; - SendMessageW( WndOwner, WM_MEASUREITEM, ItemInfo->wID, (LPARAM)&measItem); - ItemInfo->Rect.right = ItemInfo->Rect.left + measItem.itemWidth; - if (MenuInfo->maxBmpSize.cx < abs(measItem.itemWidth) + MENU_ITEM_HBMP_SPACE || - MenuInfo->maxBmpSize.cy < abs(measItem.itemHeight)) - { - MenuInfo->maxBmpSize.cx = abs(measItem.itemWidth) + MENU_ITEM_HBMP_SPACE; - MenuInfo->maxBmpSize.cy = abs(measItem.itemHeight); - MenuSetRosMenuInfo(MenuInfo); - } - } - else - { - SIZE Size; - - MenuGetBitmapItemSize((int) ItemInfo->hbmpItem, (DWORD) ItemInfo->hbmpItem, &Size); - ItemInfo->Rect.right += Size.cx; - ItemInfo->Rect.bottom += Size.cy; - - /* Leave space for the sunken border */ - ItemInfo->Rect.right += 2; - ItemInfo->Rect.bottom += 2; - - /* 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; - } - ItemInfo->Rect.right += 2 * CheckBitmapWidth; + 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); + ItemInfo->Rect.right += Size.cx + 2; + 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 += ArrowBitmapWidth; } - else + else /* hbmpItem & MenuBar */ { - ItemInfo->Rect.right += 2 * CheckBitmapWidth; - if (0 != (ItemInfo->fType & MF_POPUP)) - { - ItemInfo->Rect.right += ArrowBitmapWidth; - } + 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 += ArrowBitmapWidth; + }
/* it must be a text item - unless it's the system menu */ - if (0 == (ItemInfo->fType & MF_SYSMENU) && IS_STRING_ITEM(ItemInfo->fType)) - { - SIZE Size; - - GetTextExtentPoint32W(Dc, (LPWSTR) ItemInfo->dwTypeData, - wcslen((LPWSTR) ItemInfo->dwTypeData), &Size); - - ItemInfo->Rect.right += Size.cx; - ItemInfo->Rect.bottom += max(Size.cy, GetSystemMetrics(SM_CYMENU) - 1); - ItemInfo->XTab = 0; - - if (MenuBar) - { - ItemInfo->Rect.right += MENU_BAR_ITEMS_SPACE; - } - else if ((p = wcschr((LPWSTR) ItemInfo->dwTypeData, L'\t' )) != NULL) - { - /* Item contains a tab (only meaningful in popup menus) */ - GetTextExtentPoint32W(Dc, (LPWSTR) ItemInfo->dwTypeData, - (int)(p - (LPWSTR) ItemInfo->dwTypeData), &Size); - ItemInfo->XTab = CheckBitmapWidth + MENU_TAB_SPACE + Size.cx; - ItemInfo->Rect.right += MENU_TAB_SPACE; - } - else - { - if (NULL != wcschr((LPWSTR) ItemInfo->dwTypeData, L'\b')) - { - ItemInfo->Rect.right += MENU_TAB_SPACE; - } - ItemInfo->XTab = ItemInfo->Rect.right - CheckBitmapWidth - - ArrowBitmapWidth; - } - } - + 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; DPRINT("(%ld,%ld)-(%ld,%ld)\n", ItemInfo->Rect.left, ItemInfo->Rect.top, ItemInfo->Rect.right, ItemInfo->Rect.bottom); }
@@ -1309,7 +1376,10 @@ Start = 0; MaxX = 2 + 1;
- MenuInitRosMenuItemInfo(&ItemInfo); + MenuInfo->maxBmpSize.cx = 0; + MenuInfo->maxBmpSize.cy = 0; + + MenuInitRosMenuItemInfo(&ItemInfo); while (Start < MenuInfo->MenuItemCount) { OrgX = MaxX; @@ -1331,7 +1401,6 @@ { break; } - MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, FALSE); if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo)) { @@ -1346,7 +1415,7 @@ } MaxX = max(MaxX, ItemInfo.Rect.right); OrgY = ItemInfo.Rect.bottom; - if (IS_STRING_ITEM(ItemInfo.fType) && 0 != ItemInfo.XTab) + if ((ItemInfo.Text) && 0 != ItemInfo.XTab) { MaxTab = max(MaxTab, ItemInfo.XTab); MaxTabWidth = max(MaxTabWidth, ItemInfo.Rect.right - ItemInfo.XTab); @@ -1360,7 +1429,7 @@ if (MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo)) { ItemInfo.Rect.right = MaxX; - if (IS_STRING_ITEM(ItemInfo.fType) && 0 != ItemInfo.XTab) + if ((ItemInfo.Text) && 0 != ItemInfo.XTab) { ItemInfo.XTab = MaxTab; } @@ -1413,6 +1482,10 @@ MaxY = Rect->top + 1; Start = 0; HelpPos = -1; + + MenuInfo->maxBmpSize.cx = 0; + MenuInfo->maxBmpSize.cy = 0; + MenuInitRosMenuItemInfo(&ItemInfo); while (Start < MenuInfo->MenuItemCount) { @@ -1468,7 +1541,8 @@ } }
-/* FIXME: Is this really needed? */ +/* 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) @@ -1481,7 +1555,7 @@ Start++; } #else - Start = i; + Start = i; /* This works! */ #endif }
@@ -1548,7 +1622,10 @@ ROSMENUITEMINFO ItemInfo; UINT i; HFONT FontOld = NULL; - + BOOL flat_menu = FALSE; + + SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); + if (NULL == Menu) { Menu = GetMenu(Wnd); @@ -1575,7 +1652,7 @@
Rect->bottom = Rect->top + MenuInfo.Height;
- FillRect(DC, Rect, GetSysColorBrush(COLOR_MENU)); + FillRect(DC, Rect, GetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU));
SelectObject(DC, GetSysColorPen(COLOR_3DFACE)); MoveToEx(DC, Rect->left, Rect->bottom, NULL); @@ -1665,7 +1742,9 @@
SendMessageW(Wnd, WM_INITMENU, (WPARAM)Menu, 0);
- if (MenuGetRosMenuInfo(&MenuInfo, Menu) && 0 == MenuInfo.Height) + MenuGetRosMenuInfo(&MenuInfo, Menu); + + if (0 == MenuInfo.Height) { /* app changed/recreated menu bar entries in WM_INITMENU Recalculate menu sizes else clicks will not work */ @@ -1673,6 +1752,15 @@ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
} + /* This makes the menus of applications built with Delphi work. + * It also enables menus to be displayed in more than one window, + * but there are some bugs left that need to be fixed in this case. + */ + if(MenuInfo.Self == Menu) + { + MenuInfo.Wnd = Wnd; + MenuSetRosMenuInfo(&MenuInfo); + } }
return TRUE; @@ -1705,6 +1793,7 @@ 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); } @@ -1725,7 +1814,7 @@
if (GetSystemMetrics(SM_CXSCREEN ) < X + Width) { - if (0 != XAnchor) + if (0 != XAnchor && X >= Width - XAnchor) { X -= Width - XAnchor; } @@ -1741,7 +1830,7 @@
if (GetSystemMetrics(SM_CYSCREEN) < Y + Height) { - if (0 != YAnchor) + if (0 != YAnchor && Y >= Height + YAnchor) { Y -= Height + YAnchor; } @@ -1759,7 +1848,7 @@ /* 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) GetWindowLongW(WndOwner, GWL_HINSTANCE), + WndOwner, 0, (HINSTANCE) GetWindowLongPtrW(WndOwner, GWLP_HINSTANCE), (LPVOID) MenuInfo.Self); if (NULL == MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) { @@ -1870,12 +1959,12 @@
SelectObject(Dc, hMenuFont); MenuInitRosMenuItemInfo(&ItemInfo); - /* Clear previous highlighted item */ if (NO_SELECTED_ITEM != MenuInfo->FocusedItem) { if (MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)) { + ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT); MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); } @@ -1893,6 +1982,7 @@ { if (0 == (ItemInfo.fType & MF_SEPARATOR)) { + ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState |= MF_HILITE; MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, @@ -1927,7 +2017,6 @@ } } } - MenuCleanupRosMenuItemInfo(&ItemInfo); ReleaseDC(MenuInfo->Wnd, Dc); } @@ -2047,7 +2136,7 @@ } #if 0 mii.cbSize = sizeof(MENUITEMINFOW); - mii.fMask = MIIM_STATE; + mii.fMask |= MIIM_STATE; if((DefItem != SC_CLOSE) && GetMenuItemInfoW(Menu, DefItem, FALSE, &mii) && (mii.fState & (MFS_GRAYED | MFS_DISABLED))) { @@ -2122,7 +2211,7 @@ }
SelectObject(Dc, hMenuFont); - + ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState |= MF_HILITE; MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height, @@ -2136,8 +2225,8 @@ ItemInfo.Rect = Rect; }
+ ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState |= MF_MOUSESELECT; - MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
if (IS_SYSTEM_MENU(MenuInfo)) @@ -2156,9 +2245,10 @@ if (0 != (MenuInfo->Flags & MF_POPUP)) { Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER); - Rect.top += ItemInfo.Rect.top; + Rect.top += ItemInfo.Rect.top - 3; Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER); - Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom; + Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - 3 - 2 + - GetSystemMetrics(SM_CYBORDER); } else { @@ -2198,6 +2288,7 @@ if (NULL != MenuInfo && NULL != TopPopup && NO_SELECTED_ITEM != MenuInfo->FocusedItem) { MenuInitRosMenuItemInfo(&ItemInfo); + ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE; if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo) || 0 == (ItemInfo.fType & MF_POPUP) || 0 == (ItemInfo.fState & MF_MOUSESELECT)) @@ -2206,6 +2297,7 @@ return; } ItemInfo.fState &= ~MF_MOUSESELECT; + ItemInfo.fMask |= MIIM_STATE; MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); if (MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu)) { @@ -3053,19 +3145,19 @@ } if (! ForceMenuChar) { - Key = towupper(Key); + Key = toupperW(Key); ItemInfo = Items; for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++) { - if (IS_STRING_ITEM(ItemInfo->fType) && NULL != ItemInfo->dwTypeData) + if ((ItemInfo->Text) && NULL != ItemInfo->dwTypeData) { WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2; do { - p = wcschr(p + 2, '&'); + p = strchrW(p + 2, '&'); } while (NULL != p && L'&' == p[1]); - if (NULL != p && (towupper(p[1]) == Key)) + if (NULL != p && (toupperW(p[1]) == Key)) { return i; } @@ -3254,9 +3346,13 @@ fRemove = TRUE; /* Keyboard messages are always removed */ switch(Msg.message) { + case WM_SYSKEYDOWN: case WM_KEYDOWN: switch(Msg.wParam) { + case VK_MENU: + fEndMenu = TRUE; + break; case VK_HOME: case VK_END: if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu)) @@ -3343,19 +3439,6 @@ } break; /* WM_KEYDOWN */
- case WM_SYSKEYDOWN: - switch (Msg.wParam) - { - DbgPrint("Menu.c WM_SYSKEYDOWN wPram %d\n",Msg.wParam); - case VK_MENU: - fEndMenu = TRUE; - break; - case VK_LMENU: - fEndMenu = TRUE; - break; - } - break; /* WM_SYSKEYDOWN */ - case WM_CHAR: case WM_SYSCHAR: { @@ -3401,7 +3484,9 @@ } else { + PeekMessageW( &Msg, 0, Msg.message, Msg.message, PM_REMOVE ); DispatchMessageW(&Msg); + continue; }
if (! fEndMenu) @@ -3458,7 +3543,7 @@ /* The return value is only used by TrackPopupMenu */ if (!(Flags & TPM_RETURNCMD)) return TRUE; if (ExecutedMenuId < 0) ExecutedMenuId = 0; - return ExecutedMenuId; + return ExecutedMenuId; }
/*********************************************************************** @@ -3500,9 +3585,203 @@
VOID -MenuTrackKbdMenuBar(HWND hWnd, ULONG wParam, ULONG Key) -{ -} +MenuTrackKbdMenuBar(HWND hWnd, UINT wParam, WCHAR wChar) +{ + UINT uItem = NO_SELECTED_ITEM; + HMENU hTrackMenu; + ROSMENUINFO MenuInfo; + UINT wFlags = TPM_ENTERIDLEEX | TPM_LEFTALIGN | TPM_LEFTBUTTON; + + DPRINT("hwnd %p wParam 0x%04x wChar 0x%04x\n", hWnd, wParam, wChar); + + /* find window that has a menu */ + + while (!((GetWindowLongW( hWnd, GWL_STYLE ) & + (WS_CHILD | WS_POPUP)) != WS_CHILD)) + if (!(hWnd = GetAncestor( hWnd, GA_PARENT ))) return; + + /* check if we have to track a system menu */ + + hTrackMenu = GetMenu( hWnd ); + if (!hTrackMenu || IsIconic(hWnd) || wChar == ' ' ) + { + if (!(GetWindowLongW( hWnd, GWL_STYLE ) & WS_SYSMENU)) return; + hTrackMenu = NtUserGetSystemMenu(hWnd, FALSE); + uItem = 0; + wParam |= HTSYSMENU; /* prevent item lookup */ + } + + if (!IsMenu( hTrackMenu )) return; + + MenuInitTracking( hWnd, hTrackMenu, FALSE, wFlags ); + + if (! MenuGetRosMenuInfo(&MenuInfo, hTrackMenu)) + { + goto track_menu; + } + + if( wChar && wChar != ' ' ) + { + uItem = MenuFindItemByKey( hWnd, &MenuInfo, wChar, (wParam & HTSYSMENU) ); + if ( uItem >= (UINT)(-2) ) + { + if( uItem == (UINT)(-1) ) MessageBeep(0); + /* schedule end of menu tracking */ + wFlags |= TF_ENDMENU; + goto track_menu; + } + } + + MenuSelectItem( hWnd, &MenuInfo, uItem, TRUE, 0 ); + + if (wParam & HTSYSMENU) + { + /* prevent sysmenu activation for managed windows on Alt down/up */ +// if (GetPropA( hwnd, "__wine_x11_managed" )) + wFlags |= TF_ENDMENU; /* schedule end of menu tracking */ + } + else + { + if( uItem == NO_SELECTED_ITEM ) + MenuMoveSelection( hWnd, &MenuInfo, ITEM_NEXT ); + else + PostMessageW( hWnd, WM_KEYDOWN, VK_DOWN, 0L ); + } + +track_menu: + MenuTrackMenu( hTrackMenu, wFlags, 0, 0, hWnd, NULL ); + MenuExitTracking( hWnd ); + +} + +/* + * From MSDN: + * The MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING values cannot be combined + * with one another. Also MFT_OWNERDRAW. Set fMask to MIIM_TYPE to use fType. + * + * Windows 2K/XP: fType is used only if fMask has a value of MIIM_FTYPE. + * + * MIIM_TYPE: Retrieves or sets the fType and dwTypeData members. Windows + * 2K/XP: MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING. + * MFT_STRING is replaced by MIIM_STRING. + * (So, I guess we should use MIIM_STRING only for strings?) + * + * MIIM_FTYPE: Windows 2K/Windows XP: Retrieves or sets the fType member. + * + * Based on wine, SetMenuItemInfo_common: + * 1) set MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP any one with MIIM_TYPE, + * it will result in a error. + * 2) set menu mask to MIIM_FTYPE and MFT_BITMAP ftype it will result in a error. + * These conditions are addressed in Win32k IntSetMenuItemInfo. + * + */ +static +BOOL +FASTCALL +MenuSetItemData( + LPMENUITEMINFOW mii, + UINT Flags, + UINT_PTR IDNewItem, + LPCWSTR NewItem, + BOOL Unicode) +{ +/* + * Let us assume MIIM_FTYPE is set and building a new menu item structure. + */ + if(Flags & MF_BITMAP) + { + mii->fMask |= MIIM_BITMAP; /* Use the new way of seting hbmpItem.*/ + mii->hbmpItem = (HBITMAP) NewItem; + mii->fType &= ~MFT_BITMAP; /* just incase, Kill the old way */ + } + else if(Flags & MF_OWNERDRAW) + { + mii->fType |= MFT_OWNERDRAW; + mii->fMask |= MIIM_DATA; + mii->dwItemData = (DWORD) NewItem; + } + else if (Flags & MF_SEPARATOR) + { + mii->fType |= MFT_SEPARATOR; + } + else /* Default action MF_STRING. */ + { + /* Item beginning with a backspace is a help item */ + if (NewItem != NULL) + { + if (Unicode) + { + if (*NewItem == '\b') + { + mii->fType |= MF_HELP; + NewItem++; + } + } + else + { + LPCSTR NewItemA = (LPCSTR) NewItem; + if (*NewItemA == '\b') + { + mii->fType |= MF_HELP; + NewItemA++; + NewItem = (LPCWSTR) NewItemA; + } + } + } + mii->fMask |= MIIM_STRING; + mii->fType |= MFT_STRING; /* Zero */ + mii->dwTypeData = (LPWSTR)NewItem; + if (Unicode) + mii->cch = (NULL == NewItem ? 0 : strlenW(NewItem)); + else + mii->cch = (NULL == NewItem ? 0 : strlen((LPCSTR)NewItem)); + mii->hbmpItem = NULL; + } + + if(Flags & MF_RIGHTJUSTIFY) /* Same as MF_HELP */ + { + mii->fType |= MFT_RIGHTJUSTIFY; + } + + if(Flags & MF_MENUBREAK) + { + mii->fType |= MFT_MENUBREAK; + } + else if(Flags & MF_MENUBARBREAK) + { + mii->fType |= MFT_MENUBARBREAK; + } + + if(Flags & MF_GRAYED) + { + mii->fState |= MFS_GRAYED; + mii->fMask |= MIIM_STATE; + } + else if(Flags & MF_DISABLED) + { + mii->fState |= MFS_DISABLED; + mii->fMask |= MIIM_STATE; + } + else /* default state */ + { + mii->fState |= MFS_ENABLED; + mii->fMask |= MIIM_STATE; + } + + if(Flags & MF_POPUP) + { + mii->fType |= MF_POPUP; + mii->fMask |= MIIM_SUBMENU; + mii->hSubMenu = (HMENU)IDNewItem; + } + else + { + mii->fMask |= MIIM_ID; + mii->wID = (UINT)IDNewItem; + } + return TRUE; +} +
/* FUNCTIONS *****************************************************************/
@@ -3583,6 +3862,7 @@ if (0 != (Items[i].fType & MF_MENUBARBREAK)) break; if ( i >= idFirst && i <= idLast ) { + Items[i].fMask = MIIM_STATE | MIIM_FTYPE; if ( i == idCheck) { Items[i].fType |= MFT_RADIOCHECK; @@ -3806,8 +4086,9 @@ BOOL ByPosition, LPMENUITEMINFOA mii) { + MENUITEMINFOW miiW; LPSTR AnsiBuffer; - MENUITEMINFOW miiW; + INT Count;
if (mii->cbSize != sizeof(MENUITEMINFOA) && mii->cbSize != sizeof(MENUITEMINFOA) - sizeof(HBITMAP)) @@ -3816,45 +4097,49 @@ return FALSE; }
- if ((mii->fMask & (MIIM_STRING | MIIM_TYPE)) == 0) + if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING))) { /* No text requested, just pass on */ return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE); }
+ AnsiBuffer = mii->dwTypeData; + Count = miiW.cch = mii->cch; RtlCopyMemory(&miiW, mii, mii->cbSize); - AnsiBuffer = mii->dwTypeData; - - if (AnsiBuffer != NULL) + miiW.dwTypeData = 0; + + if (AnsiBuffer) { miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0, miiW.cch * sizeof(WCHAR)); - if (miiW.dwTypeData == NULL) - return FALSE; + if (miiW.dwTypeData == NULL) return FALSE; }
if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO)&miiW, FALSE)) { - HeapFree(GetProcessHeap(), 0, miiW.dwTypeData); + if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); return FALSE; }
- if (AnsiBuffer != NULL) + RtlCopyMemory(mii, &miiW, miiW.cbSize); + + if (!AnsiBuffer || !Count) { - if (IS_STRING_ITEM(miiW.fType)) - { - WideCharToMultiByte(CP_ACP, 0, miiW.dwTypeData, miiW.cch, AnsiBuffer, + if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); + mii->dwTypeData = AnsiBuffer; + mii->cch = miiW.cch; + return TRUE; + } + + if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType))) + { + WideCharToMultiByte(CP_ACP, 0, miiW.dwTypeData, miiW.cch, AnsiBuffer, mii->cch, NULL, NULL); - } - RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); }
- RtlCopyMemory(mii, &miiW, miiW.cbSize); - if (AnsiBuffer) - { - mii->dwTypeData = AnsiBuffer; - mii->cch = strlen(AnsiBuffer); - } + RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); + mii->dwTypeData = AnsiBuffer; + mii->cch = strlen(AnsiBuffer); return TRUE; }
@@ -3869,7 +4154,60 @@ BOOL ByPosition, LPMENUITEMINFOW mii) { - return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE); + MENUITEMINFOW miiW; + LPWSTR String; + INT Count; + + if (mii->cbSize != sizeof(MENUITEMINFOW) && + mii->cbSize != sizeof(MENUITEMINFOW) - sizeof(HBITMAP)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING))) + { + /* No text requested, just pass on */ + return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE); + } + + String = mii->dwTypeData; + Count = mii->cch; + RtlCopyMemory(&miiW, mii, mii->cbSize); + miiW.dwTypeData = 0; + + if (String) + { + miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0, + miiW.cch * sizeof(WCHAR)); + if (miiW.dwTypeData == NULL) return FALSE; + } + + if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) &miiW, FALSE)) + { + if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); + return FALSE; + } + + RtlCopyMemory(mii, &miiW, miiW.cbSize); // Okay to over write user data. + + if (!String || !Count) + { + if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); + mii->dwTypeData = String; // may not be zero. + mii->cch = miiW.cch; + return TRUE; + } + + if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType))) + { + lstrcpynW( String, miiW.dwTypeData, Count ); + } + + RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); + mii->dwTypeData = String; + mii->cch = strlenW(String); + return TRUE; }
@@ -3898,10 +4236,9 @@ { ROSMENUINFO MenuInfo; ROSMENUITEMINFO mii; - + memset( &mii, 0, sizeof(mii) ); mii.cbSize = sizeof(MENUITEMINFOW); - mii.fMask = MIIM_STATE | MIIM_TYPE | MIIM_SUBMENU; - mii.dwTypeData = NULL; + mii.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_SUBMENU;
SetLastError(0); if(NtUserMenuItemInfo(hMenu, uId, uFlags, &mii, FALSE)) @@ -3943,9 +4280,10 @@ UINT uFlag) { MENUITEMINFOA mii; + memset( &mii, 0, sizeof(mii) ); mii.dwTypeData = lpString; - mii.fMask = MIIM_STRING; - mii.fType = MF_STRING; + mii.fMask = MIIM_STRING | MIIM_FTYPE; + mii.fType = MFT_STRING; mii.cbSize = sizeof(MENUITEMINFOA); mii.cch = nMaxCount;
@@ -3969,8 +4307,10 @@ UINT uFlag) { MENUITEMINFOW miiW; + memset( &miiW, 0, sizeof(miiW) ); miiW.dwTypeData = lpString; - miiW.fMask = MIIM_STRING; + miiW.fMask = MIIM_STRING | MIIM_FTYPE; + miiW.fType = MFT_STRING; miiW.cbSize = sizeof(MENUITEMINFOW); miiW.cch = nMaxCount;
@@ -4033,6 +4373,7 @@ { return NtUserHiliteMenuItem(hwnd, hmenu, uItemHilite, uHilite); } +
/* @@ -4048,64 +4389,19 @@ LPCSTR lpNewItem) { MENUITEMINFOA mii; + memset( &mii, 0, sizeof(mii) ); mii.cbSize = sizeof(MENUITEMINFOA); - mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE; - mii.fType = 0; - mii.fState = MFS_ENABLED; - - if(uFlags & MF_BITMAP) - { - mii.fType |= MFT_BITMAP; - mii.fMask |= MIIM_BITMAP; - mii.hbmpItem = (HBITMAP) lpNewItem; - } - else if(uFlags & MF_OWNERDRAW) - { - mii.fType |= MFT_OWNERDRAW; - mii.fMask |= MIIM_DATA; - mii.dwItemData = (DWORD) lpNewItem; - } - else - { - mii.fMask |= MIIM_TYPE; - mii.dwTypeData = (LPSTR)lpNewItem; - mii.cch = (NULL == lpNewItem ? 0 : strlen(lpNewItem)); - } - - if(uFlags & MF_RIGHTJUSTIFY) - { - mii.fType |= MFT_RIGHTJUSTIFY; - } - if(uFlags & MF_MENUBREAK) - { - mii.fType |= MFT_MENUBREAK; - } - if(uFlags & MF_MENUBARBREAK) - { - mii.fType |= MFT_MENUBARBREAK; - } - if(uFlags & MF_DISABLED) - { - mii.fState |= MFS_DISABLED; - } - if(uFlags & MF_GRAYED) - { - mii.fState |= MFS_GRAYED; - } - - if(uFlags & MF_POPUP) - { - mii.fType |= MF_POPUP; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = (HMENU)uIDNewItem; - } - else - { - mii.fMask |= MIIM_ID; - mii.wID = (UINT)uIDNewItem; - } + mii.fMask = MIIM_FTYPE; + + MenuSetItemData((LPMENUITEMINFOW) &mii, + uFlags, + uIDNewItem, + (LPCWSTR) lpNewItem, + FALSE); + return InsertMenuItemA(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii); } +
/* @@ -4128,11 +4424,17 @@ if((lpmii->cbSize == sizeof(MENUITEMINFOA)) || (lpmii->cbSize == sizeof(MENUITEMINFOA) - sizeof(HBITMAP))) { - RtlMoveMemory ( &mi, lpmii, lpmii->cbSize ); - + RtlCopyMemory ( &mi, lpmii, lpmii->cbSize ); + + if( lpmii->cbSize != sizeof( MENUITEMINFOW)) + { + mi.cbSize = sizeof( MENUITEMINFOW); + mi.hbmpItem = NULL; + } /* copy the text string */ - if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) && - (MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData) + if (((mi.fMask & MIIM_STRING) || + ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING))) + && mi.dwTypeData != NULL) { Status = RtlCreateUnicodeStringFromAsciiz(&MenuText, (LPSTR)mi.dwTypeData); if (!NT_SUCCESS (Status)) @@ -4144,7 +4446,6 @@ mi.cch = MenuText.Length / sizeof(WCHAR); CleanHeap = TRUE; } - res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi);
if ( CleanHeap ) RtlFreeUnicodeString ( &MenuText ); @@ -4167,7 +4468,6 @@ MENUITEMINFOW mi; UNICODE_STRING MenuText; BOOL res = FALSE; - mi.hbmpItem = (HBITMAP)0;
/* while we could just pass 'lpmii' to win32k, we make a copy so that if a bad user passes bad data, we crash his process instead of the @@ -4176,18 +4476,22 @@ if((lpmii->cbSize == sizeof(MENUITEMINFOW)) || (lpmii->cbSize == sizeof(MENUITEMINFOW) - sizeof(HBITMAP))) { - memcpy(&mi, lpmii, lpmii->cbSize); - + RtlCopyMemory(&mi, lpmii, lpmii->cbSize); + + if( lpmii->cbSize != sizeof( MENUITEMINFOW)) + { + mi.cbSize = sizeof( MENUITEMINFOW); + mi.hbmpItem = NULL; + } /* copy the text string */ - if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) && - (MENU_ITEM_TYPE(mi.fType) == MF_STRING) && - mi.dwTypeData != NULL) + if (((mi.fMask & MIIM_STRING) || + ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING))) + && mi.dwTypeData != NULL) { RtlInitUnicodeString(&MenuText, (PWSTR)lpmii->dwTypeData); mi.dwTypeData = MenuText.Buffer; mi.cch = MenuText.Length / sizeof(WCHAR); - }; - + } res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi); } return res; @@ -4207,62 +4511,16 @@ LPCWSTR lpNewItem) { MENUITEMINFOW mii; + memset( &mii, 0, sizeof(mii) ); mii.cbSize = sizeof(MENUITEMINFOW); - mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE; - mii.fType = 0; - mii.fState = MFS_ENABLED; - - if(uFlags & MF_BITMAP) - { - mii.fType |= MFT_BITMAP; - mii.fMask |= MIIM_BITMAP; - mii.hbmpItem = (HBITMAP) lpNewItem; - } - else if(uFlags & MF_OWNERDRAW) - { - mii.fType |= MFT_OWNERDRAW; - mii.fMask |= MIIM_DATA; - mii.dwItemData = (DWORD) lpNewItem; - } - else - { - mii.fMask |= MIIM_TYPE; - mii.dwTypeData = (LPWSTR)lpNewItem; - mii.cch = (NULL == lpNewItem ? 0 : wcslen(lpNewItem)); - } - - if(uFlags & MF_RIGHTJUSTIFY) - { - mii.fType |= MFT_RIGHTJUSTIFY; - } - if(uFlags & MF_MENUBREAK) - { - mii.fType |= MFT_MENUBREAK; - } - if(uFlags & MF_MENUBARBREAK) - { - mii.fType |= MFT_MENUBARBREAK; - } - if(uFlags & MF_DISABLED) - { - mii.fState |= MFS_DISABLED; - } - if(uFlags & MF_GRAYED) - { - mii.fState |= MFS_GRAYED; - } - - if(uFlags & MF_POPUP) - { - mii.fType |= MF_POPUP; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = (HMENU)uIDNewItem; - } - else - { - mii.fMask |= MIIM_ID; - mii.wID = (UINT)uIDNewItem; - } + mii.fMask = MIIM_FTYPE; + + MenuSetItemData( &mii, + uFlags, + uIDNewItem, + lpNewItem, + TRUE); + return InsertMenuItemW(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii); }
@@ -4391,82 +4649,33 @@ UINT_PTR uIDNewItem, LPCSTR lpNewItem) { + ROSMENUINFO mi; + ROSMENUITEMINFO rmii; MENUITEMINFOA mii; memset( &mii, 0, sizeof(mii) ); mii.cbSize = sizeof(MENUITEMINFOA); - mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE; - mii.fType = 0; - mii.fState = MFS_ENABLED; - - if(!GetMenuItemInfoA( hMnu, - uPosition, - (BOOL)(MF_BYPOSITION & uFlags), - &mii)) return FALSE; - - if(uFlags & MF_BITMAP) - { - mii.fType |= MFT_BITMAP; - mii.fMask |= MIIM_BITMAP; - mii.hbmpItem = (HBITMAP) lpNewItem; - } - else if(uFlags & MF_OWNERDRAW) - { - mii.fType |= MFT_OWNERDRAW; - mii.fMask |= MIIM_DATA; - mii.dwItemData = (DWORD) lpNewItem; - } - else /* Default action MF_STRING. */ - { - if(mii.dwTypeData != NULL) - { - HeapFree(GetProcessHeap(),0, mii.dwTypeData); - } - /* Item beginning with a backspace is a help item */ - if (*lpNewItem == '\b') - { - mii.fType |= MF_HELP; - lpNewItem++; - } - mii.fMask |= MIIM_TYPE; - mii.dwTypeData = (LPSTR)lpNewItem; - mii.cch = (NULL == lpNewItem ? 0 : strlen(lpNewItem)); - } - - if(uFlags & MF_RIGHTJUSTIFY) - { - mii.fType |= MFT_RIGHTJUSTIFY; - } - if(uFlags & MF_MENUBREAK) - { - mii.fType |= MFT_MENUBREAK; - } - if(uFlags & MF_MENUBARBREAK) - { - mii.fType |= MFT_MENUBARBREAK; - } - if(uFlags & MF_DISABLED) - { - mii.fState |= MFS_DISABLED; - } - if(uFlags & MF_GRAYED) - { - mii.fState |= MFS_GRAYED; - } - - if ((mii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (mii.hSubMenu != (HMENU)uIDNewItem)) - NtUserDestroyMenu( mii.hSubMenu ); /* ModifyMenu() spec */ - - if(uFlags & MF_POPUP) - { - mii.fType |= MF_POPUP; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = (HMENU)uIDNewItem; - } - else - { - mii.fMask |= MIIM_ID; - mii.wID = (UINT)uIDNewItem; - } + mii.fMask = MIIM_FTYPE; + + if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE; + + mi.Height = 0; + + if (!MenuSetRosMenuInfo( &mi )) return FALSE; + + MenuInitRosMenuItemInfo( &rmii ); + + if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE; + + if ((rmii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem)) + NtUserDestroyMenu( rmii.hSubMenu ); /* ModifyMenu() spec */ + + MenuCleanupRosMenuItemInfo( &rmii ); + + MenuSetItemData((LPMENUITEMINFOW) &mii, + uFlags, + uIDNewItem, + (LPCWSTR) lpNewItem, + FALSE);
return SetMenuItemInfoA( hMnu, uPosition, @@ -4487,82 +4696,36 @@ UINT_PTR uIDNewItem, LPCWSTR lpNewItem) { + ROSMENUINFO mi; + ROSMENUITEMINFO rmii; MENUITEMINFOW mii; memset ( &mii, 0, sizeof(mii) ); mii.cbSize = sizeof(MENUITEMINFOW); - mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE; - mii.fState = MFS_ENABLED; - - if(!NtUserMenuItemInfo( hMnu, - uPosition, - (BOOL)(MF_BYPOSITION & uFlags), - (PROSMENUITEMINFO) &mii, - FALSE)) return FALSE; - - if(uFlags & MF_BITMAP) - { - mii.fType |= MFT_BITMAP; - mii.fMask |= MIIM_BITMAP; - mii.hbmpItem = (HBITMAP) lpNewItem; - } - else if(uFlags & MF_OWNERDRAW) - { - mii.fType |= MFT_OWNERDRAW; - mii.fMask |= MIIM_DATA; - mii.dwItemData = (DWORD) lpNewItem; - } - else - { - /*if(mii.dwTypeData != NULL) - { - HeapFree(GetProcessHeap(),0, mii.dwTypeData); - }*/ - if (*lpNewItem == '\b') - { - mii.fType |= MF_HELP; - lpNewItem++; - } - mii.fMask |= MIIM_TYPE; - mii.dwTypeData = (LPWSTR)lpNewItem; - mii.cch = (NULL == lpNewItem ? 0 : wcslen(lpNewItem)); - } - - if(uFlags & MF_RIGHTJUSTIFY) - { - mii.fType |= MFT_RIGHTJUSTIFY; - } - if(uFlags & MF_MENUBREAK) - { - mii.fType |= MFT_MENUBREAK; - } - if(uFlags & MF_MENUBARBREAK) - { - mii.fType |= MFT_MENUBARBREAK; - } - if(uFlags & MF_DISABLED) - { - mii.fState |= MFS_DISABLED; - } - if(uFlags & MF_GRAYED) - { - mii.fState |= MFS_GRAYED; - } - - if ((mii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (mii.hSubMenu != (HMENU)uIDNewItem)) - NtUserDestroyMenu( mii.hSubMenu ); - - if(uFlags & MF_POPUP) - { - mii.fType |= MF_POPUP; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = (HMENU)uIDNewItem; - } - else - { - mii.fMask |= MIIM_ID; - mii.wID = (UINT)uIDNewItem; - } - + mii.fMask = MIIM_FTYPE; + + if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE; + + mi.Height = 0; // Force size recalculation. + + if (!MenuSetRosMenuInfo( &mi )) return FALSE; + + MenuInitRosMenuItemInfo( &rmii ); + + if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE; + + if ((rmii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem)) + NtUserDestroyMenu( rmii.hSubMenu ); /* ModifyMenu() spec */ + + MenuCleanupRosMenuItemInfo( &rmii ); + + /* Init new data for this menu item */ + MenuSetItemData( &mii, + uFlags, + uIDNewItem, + lpNewItem, + TRUE); + + /* Now, make Win32k IntSetMenuItemInfo handle the changes to this menu item. */ return SetMenuItemInfoW( hMnu, uPosition, (BOOL)(MF_BYPOSITION & uFlags), @@ -4641,7 +4804,9 @@ HBITMAP hBitmapChecked) { ROSMENUITEMINFO uItem; - + memset ( &uItem, 0, sizeof(uItem) ); + uItem.fMask = MIIM_STATE | MIIM_BITMAP; + if(!(NtUserMenuItemInfo(hMenu, uPosition, (BOOL)(MF_BYPOSITION & uFlags), &uItem, FALSE))) return FALSE;
@@ -4673,16 +4838,35 @@ { MENUITEMINFOW MenuItemInfoW; UNICODE_STRING UnicodeString; - ULONG Result; + NTSTATUS Status; + ULONG Result = FALSE;
RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW)));
- if ((MenuItemInfoW.fMask & (MIIM_TYPE | MIIM_STRING)) && - (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING) && - MenuItemInfoW.dwTypeData != NULL) + if( lpmii->cbSize != sizeof( MENUITEMINFOW)) { - RtlCreateUnicodeStringFromAsciiz(&UnicodeString, + MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW); + MenuItemInfoW.hbmpItem = NULL; + } +/* + * MIIM_STRING == good + * MIIM_TYPE & MFT_STRING == good + * MIIM_STRING & MFT_STRING == good + * MIIM_STRING & MFT_OWNERSRAW == good + */ + if (((MenuItemInfoW.fMask & MIIM_STRING) || + ((MenuItemInfoW.fMask & MIIM_TYPE) && + (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING))) + && MenuItemInfoW.dwTypeData != NULL) + { +/* cch is ignored when the content of a menu item is set by calling SetMenuItemInfo. */ + Status = RtlCreateUnicodeStringFromAsciiz(&UnicodeString, (LPSTR)MenuItemInfoW.dwTypeData); + if (!NT_SUCCESS (Status)) + { + SetLastError (RtlNtStatusToDosError(Status)); + return FALSE; + } MenuItemInfoW.dwTypeData = UnicodeString.Buffer; MenuItemInfoW.cch = UnicodeString.Length / sizeof(WCHAR); } @@ -4715,15 +4899,27 @@ LPCMENUITEMINFOW lpmii) { MENUITEMINFOW MenuItemInfoW; + ULONG Result;
RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW))); - if (0 != (MenuItemInfoW.fMask & MIIM_STRING)) + + if( lpmii->cbSize != sizeof( MENUITEMINFOW)) { - MenuItemInfoW.cch = wcslen(MenuItemInfoW.dwTypeData); + MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW); + MenuItemInfoW.hbmpItem = NULL; }
- return NtUserMenuItemInfo(hMenu, uItem, fByPosition, + if (((MenuItemInfoW.fMask & MIIM_STRING) || + ((MenuItemInfoW.fMask & MIIM_TYPE) && + (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING))) + && MenuItemInfoW.dwTypeData != NULL) + { + MenuItemInfoW.cch = strlenW(MenuItemInfoW.dwTypeData); + } + Result = NtUserMenuItemInfo(hMenu, uItem, fByPosition, (PROSMENUITEMINFO)&MenuItemInfoW, TRUE); + + return Result; }
/* @@ -4939,3 +5135,5 @@ return InsertMenuA(hMenu, cmd, flags, cmdInsert, lpszNewItem); }; } + +
Modified: branches/ros-branch-0_3_0/reactos/include/reactos/win32k/ntusrtyp.h URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_0/reactos/include... ============================================================================== --- branches/ros-branch-0_3_0/reactos/include/reactos/win32k/ntusrtyp.h (original) +++ branches/ros-branch-0_3_0/reactos/include/reactos/win32k/ntusrtyp.h Mon Jul 31 09:18:08 2006 @@ -164,6 +164,7 @@ /* ----------- Extra ----------- */ RECT Rect; /* Item area (relative to menu window) */ UINT XTab; /* X position of text after Tab */ + LPWSTR Text; /* Copy of the text pointer in MenuItem->Text */ } ROSMENUITEMINFO, *PROSMENUITEMINFO;
#endif
Modified: branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/menu.c URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_0/reactos/subsyst... ============================================================================== --- branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/menu.c (original) +++ branches/ros-branch-0_3_0/reactos/subsystems/win32/win32k/ntuser/menu.c Mon Jul 31 09:18:08 2006 @@ -277,6 +277,7 @@ { if(Menu) { + PWINDOW_OBJECT Window; PWINSTATION_OBJECT WindowStation; NTSTATUS Status;
@@ -296,6 +297,14 @@ NULL); if(NT_SUCCESS(Status)) { + if (Menu->MenuInfo.Wnd) + { + Window = UserGetWindowObject(Menu->MenuInfo.Wnd); + if (Window) + { + Window->IDMenu = 0; + } + } ObmDeleteObject(Menu->MenuInfo.Self, otMenu); ObDereferenceObject(WindowStation); return TRUE; @@ -683,6 +692,10 @@ { NTSTATUS Status;
+ if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE)) + { + lpmii->fType = MenuItem->fType; + } if(lpmii->fMask & MIIM_BITMAP) { lpmii->hbmpItem = MenuItem->hbmpItem; @@ -696,10 +709,6 @@ { lpmii->dwItemData = MenuItem->dwItemData; } - if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE)) - { - lpmii->fType = MenuItem->fType; - } if(lpmii->fMask & MIIM_ID) { lpmii->wID = MenuItem->wID; @@ -712,7 +721,9 @@ { lpmii->hSubMenu = MenuItem->hSubMenu; } - if (lpmii->fMask & (MIIM_STRING | MIIM_TYPE)) + + if ((lpmii->fMask & MIIM_STRING) || + ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))) { if (lpmii->dwTypeData == NULL) { @@ -735,6 +746,7 @@ { lpmii->Rect = MenuItem->Rect; lpmii->XTab = MenuItem->XTab; + lpmii->Text = MenuItem->Text.Buffer; }
return TRUE; @@ -752,36 +764,61 @@ } if( lpmii->fType & ~fTypeMask) { - DPRINT("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask); + DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask); lpmii->fMask &= ~(MIIM_TYPE | MIIM_FTYPE); } - if(lpmii->fMask & MIIM_BITMAP) - { - MenuItem->hbmpItem = lpmii->hbmpItem; - } - if(lpmii->fMask & MIIM_CHECKMARKS) - { - MenuItem->hbmpChecked = lpmii->hbmpChecked; - MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked; - } - if(lpmii->fMask & MIIM_DATA) - { - MenuItem->dwItemData = lpmii->dwItemData; - } - if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE)) - { + if(lpmii->fMask & MIIM_TYPE) + { + if(lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) + { + DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n"); + /* this does not happen on Win9x/ME */ + SetLastNtError( ERROR_INVALID_PARAMETER); + return FALSE; + } /* * Delete the menu item type when changing type from * MF_STRING. */ if (MenuItem->fType != lpmii->fType && - MENU_ITEM_TYPE(MenuItem->fType) == MF_STRING) + MENU_ITEM_TYPE(MenuItem->fType) == MFT_STRING) { FreeMenuText(MenuItem); RtlInitUnicodeString(&MenuItem->Text, NULL); } - MenuItem->fType &= ~MENU_ITEM_TYPE(MenuItem->fType); - MenuItem->fType |= MENU_ITEM_TYPE(lpmii->fType); + if(lpmii->fType & MFT_BITMAP) + { +// if(lpmii->hbmpItem) + MenuItem->hbmpItem = lpmii->hbmpItem; +// else +// { /* Win 9x/Me stuff */ +// MenuItem->hbmpItem = (HBITMAP)lpmii->dwTypeData; +// } + } + MenuItem->fType |= lpmii->fType; + } + if (lpmii->fMask & MIIM_FTYPE ) + { + if(( lpmii->fType & MFT_BITMAP)) + { + DbgPrint("IntSetMenuItemInfo: Can not use FTYPE and MFT_BITMAP.\n"); + SetLastNtError( ERROR_INVALID_PARAMETER); + return FALSE; + } + MenuItem->fType |= lpmii->fType; /* Need to save all the flags, this fixed MFT_RIGHTJUSTIFY */ + } + if(lpmii->fMask & MIIM_BITMAP) + { + MenuItem->hbmpItem = lpmii->hbmpItem; + } + if(lpmii->fMask & MIIM_CHECKMARKS) + { + MenuItem->hbmpChecked = lpmii->hbmpChecked; + MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked; + } + if(lpmii->fMask & MIIM_DATA) + { + MenuItem->dwItemData = lpmii->dwItemData; } if(lpmii->fMask & MIIM_ID) { @@ -819,8 +856,9 @@ MenuItem->fType &= ~MF_POPUP; } } - if ((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) && - (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)) + + if ((lpmii->fMask & MIIM_STRING) || + ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))) { FreeMenuText(MenuItem);
@@ -860,6 +898,7 @@ { MenuItem->Rect = lpmii->Rect; MenuItem->XTab = lpmii->XTab; + lpmii->Text = MenuItem->Text.Buffer; /* Send back new allocated string or zero */ }
return TRUE; @@ -1019,6 +1058,7 @@ mii.hSubMenu = CurItem->hSubMenu; mii.Rect = CurItem->Rect; mii.XTab = CurItem->XTab; + mii.Text = CurItem->Text.Buffer;
Status = MmCopyToCaller(Buf, &mii, sizeof(ROSMENUITEMINFO)); if (! NT_SUCCESS(Status)) @@ -1397,27 +1437,38 @@ { PWINSTATION_OBJECT WinStaObject; HANDLE Handle; - - NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, + NTSTATUS Status; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + + if (CsrProcess != CurrentProcess) + { + /* + * CsrProcess does not have a Win32WindowStation + * + */ + + Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, KernelMode, 0, &WinStaObject);
- if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of window station handle (0x%X) failed\n", - PsGetCurrentProcess()->Win32WindowStation); - SetLastNtError(Status); - return (HMENU)0; - } - - IntCreateMenu(&Handle, !PopupMenu); - - ObDereferenceObject(WinStaObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Validation of window station handle (0x%X) failed\n", + CurrentProcess->Win32WindowStation); + SetLastNtError(Status); + return (HMENU)0; + } + IntCreateMenu(&Handle, !PopupMenu); + ObDereferenceObject(WinStaObject); + } + else + { + IntCreateMenu(&Handle, !PopupMenu); + } + return (HMENU)Handle; } - -
HMENU STDCALL NtUserCreateMenu(BOOL PopupMenu)