implemented multiline menu bars

svn path=/trunk/; revision=7883
This commit is contained in:
Thomas Bluemel 2004-01-26 23:22:48 +00:00
parent 83adec498a
commit 53623ae9dc
5 changed files with 114 additions and 67 deletions

View file

@ -12,8 +12,6 @@ UINT
MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw); MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw);
BOOL BOOL
MenuInit(VOID); MenuInit(VOID);
ULONG
MenuGetMenuBarHeight(HWND hWnd, ULONG MenuBarWidth, LONG OrgX, LONG OrgY);
VOID VOID
MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt); MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt);
VOID VOID

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.44 2004/01/26 12:46:16 weiden Exp $ /* $Id: menu.c,v 1.45 2004/01/26 23:22:48 weiden Exp $
* *
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c * FILE: lib/user32/windows/menu.c
@ -274,29 +274,6 @@ MenuInit(VOID)
} }
ULONG
MenuGetMenuBarHeight(HWND hWnd, ULONG MenuBarWidth, LONG OrgX, LONG OrgY)
{
/*ULONG MenuId;
PPOPUP_MENU Menu;
RECT Rect;
HDC hDC;
MenuId = GetWindowLong(hWnd, GWL_ID);
Menu = MenuGetMenu((HMENU)MenuId);
if (Menu == NULL)
{
return(0);
}
hDC = GetDCEx(hWnd, 0, DCX_CACHE | DCX_WINDOW);
SelectObject(hDC, hMenuFont);
SetRect(&Rect, OrgX, OrgY, OrgX + MenuBarWidth,
OrgY + GetSystemMetrics(SM_CYMENU));
MenuMenuBarCalcSize(hDC, &Rect, Menu, hWnd);
ReleaseDC(hWnd, hDC);*/
return(GetSystemMetrics(SM_CYMENU));
}
static BOOL static BOOL
MeasureMenuItem(HWND hWnd, HMENU mnu, HDC hDC, MENUITEMINFOW *mii, RECT *mir, LPWSTR str) MeasureMenuItem(HWND hWnd, HMENU mnu, HDC hDC, MENUITEMINFOW *mii, RECT *mir, LPWSTR str)
{ {
@ -372,7 +349,7 @@ DrawMenuItem(HWND hWnd, HMENU mnu, HDC hDC, MENUITEMINFOW *mii, RECT *mir, LPWST
UINT UINT
MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw) MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw)
{ {
UINT height; UINT bottom, line;
HMENU mnu; HMENU mnu;
HANDLE hHeap; HANDLE hHeap;
PVOID Buf, hBuf; PVOID Buf, hBuf;
@ -382,25 +359,22 @@ MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw)
RECT *omir, *mir = NULL; RECT *omir, *mir = NULL;
LPWSTR str; LPWSTR str;
FillRect(hDC, Rect, GetSysColorBrush(COLOR_MENU));
height = Rect->bottom - Rect->top;
mnu = GetMenu(hWnd); /* Fixme - pass menu handle as parameter */ mnu = GetMenu(hWnd); /* Fixme - pass menu handle as parameter */
/* get menu item list size */ /* get menu item list size */
BufSize = NtUserBuildMenuItemList(mnu, (VOID*)1, 0, 0); BufSize = NtUserBuildMenuItemList(mnu, (VOID*)1, 0, 0);
if(BufSize) if(BufSize)
{ {
/* FIXME cache menu bar items using NtUserDrawMenuBarTemp()
instead of allocating and deallocating memory everytime */
hHeap = GetProcessHeap(); hHeap = GetProcessHeap();
hBuf = HeapAlloc(hHeap, 0, BufSize); hBuf = HeapAlloc(hHeap, 0, BufSize);
if(!hBuf) if(!hBuf)
return(Rect->bottom - Rect->top); return 0;
Buf = hBuf; Buf = hBuf;
/* copy menu items into buffer */ /* copy menu items into buffer */
Items = Items2 = NtUserBuildMenuItemList(mnu, Buf, BufSize, 0); Items = Items2 = NtUserBuildMenuItemList(mnu, Buf, BufSize, 0);
if(!Draw)
{
bottom = line = Rect->top;
smir.fByPosition = TRUE; smir.fByPosition = TRUE;
smir.uItem = 0; smir.uItem = 0;
/* calculate menu item rectangles */ /* calculate menu item rectangles */
@ -431,16 +405,38 @@ MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw)
mir->top = Rect->top; mir->top = Rect->top;
} }
MeasureMenuItem(hWnd, mnu, hDC, mii, mir, str); MeasureMenuItem(hWnd, mnu, hDC, mii, mir, str);
if(mir->right > Rect->right)
{
mir->right -= (mir->left - Rect->left);
mir->left = Rect->left;
mir->top += line;
mir->bottom += line;
line = mir->bottom - mir->top;
}
smir.rcRect = *mir; smir.rcRect = *mir;
NtUserSetMenuItemRect(mnu, &smir); NtUserSetMenuItemRect(mnu, &smir);
height = max(height, mir->top + mir->bottom); bottom = max(bottom, mir->bottom);
line = max(line, mir->bottom - mir->top);
/* DbgPrint("Measure menu item %ws: (%d, %d, %d, %d)\n", str, mir->left, mir->top, mir->right, mir->bottom); */ /* DbgPrint("Measure menu item %ws: (%d, %d, %d, %d)\n", str, mir->left, mir->top, mir->right, mir->bottom); */
Items--; Items--;
smir.uItem++; smir.uItem++;
} }
height = max(height, GetSystemMetrics(SM_CYMENU)); bottom = max(bottom, Rect->top + GetSystemMetrics(SM_CYMENU));
if(bottom - Rect->top > 0)
{
if(NtUserSetMenuBarHeight(mnu, bottom - Rect->top) && Draw)
{
/* FIXME - update frame */
}
}
}
else
{
bottom = Rect->bottom;
FillRect(hDC, Rect, GetSysColorBrush(COLOR_MENU));
Buf = hBuf; Buf = hBuf;
/* draw menu items */ /* draw menu items */
while (Items2 > 0) while (Items2 > 0)
@ -460,22 +456,23 @@ MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw)
DrawMenuItem(hWnd, mnu, hDC, mii, mir, str); DrawMenuItem(hWnd, mnu, hDC, mii, mir, str);
Items2--; Items2--;
} }
}
HeapFree(hHeap, 0, hBuf); HeapFree(hHeap, 0, hBuf);
} }
return height; return max(bottom - Rect->top, GetSystemMetrics(SM_CYMENU));
} }
VOID VOID
MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt) MenuTrackMouseMenuBar(HWND hWnd, ULONG Ht, POINT Pt)
{DbgPrint("MenuTrackMouseMenuBar at %i, %i\n", Pt.x, Pt.y); {
int Item = NtUserMenuItemFromPoint(hWnd, GetMenu(hWnd), Pt.x, Pt.y); int Item = NtUserMenuItemFromPoint(hWnd, GetMenu(hWnd), Pt.x, Pt.y);
if(Item > -1) if(Item > -1)
{ {
/* FIXME */
} }
} }

