Implement menu handling

svn path=/trunk/; revision=8195
This commit is contained in:
Gé van Geldorp 2004-02-15 07:39:12 +00:00
parent a3ac53db3d
commit 6fc29ccca7
8 changed files with 2977 additions and 511 deletions

View file

@ -12,6 +12,7 @@
#include <win32k/icm.h> #include <win32k/icm.h>
#include <win32k/line.h> #include <win32k/line.h>
#include <win32k/metafile.h> #include <win32k/metafile.h>
#include <win32k/menu.h>
#include <win32k/misc.h> #include <win32k/misc.h>
#include <win32k/ntuser.h> #include <win32k/ntuser.h>
#include <win32k/paint.h> #include <win32k/paint.h>

View file

@ -0,0 +1,249 @@
/* $Id: menu.h,v 1.1 2004/02/15 07:39:12 gvg Exp $ */
#ifndef WIN32K_MENU_H_INCLUDED
#define WIN32K_MENU_H_INCLUDED
typedef struct tagROSMENUINFO {
/* ----------- MENUINFO ----------- */
DWORD cbSize;
DWORD fMask;
DWORD dwStyle;
UINT cyMax;
HBRUSH hbrBack;
DWORD dwContextHelpID;
ULONG_PTR dwMenuData;
/* ----------- Extra ----------- */
HMENU Self; /* Handle of this menu */
WORD Flags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
UINT FocusedItem; /* Currently focused item */
UINT MenuItemCount; /* Number of items in the menu */
HWND Wnd; /* Window containing the menu */
WORD Width; /* Width of the whole menu */
WORD Height; /* Height of the whole menu */
HWND WndOwner; /* window receiving the messages for ownerdraw */
BOOL TimeToHide; /* Request hiding when receiving a second click in the top-level menu item */
} ROSMENUINFO, *PROSMENUINFO;
/* (other FocusedItem values give the position of the focused item) */
#define NO_SELECTED_ITEM 0xffff
typedef struct tagROSMENUITEMINFO
{
/* ----------- MENUITEMINFOW ----------- */
UINT cbSize;
UINT fMask;
UINT fType;
UINT fState;
UINT wID;
HMENU hSubMenu;
HBITMAP hbmpChecked;
HBITMAP hbmpUnchecked;
DWORD dwItemData;
LPWSTR dwTypeData;
UINT cch;
HBITMAP hbmpItem;
/* ----------- Extra ----------- */
RECT Rect; /* Item area (relative to menu window) */
UINT XTab; /* X position of text after Tab */
} ROSMENUITEMINFO, *PROSMENUITEMINFO;
typedef struct _SETMENUITEMRECT
{
UINT uItem;
BOOL fByPosition;
RECT rcRect;
} SETMENUITEMRECT, *PSETMENUITEMRECT;
DWORD
STDCALL
NtUserBuildMenuItemList(
HMENU hMenu,
PVOID Buffer,
ULONG nBufSize,
DWORD Reserved);
DWORD
STDCALL
NtUserCheckMenuItem(
HMENU hmenu,
UINT uIDCheckItem,
UINT uCheck);
HMENU
STDCALL
NtUserCreateMenu(BOOL PopupMenu);
BOOL
STDCALL
NtUserDeleteMenu(
HMENU hMenu,
UINT uPosition,
UINT uFlags);
BOOL
STDCALL
NtUserDestroyMenu(
HMENU hMenu);
DWORD
STDCALL
NtUserDrawMenuBarTemp(
HWND hWnd,
HDC hDC,
PRECT hRect,
HMENU hMenu,
HFONT hFont);
UINT
STDCALL
NtUserEnableMenuItem(
HMENU hMenu,
UINT uIDEnableItem,
UINT uEnable);
DWORD
STDCALL
NtUserInsertMenuItem(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
LPCMENUITEMINFOW lpmii);
BOOL
STDCALL
NtUserEndMenu(VOID);
UINT STDCALL
NtUserGetMenuDefaultItem(
HMENU hMenu,
UINT fByPos,
UINT gmdiFlags);
BOOL
STDCALL
NtUserGetMenuBarInfo(
HWND hwnd,
LONG idObject,
LONG idItem,
PMENUBARINFO pmbi);
UINT
STDCALL
NtUserGetMenuIndex(
HMENU hMenu,
UINT wID);
BOOL
STDCALL
NtUserGetMenuItemRect(
HWND hWnd,
HMENU hMenu,
UINT uItem,
LPRECT lprcItem);
HMENU
STDCALL
NtUserGetSystemMenu(
HWND hWnd,
BOOL bRevert);
BOOL
STDCALL
NtUserHiliteMenuItem(
HWND hwnd,
HMENU hmenu,
UINT uItemHilite,
UINT uHilite);
BOOL
STDCALL
NtUserMenuInfo(
HMENU hmenu,
PROSMENUINFO lpmi,
BOOL fsog
);
int
STDCALL
NtUserMenuItemFromPoint(
HWND hWnd,
HMENU hMenu,
DWORD X,
DWORD Y);
BOOL
STDCALL
NtUserMenuItemInfo(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
PROSMENUITEMINFO lpmii,
BOOL fsog
);
BOOL
STDCALL
NtUserRemoveMenu(
HMENU hMenu,
UINT uPosition,
UINT uFlags);
BOOL
STDCALL
NtUserSetMenu(
HWND hWnd,
HMENU hMenu,
BOOL bRepaint);
BOOL
STDCALL
NtUserSetMenuContextHelpId(
HMENU hmenu,
DWORD dwContextHelpId);
BOOL
STDCALL
NtUserSetMenuDefaultItem(
HMENU hMenu,
UINT uItem,
UINT fByPos);
BOOL
STDCALL
NtUserSetMenuFlagRtoL(
HMENU hMenu);
BOOL
STDCALL
NtUserSetSystemMenu(
HWND hWnd,
HMENU hMenu);
DWORD
STDCALL
NtUserThunkedMenuInfo(
HMENU hMenu,
LPCMENUINFO lpcmi);
DWORD
STDCALL
NtUserThunkedMenuItemInfo(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
BOOL bInsert,
LPMENUITEMINFOW lpmii,
PUNICODE_STRING lpszCaption);
BOOL
STDCALL
NtUserTrackPopupMenuEx(
HMENU hmenu,
UINT fuFlags,
int x,
int y,
HWND hwnd,
LPTPMPARAMS lptpm);
#endif /* WIN32K_MENU_H_INCLUDED */

