[PATCH 3/3] user32: Don't rely on HMENU for showing popups
Andrew Eikum
aeikum at codeweavers.com
Fri May 16 10:55:18 CDT 2014
The idea here is to push the conversions from HMENU to struct pointer
up the call stack until eventually we are only converting to/from
HMENUs near the client code border, so we don't depend on HMENU
internally at all.
This is the first in a sequence of about 8 patches converting HMENUs
to raw pointers.
---
dlls/user32/menu.c | 85 +++++++++++++++++++++++++++---------------------------
1 file changed, 42 insertions(+), 43 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 6f064de..851e40d 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -195,6 +195,10 @@ const struct builtin_class_descr MENU_builtin_class =
(HBRUSH)(COLOR_MENU+1) /* brush */
};
+static HMENU MENU_GetHandle(const POPUPMENU *menu)
+{
+ return menu ? menu->obj.handle : NULL;
+}
/***********************************************************************
* debug_print_menuitem
@@ -1391,14 +1395,13 @@ static void draw_popup_arrow( HDC hdc, RECT rect, UINT arrow_bitmap_width,
*
* Draw a single menu item.
*/
-static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, MENUITEM *lpitem,
+static void MENU_DrawMenuItem( HWND hwnd, POPUPMENU *menu, HWND hwndOwner, HDC hdc, MENUITEM *lpitem,
UINT height, BOOL menuBar, UINT odaction )
{
RECT rect;
BOOL flat_menu = FALSE;
int bkgnd;
UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0;
- POPUPMENU *menu = MENU_GetMenu(hmenu);
RECT bmprc;
debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, "");
@@ -1446,7 +1449,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
TRACE("rect=%s\n", wine_dbgstr_rect( &lpitem->rect));
rect = lpitem->rect;
- MENU_AdjustMenuItemRect(MENU_GetMenu(hmenu), &rect);
+ MENU_AdjustMenuItemRect(menu, &rect);
if (lpitem->fType & MF_OWNERDRAW)
{
@@ -1470,7 +1473,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
if (lpitem->fState & MF_GRAYED) dis.itemState |= ODS_GRAYED|ODS_DISABLED;
if (lpitem->fState & MF_HILITE) dis.itemState |= ODS_SELECTED;
dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
- dis.hwndItem = (HWND)hmenu;
+ dis.hwndItem = (HWND)MENU_GetHandle(menu);
dis.hDC = hdc;
dis.rcItem = rect;
TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
@@ -1632,7 +1635,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
POINT origorg;
/* some applications make this assumption on the DC's origin */
SetViewportOrgEx( hdc, rect.left, rect.top, &origorg);
- MENU_DrawBitmapItem(hdc, lpitem, &bmprc, hmenu, hwndOwner,
+ MENU_DrawBitmapItem(hdc, lpitem, &bmprc, MENU_GetHandle(menu), hwndOwner,
odaction, FALSE);
SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
}
@@ -1650,7 +1653,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
POINT origorg;
SetViewportOrgEx( hdc, rect.left, rect.top, &origorg);
- MENU_DrawBitmapItem( hdc, lpitem, &bmprc, hmenu, hwndOwner,
+ MENU_DrawBitmapItem( hdc, lpitem, &bmprc, MENU_GetHandle(menu), hwndOwner,
odaction, menuBar);
SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
}
@@ -1776,7 +1779,7 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
item = menu->items;
for( u = menu->nItems; u > 0; u--, item++)
- MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc,
+ MENU_DrawMenuItem( hwnd, menu, menu->hwndOwner, hdc,
item, menu->Height, FALSE, ODA_DRAWENTIRE );
}
/* draw scroll arrows */
@@ -1816,14 +1819,13 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd )
*
* Popup menu initialization before WM_ENTERMENULOOP.
*/
-static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
+static BOOL MENU_InitPopup( HWND hwndOwner, POPUPMENU *menu, UINT flags )
{
- POPUPMENU *menu;
DWORD ex_style = 0;
- TRACE("owner=%p hmenu=%p\n", hwndOwner, hmenu);
+ TRACE("owner=%p menu=%p\n", hwndOwner, menu);
- if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+ if (!menu) return FALSE;
/* store the owner for DrawItem */
if (!IsWindow( hwndOwner ))
@@ -1840,7 +1842,7 @@ static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
menu->hWnd = CreateWindowExW( ex_style, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL,
WS_POPUP, 0, 0, 0, 0,
hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
- (LPVOID)hmenu );
+ (LPVOID)MENU_GetHandle(menu) );
if( !menu->hWnd ) return FALSE;
return TRUE;
}
@@ -1851,19 +1853,18 @@ static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
*
* Display a popup menu.
*/
-static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
+static BOOL MENU_ShowPopup( HWND hwndOwner, POPUPMENU *menu, UINT id, UINT flags,
INT x, INT y, INT xanchor, INT yanchor )
{
- POPUPMENU *menu;
INT width, height;
POINT pt;
HMONITOR monitor;
MONITORINFO info;
- TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
- hwndOwner, hmenu, id, x, y, xanchor, yanchor);
+ TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
+ hwndOwner, menu, id, x, y, xanchor, yanchor);
- if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+ if (!menu) return FALSE;
if (menu->FocusedItem != NO_SELECTED_ITEM)
{
menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
@@ -1916,7 +1917,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
if (!top_popup) {
top_popup = menu->hWnd;
- top_popup_hmenu = hmenu;
+ top_popup_hmenu = MENU_GetHandle(menu);
}
/* Display the window */
@@ -1996,7 +1997,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
if (lppop->FocusedItem != NO_SELECTED_ITEM)
{
lppop->items[lppop->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
- MENU_DrawMenuItem(lppop->hWnd, hmenu, hwndOwner, hdc,&lppop->items[lppop->FocusedItem],
+ MENU_DrawMenuItem(lppop->hWnd, lppop, hwndOwner, hdc,&lppop->items[lppop->FocusedItem],
lppop->Height, !(lppop->wFlags & MF_POPUP),
ODA_SELECT );
}
@@ -2008,7 +2009,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
if(!(lppop->items[wIndex].fType & MF_SEPARATOR)) {
lppop->items[wIndex].fState |= MF_HILITE;
MENU_EnsureMenuItemVisible(lppop, wIndex, hdc);
- MENU_DrawMenuItem( lppop->hWnd, hmenu, hwndOwner, hdc,
+ MENU_DrawMenuItem( lppop->hWnd, lppop, hwndOwner, hdc,
&lppop->items[wIndex], lppop->Height,
!(lppop->wFlags & MF_POPUP), ODA_SELECT );
}
@@ -2264,16 +2265,14 @@ static HMENU MENU_GetSubPopup( HMENU hmenu )
*
* Hide the sub-popup menus of this menu.
*/
-static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
+static void MENU_HideSubPopups( HWND hwndOwner, POPUPMENU *menu,
BOOL sendMenuSelect, UINT wFlags )
{
- POPUPMENU *menu = MENU_GetMenu( hmenu );
- TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, sendMenuSelect);
+ TRACE("owner=%p menu=%p 0x%04x\n", hwndOwner, menu, sendMenuSelect);
if (menu && top_popup)
{
- HMENU hsubmenu;
POPUPMENU *submenu;
MENUITEM *item;
@@ -2283,17 +2282,17 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
if (!(item->fType & MF_POPUP) ||
!(item->fState & MF_MOUSESELECT)) return;
item->fState &= ~MF_MOUSESELECT;
- hsubmenu = item->hSubMenu;
+ submenu = MENU_GetMenu(item->hSubMenu);
} else return;
- if (!(submenu = MENU_GetMenu( hsubmenu ))) return;
- MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE, wFlags );
- MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
+ if (!submenu) return;
+ MENU_HideSubPopups( hwndOwner, submenu, FALSE, wFlags );
+ MENU_SelectItem( hwndOwner, MENU_GetHandle(submenu), NO_SELECTED_ITEM, sendMenuSelect, 0 );
DestroyWindow( submenu->hWnd );
submenu->hWnd = 0;
if (!(wFlags & TPM_NONOTIFY))
- SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)hsubmenu,
+ SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)MENU_GetHandle(submenu),
MAKELPARAM(0, IS_SYSTEM_MENU(submenu)) );
}
}
@@ -2343,7 +2342,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
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 );
+ MENU_DrawMenuItem( menu->hWnd, menu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE );
ReleaseDC( menu->hWnd, hdc );
}
if (!item->rect.top && !item->rect.left && !item->rect.bottom && !item->rect.right)
@@ -2398,9 +2397,9 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
/* use default alignment for submenus */
wFlags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
- MENU_InitPopup( hwndOwner, item->hSubMenu, wFlags );
+ MENU_InitPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), wFlags );
- MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, wFlags,
+ MENU_ShowPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), menu->FocusedItem, wFlags,
rect.left, rect.top, rect.right, rect.bottom );
if (selectFirst)
MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
@@ -2538,11 +2537,11 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFl
!((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) )
{
/* both are top level menus (system and menu-bar) */
- MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+ MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags );
MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 );
pmt->hTopMenu = hPtMenu;
}
- else MENU_HideSubPopups( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags );
+ else MENU_HideSubPopups( pmt->hOwnerWnd, ptmenu, FALSE, wFlags );
MENU_SelectItem( pmt->hOwnerWnd, hPtMenu, id, TRUE, 0 );
}
@@ -2781,7 +2780,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM,
FALSE, 0 );
if( pmt->hCurrentMenu != pmt->hTopMenu )
- MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+ MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags );
}
if( hNewWnd != pmt->hOwnerWnd )
@@ -2862,7 +2861,7 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
hmenutmp = MENU_GetSubPopup( hmenuprev );
}
- MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
+ MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags );
pmt->hCurrentMenu = hmenuprev;
bEndMenu = FALSE;
}
@@ -2901,7 +2900,7 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
hmenutmp = MENU_GetSubPopup( hmenuprev );
}
- MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
+ MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags );
pmt->hCurrentMenu = hmenuprev;
if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) )
@@ -2964,7 +2963,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags )
{
if( pmt->hCurrentMenu != pmt->hTopMenu )
{
- MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+ MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags );
hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu;
} else hmenutmp = 0;
@@ -3264,7 +3263,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
if( IsWindow( mt.hOwnerWnd ) )
{
- MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE, wFlags );
+ MENU_HideSubPopups( mt.hOwnerWnd, menu, FALSE, wFlags );
if (menu && (menu->wFlags & MF_POPUP))
{
@@ -3463,7 +3462,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
return FALSE;
}
- if (MENU_InitPopup( hWnd, hMenu, wFlags ))
+ if (MENU_InitPopup( hWnd, menu, wFlags ))
{
MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
@@ -3471,7 +3470,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
- if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
+ if (MENU_ShowPopup( hWnd, MENU_GetMenu(hMenu), 0, wFlags, x, y, 0, 0 ))
ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
lpTpm ? &lpTpm->rcExclude : NULL );
MENU_ExitTracking(hWnd, TRUE);
@@ -3760,7 +3759,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE;
if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
if (menu->FocusedItem == wItemID) return TRUE;
- MENU_HideSubPopups( hWnd, hMenu, FALSE, 0 );
+ MENU_HideSubPopups( hWnd, menu, FALSE, 0 );
MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 );
return TRUE;
}
@@ -4450,7 +4449,7 @@ DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFO
for (i = 0; i < lppop->nItems; i++)
{
- MENU_DrawMenuItem( hwnd, hMenu, hwnd,
+ MENU_DrawMenuItem( hwnd, lppop, hwnd,
hDC, &lppop->items[i], lppop->Height, TRUE, ODA_DRAWENTIRE );
}
retvalue = lppop->Height;
--
1.9.2
More information about the wine-patches
mailing list