menu.c: fix for items with HBMMENU_CALLBACK bitmap handle.
Rein Klazes
wijn at wanadoo.nl
Tue Jul 5 12:10:47 CDT 2005
Hi,
Fixes for bug #3073, "Icons are drawn incorrectly in menu - always at
very top of menu instead of being drawn near menu entries".
Changelog:
dlls/user : menu.c
- when sending the WM_DRAWITEM message in case of a menu item with
hbmpItem = HBMMENU_CALLBACK, move the drawing origin to the top left of
the item rectangle;
- at the same time also make sure that the itemState field of the
DRAWITEMSTRUCT is properly initialized;
- Do the drawing of the check mark before sending the WM_DRAWITEM
message, some application likes to "overdraw" the checkmark.
Rein.
-------------- next part --------------
--- wine/dlls/user/menu.c 2005-06-21 10:01:33.000000000 +0200
+++ mywine/dlls/user/menu.c 2005-07-05 15:19:05.000000000 +0200
@@ -1285,39 +1285,16 @@ static void MENU_DrawMenuItem( HWND hwnd
if (!(lpitem->fType & MF_OWNERDRAW))
{
+ RECT rc;
+ rc = rect;
/* New style MIIM_BITMAP */
if (lpitem->hbmpItem)
{
POPUPMENU *menu = MENU_GetMenu(hmenu);
- HBITMAP hbm = lpitem->hbmpItem;
-
- if (hbm == HBMMENU_CALLBACK)
- {
- DRAWITEMSTRUCT drawItem;
- drawItem.CtlType = ODT_MENU;
- drawItem.CtlID = 0;
- drawItem.itemID = lpitem->wID;
- drawItem.itemAction = odaction;
- drawItem.itemState |= (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
- drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
- drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
- drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
- drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
- drawItem.hwndItem = (HWND)hmenu;
- drawItem.hDC = hdc;
- drawItem.rcItem = lpitem->rect;
- drawItem.itemData = lpitem->dwItemData;
-
- if (!(lpitem->fState & MF_CHECKED))
- SendMessageW( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
-
- } else {
- MENU_DrawBitmapItem(hdc, lpitem, &rect, FALSE, TRUE);
- }
if (menu->dwStyle & MNS_CHECKORBMP)
- rect.left += menu->maxBmpSize.cx - check_bitmap_width;
+ rc.left += menu->maxBmpSize.cx - check_bitmap_width;
else
- rect.left += menu->maxBmpSize.cx;
+ rc.left += menu->maxBmpSize.cx;
}
/* Draw the check mark
*
@@ -1329,7 +1306,7 @@ static void MENU_DrawMenuItem( HWND hwnd
{
HDC hdcMem = CreateCompatibleDC( hdc );
SelectObject( hdcMem, bm );
- BitBlt( hdc, rect.left, (y - check_bitmap_height) / 2,
+ BitBlt( hdc, rc.left, (y - check_bitmap_height) / 2,
check_bitmap_width, check_bitmap_height,
hdcMem, 0, 0, SRCCOPY );
DeleteDC( hdcMem );
@@ -1344,11 +1321,43 @@ static void MENU_DrawMenuItem( HWND hwnd
DrawFrameControl( hdcMem, &r, DFC_MENU,
(lpitem->fType & MFT_RADIOCHECK) ?
DFCS_MENUBULLET : DFCS_MENUCHECK );
- BitBlt( hdc, rect.left, (y - r.bottom) / 2, r.right, r.bottom,
+ BitBlt( hdc, rc.left, (y - r.bottom) / 2, r.right, r.bottom,
hdcMem, 0, 0, SRCCOPY );
DeleteDC( hdcMem );
DeleteObject( bm );
}
+ /* New style MIIM_BITMAP */
+ if (lpitem->hbmpItem)
+ {
+ HBITMAP hbm = lpitem->hbmpItem;
+
+ if (hbm == HBMMENU_CALLBACK)
+ {
+ DRAWITEMSTRUCT drawItem;
+ POINT origorg;
+ drawItem.CtlType = ODT_MENU;
+ drawItem.CtlID = 0;
+ drawItem.itemID = lpitem->wID;
+ drawItem.itemAction = odaction;
+ drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
+ drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
+ drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
+ drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
+ drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
+ drawItem.hwndItem = (HWND)hmenu;
+ drawItem.hDC = hdc;
+ drawItem.rcItem = lpitem->rect;
+ drawItem.itemData = lpitem->dwItemData;
+ /* some applications make this assumption on the DC's origin */
+ SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg);
+ OffsetRect( &drawItem.rcItem, - lpitem->rect.left, - lpitem->rect.top);
+ SendMessageW( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
+ SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
+
+ } else {
+ MENU_DrawBitmapItem(hdc, lpitem, &rect, FALSE, TRUE);
+ }
+ }
}
/* Draw the popup-menu arrow */
More information about the wine-patches
mailing list