View file

@ -84,14 +84,6 @@ NtUserBuildHwndList(
HWND* pWnd, HWND* pWnd,
ULONG nBufSize); ULONG nBufSize);
DWORD
STDCALL
NtUserBuildMenuItemList(
HMENU hMenu,
PVOID Buffer,
ULONG nBufSize,
DWORD Reserved);
NTSTATUS STDCALL NTSTATUS STDCALL
NtUserBuildNameList( NtUserBuildNameList(
HWINSTA hWinSta, HWINSTA hWinSta,
@ -225,13 +217,6 @@ NtUserChangeDisplaySettings(
DWORD dwflags, DWORD dwflags,
LPVOID lParam); LPVOID lParam);
DWORD
STDCALL
NtUserCheckMenuItem(
HMENU hmenu,
UINT uIDCheckItem,
UINT uCheck);
HWND STDCALL HWND STDCALL
NtUserChildWindowFromPointEx(HWND Parent, NtUserChildWindowFromPointEx(HWND Parent,
LONG x, LONG x,
@ -311,10 +296,6 @@ NtUserCreateLocalMemHandle(
DWORD Unknown2, DWORD Unknown2,
DWORD Unknown3); DWORD Unknown3);
HMENU
STDCALL
NtUserCreateMenu(BOOL PopupMenu);
HWND HWND
STDCALL STDCALL
NtUserCreateWindowEx( NtUserCreateWindowEx(
@ -378,13 +359,6 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
BOOL STDCALL BOOL STDCALL
NtUserDefSetText(HWND WindowHandle, PANSI_STRING Text); NtUserDefSetText(HWND WindowHandle, PANSI_STRING Text);
BOOL
STDCALL
NtUserDeleteMenu(
HMENU hMenu,
UINT uPosition,
UINT uFlags);
BOOLEAN BOOLEAN
STDCALL STDCALL
NtUserDestroyAcceleratorTable( NtUserDestroyAcceleratorTable(
@ -396,11 +370,6 @@ NtUserDestroyCursorIcon(
HANDLE Handle, HANDLE Handle,
DWORD Unknown); DWORD Unknown);
BOOL
STDCALL
NtUserDestroyMenu(
HMENU hMenu);
BOOLEAN STDCALL BOOLEAN STDCALL
NtUserDestroyWindow(HWND Wnd); NtUserDestroyWindow(HWND Wnd);
@ -467,35 +436,10 @@ NtUserDrawIconEx(
DWORD Unknown0, DWORD Unknown0,
DWORD Unknown1); DWORD Unknown1);
DWORD
STDCALL
NtUserDrawMenuBarTemp(
HWND hWnd,
HDC hDC,
PRECT hRect,
HMENU hMenu,
HFONT hFont);
DWORD DWORD
STDCALL STDCALL
NtUserEmptyClipboard(VOID); NtUserEmptyClipboard(VOID);
UINT
STDCALL
NtUserEnableMenuItem(
HMENU hMenu,
UINT uIDEnableItem,
UINT uEnable);
DWORD
STDCALL
NtUserInsertMenuItem(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
LPCMENUITEMINFOW lpmii);
BOOL BOOL
STDCALL STDCALL
NtUserEnableScrollBar( NtUserEnableScrollBar(
@ -509,10 +453,6 @@ NtUserEndDeferWindowPosEx(
DWORD Unknown0, DWORD Unknown0,
DWORD Unknown1); DWORD Unknown1);
BOOL
STDCALL
NtUserEndMenu(VOID);
BOOL STDCALL BOOL STDCALL
NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* lPs); NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* lPs);
@ -693,16 +633,17 @@ STDCALL
NtUserGetCursorInfo( NtUserGetCursorInfo(
PCURSORINFO pci); PCURSORINFO pci);
UINT STDCALL HDC
NtUserGetMenuDefaultItem( STDCALL
HMENU hMenu, NtUserGetDC(
UINT fByPos, HWND hWnd);
UINT gmdiFlags);
HDC STDCALL HDC
NtUserGetDC(HWND hWnd); STDCALL
NtUserGetDCEx(
HDC STDCALL NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags); HWND hWnd,
HANDLE hRegion,
ULONG Flags);
UINT UINT
STDCALL STDCALL
@ -782,28 +723,6 @@ STDCALL
NtUserGetListBoxInfo( NtUserGetListBoxInfo(
DWORD Unknown0); DWORD Unknown0);
BOOL
STDCALL
NtUserGetMenuBarInfo(
HWND hwnd,
LONG idObject,
LONG idItem,
PMENUBARINFO pmbi);
UINT
STDCALL
NtUserGetMenuIndex(
HMENU hMenu,
UINT wID);
BOOL
STDCALL
NtUserGetMenuItemRect(
HWND hWnd,
HMENU hMenu,
UINT uItem,
LPRECT lprcItem);
BOOL BOOL
STDCALL STDCALL
NtUserGetMessage( NtUserGetMessage(
@ -858,12 +777,6 @@ NtUserGetScrollInfo(
int fnBar, int fnBar,
LPSCROLLINFO lpsi); LPSCROLLINFO lpsi);
HMENU
STDCALL
NtUserGetSystemMenu(
HWND hWnd,
BOOL bRevert);
HDESK HDESK
STDCALL STDCALL
NtUserGetThreadDesktop( NtUserGetThreadDesktop(
@ -913,14 +826,6 @@ STDCALL
NtUserHideCaret( NtUserHideCaret(
HWND hWnd); HWND hWnd);
BOOL
STDCALL
NtUserHiliteMenuItem(
HWND hwnd,
HMENU hmenu,
UINT uItemHilite,
UINT uHilite);
DWORD DWORD
STDCALL STDCALL
NtUserImpersonateDdeClientWindow( NtUserImpersonateDdeClientWindow(
@ -1024,32 +929,6 @@ NtUserMapVirtualKeyEx( UINT keyCode,
DWORD keyboardId, DWORD keyboardId,
HKL dwhkl ); HKL dwhkl );
BOOL
STDCALL
NtUserMenuInfo(
HMENU hmenu,
LPMENUINFO lpmi,
BOOL fsog
);
int
STDCALL
NtUserMenuItemFromPoint(
HWND hWnd,
HMENU hMenu,
DWORD X,
DWORD Y);
BOOL
STDCALL
NtUserMenuItemInfo(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
LPMENUITEMINFOW lpmii,
BOOL fsog
);
DWORD DWORD
STDCALL STDCALL
NtUserMessageCall( NtUserMessageCall(
@ -1226,13 +1105,6 @@ NtUserRegisterTasklist(
UINT STDCALL UINT STDCALL
NtUserRegisterWindowMessage(PUNICODE_STRING MessageName); NtUserRegisterWindowMessage(PUNICODE_STRING MessageName);
BOOL
STDCALL
NtUserRemoveMenu(
HMENU hMenu,
UINT uPosition,
UINT uFlags);
HANDLE STDCALL HANDLE STDCALL
NtUserRemoveProp(HWND hWnd, ATOM Atom); NtUserRemoveProp(HWND hWnd, ATOM Atom);
@ -1419,31 +1291,6 @@ STDCALL
NtUserSetLogonNotifyWindow( NtUserSetLogonNotifyWindow(
DWORD Unknown0); DWORD Unknown0);
BOOL
STDCALL
NtUserSetMenu(
HWND hWnd,
HMENU hMenu,
BOOL bRepaint);
BOOL
STDCALL
NtUserSetMenuContextHelpId(
HMENU hmenu,
DWORD dwContextHelpId);
BOOL
STDCALL
NtUserSetMenuDefaultItem(
HMENU hMenu,
UINT uItem,
UINT fByPos);
BOOL
STDCALL
NtUserSetMenuFlagRtoL(
HMENU hMenu);
BOOL BOOL
STDCALL STDCALL
NtUserSetObjectInformation( NtUserSetObjectInformation(
@ -1504,12 +1351,6 @@ NtUserSetSystemCursor(
HCURSOR hcur, HCURSOR hcur,
DWORD id); DWORD id);
BOOL
STDCALL
NtUserSetSystemMenu(
HWND hWnd,
HMENU hMenu);
BOOL BOOL
STDCALL STDCALL
NtUserSetThreadDesktop( NtUserSetThreadDesktop(
@ -1653,22 +1494,6 @@ NtUserSystemParametersInfo(
PVOID pvParam, PVOID pvParam,
UINT fWinIni); UINT fWinIni);
DWORD
STDCALL
NtUserThunkedMenuInfo(
HMENU hMenu,
LPCMENUINFO lpcmi);
DWORD
STDCALL
NtUserThunkedMenuItemInfo(
HMENU hMenu,
UINT uItem,
BOOL fByPosition,
BOOL bInsert,
LPMENUITEMINFOW lpmii,
PUNICODE_STRING lpszCaption);
int int
STDCALL STDCALL
NtUserToUnicodeEx( NtUserToUnicodeEx(
@ -1685,16 +1510,6 @@ STDCALL
NtUserTrackMouseEvent( NtUserTrackMouseEvent(
DWORD Unknown0); DWORD Unknown0);
BOOL
STDCALL
NtUserTrackPopupMenuEx(
HMENU hmenu,
UINT fuFlags,
int x,
int y,
HWND hwnd,
LPTPMPARAMS lptpm);
int int
STDCALL STDCALL
NtUserTranslateAccelerator( NtUserTranslateAccelerator(
@ -1876,13 +1691,6 @@ NtUserSetScrollBarInfo(
LONG idObject, LONG idObject,
SETSCROLLBARINFO *info); SETSCROLLBARINFO *info);
typedef struct _SETMENUITEMRECT
{
UINT uItem;
BOOL fByPosition;
RECT rcRect;
} SETMENUITEMRECT, *PSETMENUITEMRECT;
#endif /* __WIN32K_NTUSER_H */ #endif /* __WIN32K_NTUSER_H */
/* EOF */ /* EOF */

File diff suppressed because it is too large Load diff

View file

@ -3,6 +3,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <napi/win32.h> #include <napi/win32.h>
#include <win32k/menu.h>
#define IS_ATOM(x) \ #define IS_ATOM(x) \
(((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000))
@ -27,21 +28,17 @@ typedef struct _MENU_ITEM
UNICODE_STRING Text; UNICODE_STRING Text;
HBITMAP hbmpItem; HBITMAP hbmpItem;
RECT Rect; RECT Rect;
UINT XTab;
} MENU_ITEM, *PMENU_ITEM; } MENU_ITEM, *PMENU_ITEM;
typedef struct _MENU_OBJECT typedef struct _MENU_OBJECT
{ {
HANDLE Self;
PW32PROCESS W32Process; PW32PROCESS W32Process;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
int MenuItemCount;
FAST_MUTEX MenuItemsLock; FAST_MUTEX MenuItemsLock;
PMENU_ITEM MenuItemList; PMENU_ITEM MenuItemList;
MENUINFO MenuInfo; ROSMENUINFO MenuInfo;
BOOL RtoL; BOOL RtoL;
BOOL IsSystemMenu;
BOOL IsMenuBar;
int Height;
} MENU_OBJECT, *PMENU_OBJECT; } MENU_OBJECT, *PMENU_OBJECT;
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
@ -77,28 +74,18 @@ BOOL FASTCALL
IntSetMenuContextHelpId(PMENU_OBJECT MenuObject, DWORD dwContextHelpId); IntSetMenuContextHelpId(PMENU_OBJECT MenuObject, DWORD dwContextHelpId);
BOOL FASTCALL BOOL FASTCALL
IntGetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi); IntGetMenuInfo(PMENU_OBJECT MenuObject, PROSMENUINFO lpmi);
BOOL FASTCALL BOOL FASTCALL
IntIsMenu(HMENU hMenu); IntIsMenu(HMENU hMenu);
BOOL FASTCALL BOOL FASTCALL
IntSetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi); IntSetMenuInfo(PMENU_OBJECT MenuObject, PROSMENUINFO lpmi);
int FASTCALL int FASTCALL
IntGetMenuItemByFlag(PMENU_OBJECT MenuObject, UINT uSearchBy, UINT fFlag, IntGetMenuItemByFlag(PMENU_OBJECT MenuObject, UINT uSearchBy, UINT fFlag,
PMENU_ITEM *MenuItem, PMENU_ITEM *PrevMenuItem); PMENU_ITEM *MenuItem, PMENU_ITEM *PrevMenuItem);
BOOL FASTCALL
IntGetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPMENUITEMINFOW lpmii);
BOOL FASTCALL
IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFOW lpmii);
BOOL FASTCALL
IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
LPCMENUITEMINFOW lpmii);
UINT FASTCALL UINT FASTCALL
IntEnableMenuItem(PMENU_OBJECT MenuObject, UINT uIDEnableItem, UINT uEnable); IntEnableMenuItem(PMENU_OBJECT MenuObject, UINT uIDEnableItem, UINT uEnable);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: menu.c,v 1.43 2004/01/26 23:22:48 weiden Exp $ /* $Id: menu.c,v 1.44 2004/02/15 07:39:12 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -71,6 +71,11 @@
} else { \ } else { \
(state) &= ~MFS_DEFAULT; \ (state) &= ~MFS_DEFAULT; \
} \ } \
if((change) & MF_MOUSESELECT) { \
(state) |= MF_MOUSESELECT; \
} else { \
(state) &= ~MF_MOUSESELECT; \
} \
} }
#define FreeMenuText(MenuItem) \ #define FreeMenuText(MenuItem) \
@ -171,7 +176,7 @@ IntFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem,
if(RemoveFromList) if(RemoveFromList)
{ {
/* FIXME - Remove from List */ /* FIXME - Remove from List */
MenuObject->MenuItemCount--; MenuObject->MenuInfo.MenuItemCount--;
} }
if(bRecurse && MenuItem->hSubMenu) if(bRecurse && MenuItem->hSubMenu)
{ {
@ -225,7 +230,7 @@ IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse)
CurItem = NextItem; CurItem = NextItem;
res++; res++;
} }
MenuObject->MenuItemCount = 0; MenuObject->MenuInfo.MenuItemCount = 0;
MenuObject->MenuItemList = NULL; MenuObject->MenuItemList = NULL;
return res; return res;
} }
@ -248,7 +253,7 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject,
ExReleaseFastMutexUnsafe(&MenuObject->W32Process->MenuListLock); ExReleaseFastMutexUnsafe(&MenuObject->W32Process->MenuListLock);
} }
ObmCloseHandle(MenuObject->W32Process->WindowStation->HandleTable, MenuObject->Self); ObmCloseHandle(MenuObject->W32Process->WindowStation->HandleTable, MenuObject->MenuInfo.Self);
return TRUE; return TRUE;
} }
@ -271,8 +276,6 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
return NULL; return NULL;
} }
MenuObject->Self = *Handle;
MenuObject->IsMenuBar = IsMenuBar;
MenuObject->W32Process = Win32Process; MenuObject->W32Process = Win32Process;
MenuObject->RtoL = FALSE; /* default */ MenuObject->RtoL = FALSE; /* default */
MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */ MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
@ -283,8 +286,16 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */ NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
MenuObject->MenuInfo.dwContextHelpID = 0; /* default */ MenuObject->MenuInfo.dwContextHelpID = 0; /* default */
MenuObject->MenuInfo.dwMenuData = 0; /* default */ MenuObject->MenuInfo.dwMenuData = 0; /* default */
MenuObject->MenuInfo.Self = *Handle;
MenuObject->MenuInfo.FocusedItem = NO_SELECTED_ITEM;
MenuObject->MenuInfo.Flags = (IsMenuBar ? 0 : MF_POPUP);
MenuObject->MenuInfo.Wnd = NULL;
MenuObject->MenuInfo.WndOwner = NULL;
MenuObject->MenuInfo.Height = 0;
MenuObject->MenuInfo.Width = 0;
MenuObject->MenuInfo.TimeToHide = FALSE;
MenuObject->MenuItemCount = 0; MenuObject->MenuInfo.MenuItemCount = 0;
MenuObject->MenuItemList = NULL; MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock); ExInitializeFastMutex(&MenuObject->MenuItemsLock);
@ -302,7 +313,7 @@ IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
PMENU_ITEM MenuItem, NewMenuItem = NULL; PMENU_ITEM MenuItem, NewMenuItem = NULL;
PMENU_ITEM Old = NULL; PMENU_ITEM Old = NULL;
if(!Source->MenuItemCount) if(!Source->MenuInfo.MenuItemCount)
return FALSE; return FALSE;
ExAcquireFastMutexUnsafe(&Destination->MenuItemsLock); ExAcquireFastMutexUnsafe(&Destination->MenuItemsLock);
@ -354,7 +365,7 @@ IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
Old->Next = NewMenuItem; Old->Next = NewMenuItem;
else else
Destination->MenuItemList = NewMenuItem; Destination->MenuItemList = NewMenuItem;
Destination->MenuItemCount++; Destination->MenuInfo.MenuItemCount++;
MenuItem = MenuItem->Next; MenuItem = MenuItem->Next;
} }
@ -379,7 +390,6 @@ IntCloneMenu(PMENU_OBJECT Source)
if(!MenuObject) if(!MenuObject)
return NULL; return NULL;
MenuObject->Self = Handle;
MenuObject->W32Process = Process; MenuObject->W32Process = Process;
MenuObject->RtoL = Source->RtoL; MenuObject->RtoL = Source->RtoL;
MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */ MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
@ -389,8 +399,15 @@ IntCloneMenu(PMENU_OBJECT Source)
MenuObject->MenuInfo.hbrBack = Source->MenuInfo.hbrBack; MenuObject->MenuInfo.hbrBack = Source->MenuInfo.hbrBack;
MenuObject->MenuInfo.dwContextHelpID = Source->MenuInfo.dwContextHelpID; MenuObject->MenuInfo.dwContextHelpID = Source->MenuInfo.dwContextHelpID;
MenuObject->MenuInfo.dwMenuData = Source->MenuInfo.dwMenuData; MenuObject->MenuInfo.dwMenuData = Source->MenuInfo.dwMenuData;
MenuObject->MenuInfo.Self = Handle;
MenuObject->MenuInfo.FocusedItem = NO_SELECTED_ITEM;
MenuObject->MenuInfo.Wnd = NULL;
MenuObject->MenuInfo.WndOwner = NULL;
MenuObject->MenuInfo.Height = 0;
MenuObject->MenuInfo.Width = 0;
MenuObject->MenuInfo.TimeToHide = FALSE;
MenuObject->MenuItemCount = 0; MenuObject->MenuInfo.MenuItemCount = 0;
MenuObject->MenuItemList = NULL; MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock); ExInitializeFastMutex(&MenuObject->MenuItemsLock);
@ -419,9 +436,7 @@ IntSetMenuContextHelpId(PMENU_OBJECT MenuObject, DWORD dwContextHelpId)
} }
BOOL FASTCALL BOOL FASTCALL
IntGetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi) IntGetMenuInfo(PMENU_OBJECT MenuObject, PROSMENUINFO lpmi)
{
if(MenuObject)
{ {
if(lpmi->fMask & MIM_BACKGROUND) if(lpmi->fMask & MIM_BACKGROUND)
lpmi->hbrBack = MenuObject->MenuInfo.hbrBack; lpmi->hbrBack = MenuObject->MenuInfo.hbrBack;
@ -433,9 +448,14 @@ IntGetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi)
lpmi->dwMenuData = MenuObject->MenuInfo.dwMenuData; lpmi->dwMenuData = MenuObject->MenuInfo.dwMenuData;
if(lpmi->fMask & MIM_STYLE) if(lpmi->fMask & MIM_STYLE)
lpmi->dwStyle = MenuObject->MenuInfo.dwStyle; lpmi->dwStyle = MenuObject->MenuInfo.dwStyle;
return TRUE; if (sizeof(MENUINFO) < lpmi->cbSize)
{
RtlCopyMemory((char *) lpmi + sizeof(MENUINFO),
(char *) &MenuObject->MenuInfo + sizeof(MENUINFO),
lpmi->cbSize - sizeof(MENUINFO));
} }
return FALSE;
return TRUE;
} }
@ -454,7 +474,7 @@ IntIsMenu(HMENU hMenu)
BOOL FASTCALL BOOL FASTCALL
IntSetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi) IntSetMenuInfo(PMENU_OBJECT MenuObject, PROSMENUINFO lpmi)
{ {
if(lpmi->fMask & MIM_BACKGROUND) if(lpmi->fMask & MIM_BACKGROUND)
MenuObject->MenuInfo.hbrBack = lpmi->hbrBack; MenuObject->MenuInfo.hbrBack = lpmi->hbrBack;
@ -470,6 +490,16 @@ IntSetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi)
{ {
/* FIXME */ /* FIXME */
} }
if (sizeof(MENUINFO) < lpmi->cbSize)
{
MenuObject->MenuInfo.FocusedItem = lpmi->FocusedItem;
MenuObject->MenuInfo.Height = lpmi->Height;
MenuObject->MenuInfo.Width = lpmi->Width;
MenuObject->MenuInfo.Wnd = lpmi->Wnd;
MenuObject->MenuInfo.WndOwner = lpmi->WndOwner;
MenuObject->MenuInfo.TimeToHide = lpmi->TimeToHide;
}
return TRUE; return TRUE;
} }
@ -582,20 +612,18 @@ IntInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
MenuItem->Next = NULL; MenuItem->Next = NULL;
} }
} }
MenuObject->MenuItemCount++; MenuObject->MenuInfo.MenuItemCount++;
return npos; return npos;
} }
BOOL FASTCALL BOOL FASTCALL
IntGetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPMENUITEMINFOW lpmii) IntGetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii)
{ {
if(!MenuItem || !MenuObject || !lpmii) UNICODE_STRING Text;
{ NTSTATUS Status;
return FALSE;
}
lpmii->cch = MenuItem->Text.Length; lpmii->cch = MenuItem->Text.Length / sizeof(WCHAR);
if(lpmii->fMask & MIIM_BITMAP) if(lpmii->fMask & MIIM_BITMAP)
{ {
@ -626,12 +654,44 @@ IntGetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPMENUITEMINFOW
{ {
lpmii->hSubMenu = MenuItem->hSubMenu; lpmii->hSubMenu = MenuItem->hSubMenu;
} }
if (0 != (lpmii->fMask & MIIM_STRING) ||
0 != (lpmii->fMask & MIIM_TYPE))
{
Status = MmCopyFromCaller(&Text, lpmii->dwTypeData, sizeof(UNICODE_STRING));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
Text.Length = min(Text.MaximumLength, MenuItem->Text.Length);
if (0 != Text.Length)
{
Status = MmCopyToCaller(Text.Buffer, MenuItem->Text.Buffer, Text.Length);
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
}
Status = MmCopyToCaller(lpmii->dwTypeData, &Text, sizeof(UNICODE_STRING));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
}
if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize)
{
lpmii->Rect = MenuItem->Rect;
lpmii->XTab = MenuItem->XTab;
}
return TRUE; return TRUE;
} }
BOOL FASTCALL BOOL FASTCALL
IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFOW lpmii) IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii)
{ {
PUNICODE_STRING Source; PUNICODE_STRING Source;
UINT copylen = 0; UINT copylen = 0;
@ -711,19 +771,24 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFO
RtlInitUnicodeString(&MenuItem->Text, NULL); RtlInitUnicodeString(&MenuItem->Text, NULL);
} }
if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize)
{
MenuItem->Rect = lpmii->Rect;
MenuItem->XTab = lpmii->XTab;
}
return TRUE; return TRUE;
} }
BOOL FASTCALL static BOOL FASTCALL
IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition, IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
LPCMENUITEMINFOW lpmii) PROSMENUITEMINFO ItemInfo)
{ {
int pos = (int)uItem; int pos = (int)uItem;
PMENU_ITEM MenuItem; PMENU_ITEM MenuItem;
if(MenuObject->MenuItemCount >= MAX_MENU_ITEMS) if (MAX_MENU_ITEMS <= MenuObject->MenuInfo.MenuItemCount)
{ {
/* FIXME Set last error code? */
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; return FALSE;
} }
@ -731,19 +796,23 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
if (fByPosition) if (fByPosition)
{ {
/* calculate position */ /* calculate position */
if(pos > MenuObject->MenuItemCount) if(MenuObject->MenuInfo.MenuItemCount < pos)
pos = MenuObject->MenuItemCount; {
pos = MenuObject->MenuInfo.MenuItemCount;
}
} }
else else
{ {
pos = IntGetMenuItemByFlag(MenuObject, uItem, MF_BYCOMMAND, NULL, NULL); pos = IntGetMenuItemByFlag(MenuObject, uItem, MF_BYCOMMAND, NULL, NULL);
} }
if(pos < -1) pos = -1; if (pos < -1)
{
pos = -1;
}
MenuItem = ExAllocatePool(PagedPool, sizeof(MENU_ITEM)); MenuItem = ExAllocatePool(PagedPool, sizeof(MENU_ITEM));
if(!MenuItem) if (NULL == MenuItem)
{ {
/* FIXME Set last error code? */
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; return FALSE;
} }
@ -758,7 +827,7 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
RtlInitUnicodeString(&MenuItem->Text, NULL); RtlInitUnicodeString(&MenuItem->Text, NULL);
MenuItem->hbmpItem = (HBITMAP)0; MenuItem->hbmpItem = (HBITMAP)0;
if(!IntSetMenuItemInfo(MenuObject, MenuItem, lpmii)) if (! IntSetMenuItemInfo(MenuObject, MenuItem, ItemInfo))
{ {
ExFreePool(MenuItem); ExFreePool(MenuItem);
return FALSE; return FALSE;
@ -1054,7 +1123,7 @@ IntInitTracking(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject, BOOL Popup
/* FIXME - send WM_SETCURSOR message */ /* FIXME - send WM_SETCURSOR message */
if(!(Flags & TPM_NONOTIFY)) if(!(Flags & TPM_NONOTIFY))
IntSendMessage(WindowObject->Self, WM_INITMENU, (WPARAM)MenuObject->Self, 0); IntSendMessage(WindowObject->Self, WM_INITMENU, (WPARAM)MenuObject->MenuInfo.Self, 0);
} }
VOID FASTCALL VOID FASTCALL
@ -1164,7 +1233,7 @@ NtUserBuildMenuItemList(
} }
else else
{ {
res = MenuObject->MenuItemCount; res = MenuObject->MenuInfo.MenuItemCount;
} }
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
@ -1313,21 +1382,40 @@ NtUserInsertMenuItem(
HMENU hMenu, HMENU hMenu,
UINT uItem, UINT uItem,
BOOL fByPosition, BOOL fByPosition,
LPCMENUITEMINFOW lpmii) LPCMENUITEMINFOW UnsafeItemInfo)
{ {
DWORD res = 0; DWORD Res = 0;
PMENU_OBJECT MenuObject; PMENU_OBJECT MenuObject;
NTSTATUS Status;
ROSMENUITEMINFO ItemInfo;
MenuObject = IntGetMenuObject(hMenu); MenuObject = IntGetMenuObject(hMenu);
if(!MenuObject) if(!MenuObject)
{ {
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return 0; return 0;
} }
Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, sizeof(MENUITEMINFOW));
if (! NT_SUCCESS(Status))
{
IntReleaseMenuObject(MenuObject);
SetLastNtError(Status);
return FALSE;
}
if (ItemInfo.cbSize != sizeof(MENUITEMINFOW))
{
IntReleaseMenuObject(MenuObject);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock); ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
res = IntInsertMenuItem(MenuObject, uItem, fByPosition, lpmii); Res = IntInsertMenuItem(MenuObject, uItem, fByPosition, &ItemInfo);
ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock); ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
return res;
return Res;
} }
@ -1458,36 +1546,64 @@ NtUserHiliteMenuItem(
BOOL BOOL
STDCALL STDCALL
NtUserMenuInfo( NtUserMenuInfo(
HMENU hmenu, HMENU Menu,
LPMENUINFO lpmi, PROSMENUINFO UnsafeMenuInfo,
BOOL fsog) BOOL SetOrGet)
{ {
BOOL res = FALSE; BOOL Res;
PMENU_OBJECT MenuObject; PMENU_OBJECT MenuObject;
DWORD Size;
NTSTATUS Status;
ROSMENUINFO MenuInfo;
if(lpmi->cbSize != sizeof(MENUINFO)) Status = MmCopyFromCaller(&Size, &UnsafeMenuInfo->cbSize, sizeof(DWORD));
if (! NT_SUCCESS(Status))
{ {
/* FIXME - Set Last Error */ SetLastNtError(Status);
return FALSE; return FALSE;
} }
MenuObject = IntGetMenuObject(hmenu); if(Size < sizeof(MENUINFO) || sizeof(ROSMENUINFO) < Size)
if(!MenuObject) {
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
Status = MmCopyFromCaller(&MenuInfo, UnsafeMenuInfo, Size);
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
MenuObject = IntGetMenuObject(Menu);
if (NULL == MenuObject)
{ {
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return FALSE; return FALSE;
} }
if(fsog)
if(SetOrGet)
{ {
/* Set MenuInfo */ /* Set MenuInfo */
res = IntSetMenuInfo(MenuObject, lpmi); Res = IntSetMenuInfo(MenuObject, &MenuInfo);
} }
else else
{ {
/* Get MenuInfo */ /* Get MenuInfo */
res = IntGetMenuInfo(MenuObject, lpmi); Res = IntGetMenuInfo(MenuObject, &MenuInfo);
if (Res)
{
Status = MmCopyToCaller(UnsafeMenuInfo, &MenuInfo, Size);
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
} }
}
}
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
return res;
return Res;
} }
@ -1496,35 +1612,38 @@ NtUserMenuInfo(
*/ */
int STDCALL int STDCALL
NtUserMenuItemFromPoint( NtUserMenuItemFromPoint(
HWND hWnd, HWND Wnd,
HMENU hMenu, HMENU Menu,
DWORD X, DWORD X,
DWORD Y) DWORD Y)
{ {
PMENU_OBJECT MenuObject; PMENU_OBJECT MenuObject;
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT WindowObject = NULL;
PMENU_ITEM mi; PMENU_ITEM mi;
int i; int i;
MenuObject = IntGetMenuObject(hMenu); MenuObject = IntGetMenuObject(Menu);
if(!MenuObject) if (NULL == MenuObject)
{ {
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return -1; return -1;
} }
if(hWnd) if (0 != (MenuObject->MenuInfo.Flags & MF_POPUP))
{ {
WindowObject = IntGetWindowObject(hWnd); WindowObject = IntGetWindowObject(MenuObject->MenuInfo.Wnd);
if(!WindowObject) if (NULL == WindowObject)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return -1; return -1;
} }
X -= WindowObject->WindowRect.left;
Y -= WindowObject->WindowRect.top;
IntReleaseWindowObject(WindowObject);
} }
ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock); ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
mi = MenuObject->MenuItemList; mi = MenuObject->MenuItemList;
for(i = 0; mi; i++) for (i = 0; NULL != mi; i++)
{ {
if (InRect(mi->Rect, X, Y)) if (InRect(mi->Rect, X, Y))
{ {
@ -1536,10 +1655,7 @@ NtUserMenuItemFromPoint(
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
if(hWnd) return (mi ? i : NO_SELECTED_ITEM);
IntReleaseWindowObject(WindowObject);
return (mi ? i : -1);
} }
@ -1549,35 +1665,38 @@ NtUserMenuItemFromPoint(
BOOL BOOL
STDCALL STDCALL
NtUserMenuItemInfo( NtUserMenuItemInfo(
HMENU hMenu, HMENU Menu,
UINT uItem, UINT Item,
BOOL fByPosition, BOOL ByPosition,
LPMENUITEMINFOW lpmii, PROSMENUITEMINFO UnsafeItemInfo,
BOOL fsog) BOOL SetOrGet)
{ {
PMENU_OBJECT MenuObject; PMENU_OBJECT MenuObject;
PMENU_ITEM MenuItem; PMENU_ITEM MenuItem;
MENUITEMINFOW Safemii; ROSMENUITEMINFO ItemInfo;
NTSTATUS Status; NTSTATUS Status;
UINT Size;
BOOL Ret;
MenuObject = IntGetMenuObject(hMenu); MenuObject = IntGetMenuObject(Menu);
if(!MenuObject) if (NULL == MenuObject)
{ {
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return FALSE; return FALSE;
} }
Status = MmCopyFromCaller(&Size, &UnsafeItemInfo->cbSize, sizeof(UINT));
if(fsog) if (! NT_SUCCESS(Status))
{ {
/* Set menu item info */ IntReleaseMenuObject(MenuObject);
SetLastNtError(Status);
return FALSE;
} }
else if(sizeof(MENUITEMINFOW) != Size && sizeof(ROSMENUITEMINFO) != Size)
{ {
if((IntGetMenuItemByFlag(MenuObject, uItem, (fByPosition ? MF_BYPOSITION : MF_BYCOMMAND), SetLastWin32Error(ERROR_INVALID_PARAMETER);
&MenuItem, NULL) > -1) && return FALSE;
IntGetMenuItemInfo(MenuObject, MenuItem, &Safemii)) }
{ Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, Size);
Status = MmCopyToCaller(lpmii, &Safemii, sizeof(MENUITEMINFOW));
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
@ -1585,13 +1704,37 @@ NtUserMenuItemInfo(
return FALSE; return FALSE;
} }
if (IntGetMenuItemByFlag(MenuObject, Item,
(ByPosition ? MF_BYPOSITION : MF_BYCOMMAND),
&MenuItem, NULL) < 0)
{
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
return TRUE; SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (SetOrGet)
{
Ret = IntSetMenuItemInfo(MenuObject, MenuItem, &ItemInfo);
}
else
{
Ret = IntGetMenuItemInfo(MenuObject, MenuItem, &ItemInfo);
if (Ret)
{
Status = MmCopyToCaller(UnsafeItemInfo, &ItemInfo, Size);
if (! NT_SUCCESS(Status))
{
IntReleaseMenuObject(MenuObject);
SetLastNtError(Status);
return FALSE;
}
} }
} }
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
return FALSE;
return Ret;
} }

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.48 2004/01/31 14:57:58 rcampbell Exp $ /* $Id: misc.c,v 1.49 2004/02/15 07:39:12 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -205,11 +205,11 @@ NtUserCallTwoParam(
if(Param2 > 0) if(Param2 > 0)
{ {
Ret = (MenuObject->Height == (int)Param2); Ret = (MenuObject->MenuInfo.Height == (int)Param2);
MenuObject->Height = (int)Param2; MenuObject->MenuInfo.Height = (int)Param2;
} }
else else
Ret = (DWORD)MenuObject->Height; Ret = (DWORD)MenuObject->MenuInfo.Height;
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
return Ret; return Ret;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: window.c,v 1.182 2004/02/08 10:53:17 navaraf Exp $ /* $Id: window.c,v 1.183 2004/02/15 07:39:12 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -432,6 +432,70 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
return 0; return 0;
} }
static BOOL FASTCALL
IntSetMenu(
PWINDOW_OBJECT WindowObject,
HMENU Menu,
BOOL *Changed)
{
PMENU_OBJECT OldMenuObject, NewMenuObject;
*Changed = (WindowObject->IDMenu != (UINT) Menu);
if (! *Changed)
{
return TRUE;
}
if (0 != WindowObject->IDMenu)
{
OldMenuObject = IntGetMenuObject((HMENU) WindowObject->IDMenu);
ASSERT(NULL == OldMenuObject || OldMenuObject->MenuInfo.Wnd == WindowObject->Self);
}
else
{
OldMenuObject = NULL;
}
if (NULL != Menu)
{
NewMenuObject = IntGetMenuObject(Menu);
if (NULL == NewMenuObject)
{
if (NULL != OldMenuObject)
{
IntReleaseMenuObject(OldMenuObject);
}
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return FALSE;
}
if (NULL != NewMenuObject->MenuInfo.Wnd)
{
/* Can't use the same menu for two windows */
if (NULL != OldMenuObject)
{
IntReleaseMenuObject(OldMenuObject);
}
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return FALSE;
}
}
WindowObject->IDMenu = (UINT) Menu;
if (NULL != NewMenuObject)
{
NewMenuObject->MenuInfo.Wnd = WindowObject->Self;
IntReleaseMenuObject(NewMenuObject);
}
if (NULL != OldMenuObject)
{
OldMenuObject->MenuInfo.Wnd = NULL;
IntReleaseMenuObject(OldMenuObject);
}
return TRUE;
}
/* INTERNAL ******************************************************************/ /* INTERNAL ******************************************************************/
@ -557,8 +621,8 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
NewMenuObject = IntCloneMenu(MenuObject); NewMenuObject = IntCloneMenu(MenuObject);
if(NewMenuObject) if(NewMenuObject)
{ {
WindowObject->SystemMenu = NewMenuObject->Self; WindowObject->SystemMenu = NewMenuObject->MenuInfo.Self;
NewMenuObject->IsSystemMenu = TRUE; NewMenuObject->MenuInfo.Flags |= MF_SYSMENU;
ret = NewMenuObject; ret = NewMenuObject;
//IntReleaseMenuObject(NewMenuObject); //IntReleaseMenuObject(NewMenuObject);
} }
@ -576,8 +640,8 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
NewMenuObject = IntCloneMenu(MenuObject); NewMenuObject = IntCloneMenu(MenuObject);
if(NewMenuObject) if(NewMenuObject)
{ {
WindowObject->SystemMenu = NewMenuObject->Self; WindowObject->SystemMenu = NewMenuObject->MenuInfo.Self;
NewMenuObject->IsSystemMenu = TRUE; NewMenuObject->MenuInfo.Flags |= MF_SYSMENU;
ret = NewMenuObject; ret = NewMenuObject;
//IntReleaseMenuObject(NewMenuObject); //IntReleaseMenuObject(NewMenuObject);
} }
@ -726,6 +790,7 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
PWINDOW_OBJECT WndOldParent; PWINDOW_OBJECT WndOldParent;
HWND hWnd, hWndNewParent, hWndOldParent; HWND hWnd, hWndNewParent, hWndOldParent;
BOOL WasVisible; BOOL WasVisible;
BOOL MenuChanged;
hWnd = Wnd->Self; hWnd = Wnd->Self;
hWndNewParent = WndNewParent->Self; hWndNewParent = WndNewParent->Self;
@ -757,7 +822,7 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
if (!(Wnd->Style & WS_CHILD)) if (!(Wnd->Style & WS_CHILD))
{ {
//if ( Wnd->Menu ) DestroyMenu ( Wnd->menu ); //if ( Wnd->Menu ) DestroyMenu ( Wnd->menu );
Wnd->IDMenu = 0; IntSetMenu(Wnd, NULL, &MenuChanged);
} }
} }
} }
@ -791,7 +856,7 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
OldMenuObject = IntGetMenuObject(WindowObject->SystemMenu); OldMenuObject = IntGetMenuObject(WindowObject->SystemMenu);
if(OldMenuObject) if(OldMenuObject)
{ {
OldMenuObject->IsSystemMenu = FALSE; OldMenuObject->MenuInfo.Flags &= ~ MF_SYSMENU;
IntReleaseMenuObject(OldMenuObject); IntReleaseMenuObject(OldMenuObject);
} }
} }
@ -799,8 +864,8 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
if(MenuObject) if(MenuObject)
{ {
/* FIXME check window style, propably return FALSE ? */ /* FIXME check window style, propably return FALSE ? */
WindowObject->SystemMenu = MenuObject->Self; WindowObject->SystemMenu = MenuObject->MenuInfo.Self;
MenuObject->IsSystemMenu = TRUE; MenuObject->MenuInfo.Flags |= MF_SYSMENU;
} }
else else
WindowObject->SystemMenu = (HMENU)0; WindowObject->SystemMenu = (HMENU)0;
@ -1096,6 +1161,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
CREATESTRUCTW Cs; CREATESTRUCTW Cs;
CBT_CREATEWNDW CbtCreate; CBT_CREATEWNDW CbtCreate;
LRESULT Result; LRESULT Result;
BOOL MenuChanged;
DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
@ -1211,9 +1277,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->SystemMenu = (HMENU)0; WindowObject->SystemMenu = (HMENU)0;
WindowObject->ContextHelpId = 0; WindowObject->ContextHelpId = 0;
WindowObject->IDMenu = (UINT)hMenu; WindowObject->IDMenu = 0;
WindowObject->Instance = hInstance; WindowObject->Instance = hInstance;
WindowObject->Self = Handle; WindowObject->Self = Handle;
IntSetMenu(WindowObject, hMenu, &MenuChanged);
WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue; WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
WindowObject->Parent = ParentWindow; WindowObject->Parent = ParentWindow;
WindowObject->Owner = IntGetWindowObject(OwnerWindowHandle); WindowObject->Owner = IntGetWindowObject(OwnerWindowHandle);
@ -1275,7 +1342,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE); SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE);
if(SystemMenu) if(SystemMenu)
{ {
WindowObject->SystemMenu = SystemMenu->Self; WindowObject->SystemMenu = SystemMenu->MenuInfo.Self;
IntReleaseMenuObject(SystemMenu); IntReleaseMenuObject(SystemMenu);
} }
} }
@ -3038,49 +3105,31 @@ NtUserSetLogonNotifyWindow(DWORD Unknown0)
*/ */
BOOL STDCALL BOOL STDCALL
NtUserSetMenu( NtUserSetMenu(
HWND hWnd, HWND Wnd,
HMENU hMenu, HMENU Menu,
BOOL bRepaint) BOOL Repaint)
{ {
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT WindowObject;
PMENU_OBJECT MenuObject; BOOL Changed;
BOOL Changed = FALSE;
WindowObject = IntGetWindowObject((HWND)hWnd); WindowObject = IntGetWindowObject((HWND) Wnd);
if (!WindowObject) if (NULL == WindowObject)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;
} }
if (hMenu) if (! IntSetMenu(WindowObject, Menu, &Changed))
{
/* assign new menu handle */
MenuObject = IntGetMenuObject((HWND)hMenu);
if (!MenuObject)
{ {
IntReleaseWindowObject(WindowObject); IntReleaseWindowObject(WindowObject);
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return FALSE; return FALSE;
} }
Changed = (WindowObject->IDMenu != (UINT)hMenu);
WindowObject->IDMenu = (UINT)hMenu;
IntReleaseMenuObject(MenuObject);
}
else
{
/* remove the menu handle */
Changed = (WindowObject->IDMenu != 0);
WindowObject->IDMenu = 0;
}
IntReleaseWindowObject(WindowObject); IntReleaseWindowObject(WindowObject);
if (Changed && bRepaint) if (Changed && Repaint)
{ {
WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
} }