View file

@ -420,12 +420,13 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn)
if(!(Style & WS_MINIMIZE)) if(!(Style & WS_MINIMIZE))
{ {
HMENU menu = GetMenu(hWnd);
/* Draw menu bar */ /* Draw menu bar */
if (UserHasMenu(hWnd, Style)) if (menu && !(Style & WS_CHILD))
{ {
TempRect = CurrentRect; TempRect = CurrentRect;
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYMENU); TempRect.bottom = TempRect.top + (UINT)NtUserSetMenuBarHeight(menu, 0);
CurrentRect.top += MenuDrawMenuBar(hDC, &TempRect, hWnd, FALSE); CurrentRect.top += MenuDrawMenuBar(hDC, &TempRect, hWnd, TRUE);
} }
if (ExStyle & WS_EX_CLIENTEDGE) if (ExStyle & WS_EX_CLIENTEDGE)
@ -477,6 +478,7 @@ DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect)
DWORD Style = GetClassLongW(hWnd, GCL_STYLE); DWORD Style = GetClassLongW(hWnd, GCL_STYLE);
DWORD ExStyle; DWORD ExStyle;
SIZE WindowBorders; SIZE WindowBorders;
RECT OrigRect = *Rect;
if (CalcSizeStruct) if (CalcSizeStruct)
{ {
@ -496,6 +498,9 @@ DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect)
if (!(Style & WS_MINIMIZE)) if (!(Style & WS_MINIMIZE))
{ {
ULONG menuheight;
HMENU menu = GetMenu(hWnd);
UserGetWindowBorders(Style, ExStyle, &WindowBorders, FALSE); UserGetWindowBorders(Style, ExStyle, &WindowBorders, FALSE);
InflateRect(Rect, -WindowBorders.cx, -WindowBorders.cy); InflateRect(Rect, -WindowBorders.cx, -WindowBorders.cy);
if ((Style & WS_CAPTION) == WS_CAPTION) if ((Style & WS_CAPTION) == WS_CAPTION)
@ -506,8 +511,21 @@ DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect)
Rect->top += GetSystemMetrics(SM_CYCAPTION); Rect->top += GetSystemMetrics(SM_CYCAPTION);
} }
if (UserHasMenu(hWnd, Style)) if (menu && !(Style & WS_CHILD))
Rect->top += MenuGetMenuBarHeight(hWnd, Rect->right - Rect->left, Rect->left, Rect->top); {
HDC hDC = GetWindowDC(hWnd);
if(hDC)
{
RECT CliRect = *Rect;
CliRect.bottom -= OrigRect.top;
CliRect.right -= OrigRect.left;
CliRect.left -= OrigRect.left;
CliRect.top -= OrigRect.top;
menuheight = (ULONG)MenuDrawMenuBar(hDC, &CliRect, hWnd, FALSE);
ReleaseDC(hWnd, hDC);
Rect->top += max(menuheight, GetSystemMetrics(SM_CYMENU));
}
}
if (ExStyle & WS_EX_CLIENTEDGE) if (ExStyle & WS_EX_CLIENTEDGE)
{ {

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.42 2004/01/26 12:46:16 weiden Exp $ /* $Id: menu.c,v 1.43 2004/01/26 23:22:48 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1042,16 +1042,45 @@ IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags,
return res; return res;
} }
VOID FASTCALL
IntInitTracking(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject, BOOL Popup,
UINT Flags)
{
/* FIXME - hide caret */
if(!(Flags & TPM_NONOTIFY))
IntSendMessage(WindowObject->Self, WM_SETCURSOR, (WPARAM)WindowObject->Self, HTCAPTION);
/* FIXME - send WM_SETCURSOR message */
if(!(Flags & TPM_NONOTIFY))
IntSendMessage(WindowObject->Self, WM_INITMENU, (WPARAM)MenuObject->Self, 0);
}
VOID FASTCALL
IntExitTracking(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject, BOOL Popup,
UINT Flags)
{
if(!(Flags & TPM_NONOTIFY))
IntSendMessage(WindowObject->Self, WM_EXITMENULOOP, 0 /* FIXME */, 0);
/* FIXME - Show caret again */
}
INT FASTCALL
IntTrackMenu(PMENU_OBJECT MenuObject, PWINDOW_OBJECT WindowObject, INT x, INT y,
RECT lprect)
{
return 0;
}
BOOL FASTCALL BOOL FASTCALL
IntTrackPopupMenu(PMENU_OBJECT MenuObject, PWINDOW_OBJECT WindowObject, IntTrackPopupMenu(PMENU_OBJECT MenuObject, PWINDOW_OBJECT WindowObject,
UINT Flags, POINT *Pos, UINT MenuPos, RECT *ExcludeRect) UINT Flags, POINT *Pos, UINT MenuPos, RECT *ExcludeRect)
{ {
IntInitTracking(WindowObject, MenuObject, TRUE, Flags);
/* FIXME */ IntExitTracking(WindowObject, MenuObject, TRUE, Flags);
DbgPrint("IntTrackPopupMenu: unimplemented\n");
SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.45 2004/01/26 12:46:16 weiden Exp $ /* $Id: misc.c,v 1.46 2004/01/26 23:22:48 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -202,8 +202,13 @@ NtUserCallTwoParam(
PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1); PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
if(!MenuObject) if(!MenuObject)
return 0; return 0;
if(Param2 > 0) if(Param2 > 0)
{
Ret = (MenuObject->Height == (int)Param2);
MenuObject->Height = (int)Param2; MenuObject->Height = (int)Param2;
}
else
Ret = (DWORD)MenuObject->Height; Ret = (DWORD)MenuObject->Height;
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
return Ret; return Ret;