ChangeSet ID: 19007 CVSROOT: /opt/cvs-commit Module name: wine Changes by: julliard@wine.codeweavers.com 2005/07/19 06:51:31 Modified files: dlls/user : win.c user_main.c menu.c controls.h Log message: Initialize the various menu global variables on demand instead of at startup time. Patch: http://cvs.winehq.org/patch.py?id=19007 Old revision New revision Changes Path 1.15 1.16 +3 -1 wine/dlls/user/win.c 1.91 1.92 +0 -3 wine/dlls/user/user_main.c 1.33 1.34 +94 -112 wine/dlls/user/menu.c 1.24 1.25 +0 -2 wine/dlls/user/controls.h Index: wine/dlls/user/win.c diff -u -p wine/dlls/user/win.c:1.15 wine/dlls/user/win.c:1.16 --- wine/dlls/user/win.c:1.15 Tue May 21 21:26:41 2013 +++ wine/dlls/user/win.c Tue May 21 21:26:41 2013 @@ -976,7 +976,9 @@ static HWND WIN_CreateWindowEx( CREATEST wndPtr->userdata = 0; wndPtr->hIcon = 0; wndPtr->hIconSmall = 0; - wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, (HMENU)-1 ) : 0; + wndPtr->hSysMenu = 0; + + if (wndPtr->dwStyle & WS_SYSMENU) SetSystemMenu( hwnd, 0 ); /* * Correct the window styles. Index: wine/dlls/user/user_main.c diff -u -p wine/dlls/user/user_main.c:1.91 wine/dlls/user/user_main.c:1.92 --- wine/dlls/user/user_main.c:1.91 Tue May 21 21:26:41 2013 +++ wine/dlls/user/user_main.c Tue May 21 21:26:41 2013 @@ -179,9 +179,6 @@ static BOOL process_attach(void) /* Initialize built-in window classes */ CLASS_RegisterBuiltinClasses(); - /* Initialize menus */ - if (!MENU_Init()) return FALSE; - /* Initialize message spying */ if (!SPY_Init()) return FALSE; Index: wine/dlls/user/menu.c diff -u -p wine/dlls/user/menu.c:1.33 wine/dlls/user/menu.c:1.34 --- wine/dlls/user/menu.c:1.33 Tue May 21 21:26:41 2013 +++ wine/dlls/user/menu.c Tue May 21 21:26:41 2013 @@ -162,19 +162,9 @@ typedef struct #define WIN_ALLOWED_MENU(style) ((style & (WS_CHILD | WS_POPUP)) != WS_CHILD) - /* Dimension of the menu bitmaps */ -static WORD arrow_bitmap_width = 0, arrow_bitmap_height = 0; - -static HBITMAP hStdMnArrow = 0; -static HBITMAP hBmpSysMenu = 0; - -static HFONT hMenuFont = 0; -static HFONT hMenuFontBold = 0; static SIZE menucharsize; static UINT ODitemheight; /* default owner drawn item height */ -static HMENU MENU_DefSysPopup = 0; /* Default system menu popup */ - /* Use global popup window because there's no way 2 menus can * be tracked at the same time. */ static HWND top_popup; @@ -330,6 +320,52 @@ static HMENU get_win_sys_menu( HWND hwnd } /*********************************************************************** + * get_menu_font + */ +static HFONT get_menu_font( BOOL bold ) +{ + static HFONT hMenuFont, hMenuFontBold; + + HFONT ret = bold ? hMenuFontBold : hMenuFont; + + if (!ret) + { + NONCLIENTMETRICSW ncm; + HFONT prev; + + ncm.cbSize = sizeof(NONCLIENTMETRICSW); + SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0); + + if (bold) + { + ncm.lfMenuFont.lfWeight += 300; + if (ncm.lfMenuFont.lfWeight > 1000) ncm.lfMenuFont.lfWeight = 1000; + } + if (!(ret = CreateFontIndirectW( &ncm.lfMenuFont ))) return 0; + prev = InterlockedCompareExchangePointer( (void **)(bold ? &hMenuFontBold : &hMenuFont), + ret, NULL ); + if (prev) + { + /* another thread beat us to it */ + DeleteObject( ret ); + ret = prev; + } + } + return ret; +} + +/*********************************************************************** + * get_arrow_bitmap + */ +static HBITMAP get_arrow_bitmap(void) +{ + static HBITMAP arrow_bitmap; + + if (!arrow_bitmap) arrow_bitmap = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_MNARROW)); + return arrow_bitmap; +} + +/*********************************************************************** * MENU_CopySysPopup * * Return the default system menu. @@ -374,9 +410,8 @@ HMENU MENU_GetSysMenu( HWND hWnd, HMENU menu->hWnd = WIN_GetFullHandle( hWnd ); TRACE("hWnd %p (hMenu %p)\n", menu->hWnd, hMenu); - if (hPopupMenu == (HMENU)(-1)) + if (!hPopupMenu) hPopupMenu = MENU_CopySysPopup(); - else if( !hPopupMenu ) hPopupMenu = MENU_DefSysPopup; if (hPopupMenu) { @@ -401,49 +436,6 @@ HMENU MENU_GetSysMenu( HWND hWnd, HMENU /*********************************************************************** - * MENU_Init - * - * Menus initialisation. - */ -BOOL MENU_Init(void) -{ - NONCLIENTMETRICSW ncm; - - /* Load menu bitmaps */ - hStdMnArrow = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_MNARROW)); - /* Load system buttons bitmaps */ - hBmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); - - if (hStdMnArrow) - { - BITMAP bm; - GetObjectW( hStdMnArrow, sizeof(bm), &bm ); - arrow_bitmap_width = bm.bmWidth; - arrow_bitmap_height = bm.bmHeight; - } else - return FALSE; - - if (!(MENU_DefSysPopup = MENU_CopySysPopup())) - return FALSE; - - ncm.cbSize = sizeof(NONCLIENTMETRICSW); - if (!(SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0))) - return FALSE; - - if (!(hMenuFont = CreateFontIndirectW( &ncm.lfMenuFont ))) - return FALSE; - - ncm.lfMenuFont.lfWeight += 300; - if ( ncm.lfMenuFont.lfWeight > 1000) - ncm.lfMenuFont.lfWeight = 1000; - - if (!(hMenuFontBold = CreateFontIndirectW( &ncm.lfMenuFont ))) - return FALSE; - - return TRUE; -} - -/*********************************************************************** * MENU_InitSysMenuPopup * * Grey the appropriate items in System menu. @@ -783,6 +775,9 @@ static void MENU_DrawBitmapItem( HDC hdc } else { + static HBITMAP hBmpSysMenu; + + if (!hBmpSysMenu) hBmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); bmp = hBmpSysMenu; if (!GetObjectW( bmp, sizeof(bm), &bm )) return; /* only use right half of the bitmap */ @@ -848,11 +843,16 @@ static void MENU_CalcItemSize( HDC hdc, { WCHAR *p; UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); + UINT arrow_bitmap_width; + BITMAP bm; TRACE("dc=%p owner=%p (%d,%d)\n", hdc, hwndOwner, orgX, orgY); debug_print_menuitem("MENU_CalcItemSize: menuitem:", lpitem, (menuBar ? " (MenuBar)" : "")); + GetObjectW( get_arrow_bitmap(), sizeof(bm), &bm ); + arrow_bitmap_width = bm.bmWidth; + SetRect( &lpitem->rect, orgX, orgY, orgX, orgY ); if (lpitem->fType & MF_OWNERDRAW) @@ -860,9 +860,7 @@ static void MENU_CalcItemSize( HDC hdc, MEASUREITEMSTRUCT mis; /* not done in Menu_Init: GetDialogBaseUnits() breaks there */ if( !menucharsize.cx ) { - HFONT hOldFont = SelectObject( hdc, hMenuFont ); menucharsize.cx = GdiGetCharDimensions( hdc, NULL, &menucharsize.cy ); - SelectObject( hdc, hOldFont ); /* Win95/98/ME will use menucharsize.cy here. Testing is possible * but it is unlikely an application will depend on that */ ODitemheight = HIWORD( GetDialogBaseUnits()); @@ -998,7 +996,7 @@ static void MENU_PopupMenuCalcSize( LPPO if (lppop->nItems == 0) return; hdc = GetDC( 0 ); - SelectObject( hdc, hMenuFont); + SelectObject( hdc, get_menu_font(FALSE)); start = 0; maxX = 2 + 1; @@ -1299,6 +1297,12 @@ static void MENU_DrawMenuItem( HWND hwnd INT y = rect.top + rect.bottom; UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK ); + UINT arrow_bitmap_width, arrow_bitmap_height; + BITMAP bmp; + + GetObjectW( get_arrow_bitmap(), sizeof(bmp), &bmp ); + arrow_bitmap_width = bmp.bmWidth; + arrow_bitmap_height = bmp.bmHeight; if (!(lpitem->fType & MF_OWNERDRAW)) { @@ -1383,7 +1387,7 @@ static void MENU_DrawMenuItem( HWND hwnd HDC hdcMem = CreateCompatibleDC( hdc ); HBITMAP hOrigBitmap; - hOrigBitmap = SelectObject( hdcMem, hStdMnArrow ); + hOrigBitmap = SelectObject( hdcMem, get_arrow_bitmap() ); BitBlt( hdc, rect.right - arrow_bitmap_width - 1, (y - arrow_bitmap_height) / 2, arrow_bitmap_width, arrow_bitmap_height, @@ -1418,7 +1422,7 @@ static void MENU_DrawMenuItem( HWND hwnd if ( lpitem->fState & MFS_DEFAULT ) { - hfontOld = SelectObject( hdc, hMenuFontBold); + hfontOld = SelectObject( hdc, get_menu_font(TRUE) ); } if (menuBar) @@ -1493,7 +1497,7 @@ static void MENU_DrawPopupMenu( HWND hwn GetClientRect( hwnd, &rect ); if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) )) - && (SelectObject( hdc, hMenuFont))) + && (SelectObject( hdc, get_menu_font(FALSE)))) { HPEN hPrevPen; @@ -1552,7 +1556,7 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT l if (suppress_draw) { - hfontOld = SelectObject( hDC, hMenuFont); + hfontOld = SelectObject( hDC, get_menu_font(FALSE)); if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd); @@ -1652,7 +1656,7 @@ static void MENU_SelectItem( HWND hwndOw else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW); if (!top_popup) top_popup = lppop->hWnd; - SelectObject( hdc, hMenuFont); + SelectObject( hdc, get_menu_font(FALSE)); /* Clear previous highlighted item */ if (lppop->FocusedItem != NO_SELECTED_ITEM) @@ -2071,7 +2075,7 @@ static HMENU MENU_ShowSubPopup( HWND hwn if (menu->wFlags & MF_POPUP) hdc = GetDC( menu->hWnd ); else hdc = GetDCEx( menu->hWnd, 0, DCX_CACHE | DCX_WINDOW); - SelectObject( hdc, hMenuFont); + SelectObject( hdc, get_menu_font(FALSE)); item->fState |= MF_HILITE; MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE ); @@ -3195,7 +3199,7 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, U if (!(lppop = MENU_GetMenu( GetMenu(hwnd) ))) return 0; hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW ); - SelectObject( hdc, hMenuFont); + SelectObject( hdc, get_menu_font(FALSE)); SetRect(&rectBar, orgX, orgY, orgX+menubarWidth, orgY+GetSystemMetrics(SM_CYMENU)); MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd ); ReleaseDC( hwnd, hdc ); @@ -3663,39 +3667,35 @@ HMENU WINAPI CreateMenu(void) */ BOOL WINAPI DestroyMenu( HMENU hMenu ) { - TRACE("(%p)\n", hMenu); + LPPOPUPMENU lppop = MENU_GetMenu(hMenu); - /* Silently ignore attempts to destroy default system popup */ + TRACE("(%p)\n", hMenu); - if (hMenu && hMenu != MENU_DefSysPopup) - { - LPPOPUPMENU lppop = MENU_GetMenu(hMenu); - if (!lppop) return FALSE; + if (!lppop) return FALSE; - lppop->wMagic = 0; /* Mark it as destroyed */ + lppop->wMagic = 0; /* Mark it as destroyed */ - /* DestroyMenu should not destroy system menu popup owner */ - if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd) - { - DestroyWindow( lppop->hWnd ); - lppop->hWnd = 0; - } + /* DestroyMenu should not destroy system menu popup owner */ + if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd) + { + DestroyWindow( lppop->hWnd ); + lppop->hWnd = 0; + } - if (lppop->items) /* recursively destroy submenus */ + if (lppop->items) /* recursively destroy submenus */ + { + int i; + MENUITEM *item = lppop->items; + for (i = lppop->nItems; i > 0; i--, item++) { - int i; - MENUITEM *item = lppop->items; - for (i = lppop->nItems; i > 0; i--, item++) - { - if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu); - MENU_FreeItemData( item ); - } - HeapFree( GetProcessHeap(), 0, lppop->items ); + if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu); + MENU_FreeItemData( item ); } - USER_HEAP_FREE( hMenu ); + HeapFree( GetProcessHeap(), 0, lppop->items ); } - return (hMenu != MENU_DefSysPopup); + USER_HEAP_FREE( hMenu ); + return TRUE; } @@ -3714,32 +3714,14 @@ HMENU WINAPI GetSystemMenu( HWND hWnd, B } else if (wndPtr) { - if( wndPtr->hSysMenu ) + if (wndPtr->hSysMenu && bRevert) { - if( bRevert ) - { - DestroyMenu(wndPtr->hSysMenu); - wndPtr->hSysMenu = 0; - } - else - { - POPUPMENU *menu = MENU_GetMenu( wndPtr->hSysMenu ); - if( menu ) - { - if( menu->nItems > 0 && menu->items[0].hSubMenu == MENU_DefSysPopup ) - menu->items[0].hSubMenu = MENU_CopySysPopup(); - } - else - { - WARN("Current sys-menu (%p) of wnd %p is broken\n", - wndPtr->hSysMenu, hWnd); - wndPtr->hSysMenu = 0; - } - } + DestroyMenu(wndPtr->hSysMenu); + wndPtr->hSysMenu = 0; } if(!wndPtr->hSysMenu && (wndPtr->dwStyle & WS_SYSMENU) ) - wndPtr->hSysMenu = MENU_GetSysMenu( hWnd, (HMENU)(-1) ); + wndPtr->hSysMenu = MENU_GetSysMenu( hWnd, 0 ); if( wndPtr->hSysMenu ) { @@ -3898,7 +3880,7 @@ DWORD WINAPI DrawMenuBarTemp(HWND hwnd, hMenu = GetMenu(hwnd); if (!hFont) - hFont = hMenuFont; + hFont = get_menu_font(FALSE); lppop = MENU_GetMenu( hMenu ); if (lppop == NULL || lprect == NULL) Index: wine/dlls/user/controls.h diff -u -p wine/dlls/user/controls.h:1.24 wine/dlls/user/controls.h:1.25 --- wine/dlls/user/controls.h:1.24 Tue May 21 21:26:41 2013 +++ wine/dlls/user/controls.h Tue May 21 21:26:41 2013 @@ -56,9 +56,7 @@ extern BOOL DESKTOP_SetPattern( LPCWSTR extern HWND ICONTITLE_Create( HWND hwnd ); /* menu controls */ -extern BOOL MENU_Init(void); extern HWND MENU_IsMenuActive(void); -extern HMENU MENU_GetSysMenu(HWND hWndOwner, HMENU hSysPopup); extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, INT orgX, INT orgY ); extern BOOL MENU_SetMenu(HWND, HMENU);