diff --git a/dlls/user/menu.c b/dlls/user/menu.c index 0a53150303f..eb1a089b5d8 100644 --- a/dlls/user/menu.c +++ b/dlls/user/menu.c @@ -142,6 +142,9 @@ typedef struct /* Height of a separator item */ #define SEPARATOR_HEIGHT 5 + /* Space between 2 columns */ +#define MENU_COL_SPACE 4 + /* (other menu->FocusedItem values give the position of the focused item) */ #define NO_SELECTED_ITEM 0xffff @@ -1026,6 +1029,8 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner ) { lpitem = &lppop->items[start]; orgX = maxX; + if( lpitem->fType & MF_MENUBREAK) + orgX += MENU_COL_SPACE; orgY = 3; maxTab = maxTabWidth = 0; diff --git a/dlls/user/tests/menu.c b/dlls/user/tests/menu.c index 4da99bd45f2..aebf7be4079 100644 --- a/dlls/user/tests/menu.c +++ b/dlls/user/tests/menu.c @@ -23,6 +23,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -46,6 +47,48 @@ static LRESULT WINAPI menu_check_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LP return DefWindowProc(hwnd, msg, wparam, lparam); } +/* globals to communicate between test and wndproc */ +unsigned int MOD_maxid; +RECT MOD_rc[4]; +/* wndproc used by test_menu_ownerdraw() */ +static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg, + WPARAM wparam, LPARAM lparam) +{ + switch (msg) + { + case WM_MEASUREITEM: + if( winetest_debug) + trace("WM_MEASUREITEM received %d,%d\n", + ((MEASUREITEMSTRUCT*)lparam)->itemWidth , + ((MEASUREITEMSTRUCT*)lparam)->itemHeight); + ((MEASUREITEMSTRUCT*)lparam)->itemWidth = 10; + ((MEASUREITEMSTRUCT*)lparam)->itemHeight = 10; + return TRUE; + case WM_DRAWITEM: + { + DRAWITEMSTRUCT * pdis; + HPEN oldpen; + pdis = (DRAWITEMSTRUCT *) lparam; + /* store the rectangl */ + MOD_rc[pdis->itemID] = pdis->rcItem; + if( winetest_debug) { + trace("WM_DRAWITEM received item %d rc %ld,%ld-%ld,%ld \n", + pdis->itemID, pdis->rcItem.left, pdis->rcItem.top, + pdis->rcItem.right,pdis->rcItem.bottom ); + oldpen=SelectObject( pdis->hDC, GetStockObject( + pdis->itemState & ODS_SELECTED ? WHITE_PEN :BLACK_PEN)); + Rectangle( pdis->hDC, pdis->rcItem.left,pdis->rcItem.top, + pdis->rcItem.right,pdis->rcItem.bottom ); + SelectObject( pdis->hDC, oldpen); + } + if( pdis->itemID == MOD_maxid) PostMessage(hwnd, WM_CANCELMODE, 0, 0); + return TRUE; + } + + } + return DefWindowProc(hwnd, msg, wparam, lparam); +} + static void register_menu_check_class(void) { WNDCLASS wc = @@ -101,9 +144,64 @@ static void test_menu_locked_by_window() DestroyWindow(hwnd); } +static void test_menu_ownerdraw() +{ + int i,j,k; + BOOL ret; + HMENU hmenu; + LONG leftcol; + HWND hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL, + WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError()); + if( !hwnd) return; + SetWindowLong( hwnd, GWL_WNDPROC, (LONG)menu_ownerdraw_wnd_proc); + hmenu = CreatePopupMenu(); + ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError()); + if( !hmenu) { DestroyWindow(hwnd);return;} + k=0; + for( j=0;j<2;j++) /* create columns */ + for(i=0;i<2;i++) { /* create rows */ + ret = AppendMenu( hmenu, MF_OWNERDRAW | + (i==0 ? MF_MENUBREAK : 0), k++, 0); + ok( ret, "AppendMenu failed for %d\n", k-1); + } + MOD_maxid = k-1; + assert( k <= sizeof(MOD_rc)/sizeof(RECT)); + /* display the menu */ + ret = TrackPopupMenu( hmenu, 0x100, 100,100, 0, hwnd, NULL); + + /* columns have a 4 pixel gap between them */ + ok( MOD_rc[0].right + 4 == MOD_rc[2].left, + "item rectangles are not separated by 4 pixels space\n"); + /* height should be what the MEASUREITEM message has returned */ + ok( MOD_rc[0].bottom - MOD_rc[0].top == 10, + "menu item has wrong height: %ld should be %d\n", + MOD_rc[0].bottom - MOD_rc[0].top, 10); + /* no gaps between the rows */ + ok( MOD_rc[0].bottom - MOD_rc[1].top == 0, + "There should not be a space between the rows, gap is %ld\n", + MOD_rc[0].bottom - MOD_rc[1].top); + + leftcol= MOD_rc[0].left; + ModifyMenu( hmenu, 0, MF_BYCOMMAND| MF_OWNERDRAW, 0, 0); + /* display the menu */ + ret = TrackPopupMenu( hmenu, 0x100, 100,100, 0, hwnd, NULL); + + /* left should be 4 pixels less now */ + ok( leftcol == MOD_rc[0].left + 4, + "columns should be 4 pixels to the left (actual %ld).\n", + leftcol - MOD_rc[0].left); + + trace("done\n"); + DestroyMenu( hmenu); + DestroyWindow(hwnd); +} + START_TEST(menu) { register_menu_check_class(); test_menu_locked_by_window(); + test_menu_ownerdraw(); }