user32: partial implementation of GetMenuBarInfo()
Rein Klazes
wijn at online.nl
Thu Jun 11 03:47:36 CDT 2009
fixes bug #18776
---
dlls/user32/menu.c | 52 +++++++++++++++++++-
dlls/user32/tests/menu.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 176 insertions(+), 1 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 335fcfa..4b3d764 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -4191,7 +4191,57 @@ HMENU WINAPI GetMenu( HWND hWnd )
*/
BOOL WINAPI GetMenuBarInfo( HWND hwnd, LONG idObject, LONG idItem, PMENUBARINFO pmbi )
{
- FIXME( "(%p,0x%08x,0x%08x,%p)\n", hwnd, idObject, idItem, pmbi );
+ TRACE( "(%p,0x%08x,0x%08x,%p)\n", hwnd, idObject, idItem, pmbi );
+ if( !pmbi || pmbi->cbSize < sizeof(MENUBARINFO)) return FALSE;
+ switch( idObject)
+ {
+ case OBJID_MENU:
+ {
+ LPPOPUPMENU lpmenu;
+ HMENU hmenu = GetMenu( hwnd);
+ RECT rc;
+ if( !(lpmenu = MENU_GetMenu( hmenu))) return FALSE;
+ if( idItem < 0 || idItem > lpmenu->nItems) return FALSE;
+ pmbi->hMenu = hmenu;
+ /* fill in the rectangle coordinates */
+ if( !lpmenu->Height)
+ SetRectEmpty( &pmbi->rcBar);
+ else if( idItem == 0) { /* get menu rectangle */
+ GetMenuItemRect( hwnd, hmenu, 0, &rc);
+ rc.right = rc.left + lpmenu->Width;
+ rc.bottom = rc.top + lpmenu->Height;
+ pmbi->rcBar = rc;
+ } else /* get item rectangle */
+ GetMenuItemRect( hwnd, hmenu, idItem - 1, &pmbi->rcBar);
+ /* is this menu active? */
+ pmbi->hwndMenu = 0;
+ if( top_popup_hmenu == hmenu && top_popup == hwnd) {
+ pmbi->fBarFocused = TRUE;
+ if( idItem) {
+ if( lpmenu->FocusedItem == (UINT) idItem - 1) {
+ pmbi->fFocused = TRUE;
+ /* fill in the hwndMenu member if the selected item
+ * has an open sub menu */
+ if( lpmenu->items[idItem - 1].fType & MF_POPUP) {
+ HMENU hsubmenu;
+ POPUPMENU *lpsubmenu;
+ hsubmenu = lpmenu->items[idItem - 1].hSubMenu;
+ lpsubmenu = MENU_GetMenu( hsubmenu);
+ if( lpsubmenu)
+ pmbi->hwndMenu = lpsubmenu->hWnd;
+ }
+ } else
+ pmbi->fFocused = FALSE;
+ } else
+ pmbi->fFocused = TRUE;
+ } else {
+ pmbi->fBarFocused = FALSE;
+ pmbi->fFocused = FALSE;
+ }
+ return TRUE;
+ }
+ }
+ FIXME( "(%p,0x%08x,0x%08x,%p) Object id not supported!\n", hwnd, idObject, idItem, pmbi );
return FALSE;
}
diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c
index 0948f69..448e04f 100644
--- a/dlls/user32/tests/menu.c
+++ b/dlls/user32/tests/menu.c
@@ -38,6 +38,7 @@
static ATOM atomMenuCheckClass;
static BOOL (WINAPI *pGetMenuInfo)(HMENU,LPCMENUINFO);
+static BOOL (WINAPI *pGetMenuBarInfo)(HWND,LONG,LONG,PMENUBARINFO);
static UINT (WINAPI *pSendInput)(UINT, INPUT*, size_t);
static BOOL (WINAPI *pSetMenuInfo)(HMENU,LPCMENUINFO);
static BOOL (WINAPI *pEndMenu) (void);
@@ -52,6 +53,7 @@ static void init_function_pointers(void)
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC(GetMenuInfo)
+ GET_PROC(GetMenuBarInfo)
GET_PROC(SendInput)
GET_PROC(SetMenuInfo)
GET_PROC(EndMenu)
@@ -116,6 +118,7 @@ typedef struct
/* globals to communicate between test and wndproc */
static BOOL bMenuVisible;
+static HMENU popmenu;
static BOOL got_input;
static HMENU hMenus[4];
@@ -256,6 +259,92 @@ static void register_menu_check_class(void)
atomMenuCheckClass = RegisterClass(&wc);
}
+/* some tests for GetMenuBarInfo */
+void test_getmenubarinfo()
+{
+ BOOL ret;
+ HMENU hmenu;
+ MENUBARINFO mbi = { sizeof(MENUBARINFO), { -1, -1, -1, -1}, (HMENU)-2, (HWND)-3, 1, 1};
+ RECT rcw, rci;
+ HWND hwnd;
+ if( !pGetMenuBarInfo) {
+ win_skip("GetMenuBarInfo is not available\n");
+ return;
+ }
+ hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL,
+ WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
+ NULL, NULL, NULL, NULL);
+ ok( hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
+ /* no menu: getmenubar =info should fail */
+ ret = pGetMenuBarInfo( hwnd, OBJID_MENU, 0, &mbi);
+ ok( !ret, "GetMenuBarInfo should not have been successfull\n");
+ /* the MENUBARINFO members have not been changed */
+ ok( (-1 == mbi.rcBar.left && (HWND) -3 == mbi.hwndMenu && mbi.fBarFocused) ||
+ TRUE, /* win 9x,ME */
+ "MENUBARINFO should not be changed.\n");
+ /* create menubar, no items yet */
+ hmenu = CreateMenu();
+ ok(hmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
+ ret = SetMenu( hwnd, hmenu);
+ ok( ret, "SetMenu failed with error %d\n", GetLastError());
+ /* do the tests */
+ UpdateWindow( hwnd); /* hack for wine to draw the window + menu */
+ ret = pGetMenuBarInfo( hwnd, OBJID_MENU, 0, &mbi);
+ ok( ret, "GetMenuBarInfo failed with error %d\n", GetLastError());
+ /* a menubar without items returns null rectangle */
+ ok( mbi.rcBar.left == 0 && mbi.rcBar.top == 0 &&
+ mbi.rcBar.bottom == 0 && mbi.rcBar.right == 0,
+ "GetMenuBarInfo returns unexpected menu rectangle. Got %d,%d-%d,%d instead of 0,0-0,0\n",
+ mbi.rcBar.left, mbi.rcBar.top, mbi.rcBar.right, mbi.rcBar.bottom);
+ ok( mbi.hMenu == hmenu, "GetMenuBarInfo returns unexpected menu handle. Got %p instead of %p\n",
+ mbi.hMenu, hmenu);
+ ok( mbi.fBarFocused == 0, "GetMenuBarInfo returns: menu bar has focus.\n");
+ ok( mbi.fFocused == 0, "GetMenuBarInfo returns: menu item has focus.\n");
+ /* add some items */
+ ret = AppendMenu( hmenu, MF_STRING , 100, "item 1");
+ ok( ret, "AppendMenu failed.\n");
+ ret = AppendMenu( hmenu, MF_STRING , 101, "item 2");
+ ok( ret, "AppendMenu failed.\n");
+ ret = SetMenu( hwnd, hmenu);
+ ok( ret, "SetMenu failed with error %d\n", GetLastError());
+ /* do the tests */
+ UpdateWindow( hwnd); /* hack for wine to draw the window + menu */
+ /* get info for the whole menu */
+ ret = pGetMenuBarInfo( hwnd, OBJID_MENU, 0, &mbi);
+ ok( ret, "GetMenuBarInfo failed with error %d\n", GetLastError());
+ /* calculate menu rectangle, from window rectangle and the position of the first item */
+ ret = GetWindowRect( hwnd, &rcw);
+ ok( ret, "GetWindowRect failed.\n");
+ ret = GetMenuItemRect( hwnd, hmenu, 0, &rci);
+ ok( ret, "GetMenuItemRect failed.\n");
+todo_wine
+ ok( mbi.rcBar.left == rci.left && mbi.rcBar.top == rci.top &&
+ mbi.rcBar.bottom == rci.bottom && mbi.rcBar.right == rcw.right - rci.left + rcw.left,
+ "GetMenuBarInfo returns unexpected menu rectangle. Got %d,%d-%d,%d instead of %d,%d-%d,%d\n",
+ mbi.rcBar.left, mbi.rcBar.top, mbi.rcBar.right, mbi.rcBar.bottom,
+ rci.left, rci.top, rcw.right - rci.left + rcw.left, rci.bottom);
+ ok( mbi.hMenu == hmenu, "GetMenuBarInfo returns unexpected menu handle. Got %p instead of %p\n",
+ mbi.hMenu, hmenu);
+ ok( mbi.fBarFocused == 0, "GetMenuBarInfo returns: menu bar has focus.\n");
+ ok( mbi.fFocused == 0, "GetMenuBarInfo returns: menu item has focus.\n");
+ /* get info for item nr.2 */
+ ret = pGetMenuBarInfo( hwnd, OBJID_MENU, 2, &mbi);
+ ok( ret, "GetMenuBarInfo failed with error %d\n", GetLastError());
+ ret = GetMenuItemRect( hwnd, hmenu, 1, &rci);
+ ok( ret, "GetMenuItemRect failed.\n");
+ ok( mbi.rcBar.left == rci.left && mbi.rcBar.top == rci.top &&
+ mbi.rcBar.bottom == rci.bottom && mbi.rcBar.right == rci.right,
+ "GetMenuBarInfo returns unexpected menu rectangle. Got %d,%d-%d,%d instead of %d,%d-%d,%d\n",
+ mbi.rcBar.left, mbi.rcBar.top, mbi.rcBar.right, mbi.rcBar.bottom,
+ rci.left, rci.top, rci.right, rci.bottom);
+ ok( mbi.hMenu == hmenu, "GetMenuBarInfo returns unexpected menu handle. Got %p instead of %p\n",
+ mbi.hMenu, hmenu);
+ ok( mbi.fBarFocused == 0, "GetMenuBarInfo returns: menu bar has focus.\n");
+ ok( mbi.fFocused == 0, "GetMenuBarInfo returns: menu item has focus.\n");
+ /* clean up */
+ DestroyWindow(hwnd);
+}
+
/* demonstrates that windows locks the menu object so that it is still valid
* even after a client calls DestroyMenu on it */
static void test_menu_locked_by_window(void)
@@ -1985,6 +2074,35 @@ static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter)
}
else
ok(menu_tests[i].bMenuVisible == bMenuVisible, "test %d\n", i);
+ /* add some GetMenuBarInfo tests */
+ if( pGetMenuBarInfo)
+ {
+ MENUBARINFO mbi = { sizeof(MENUBARINFO)};
+ HMENU hmenu;
+ UINT state;
+ /* get info for the menu */
+ pGetMenuBarInfo( hWnd, OBJID_MENU, 0, &mbi);
+ hmenu = GetMenu( hWnd);
+ ok( !mbi.hwndMenu, "test %d GetMenuBarInfo.hwndMenu wrong: %p expected NULL\n",
+ i, mbi.hwndMenu);
+ ok( mbi.hMenu == hmenu, "test %d GetMenuBarInfo got wrong menu: %p expected %p\n",
+ i, mbi.hMenu, hmenu);
+ ok( !bMenuVisible == !mbi.fBarFocused, "test %d GetMenuBarInfo.fBarFocused (%d) is wrong\n",
+ i, mbi.fBarFocused != 0);
+ ok( !bMenuVisible == !mbi.fFocused, "test %d GetMenuBarInfo.fFocused (%d) is wrong\n",
+ i, mbi.fFocused != 0);
+ /* get info for the menu's first item */
+ pGetMenuBarInfo( hWnd, OBJID_MENU, 1, &mbi);
+ state = GetMenuState( hmenu, 0, MF_BYPOSITION);
+ ok( !mbi.hwndMenu == !popmenu, "test %d GetMenuBarInfo.hwndMenu wrong: %p expected %sNULL\n",
+ i, mbi.hwndMenu, popmenu ? "not " : "");
+ ok( mbi.hMenu == hmenu, "test %d GetMenuBarInfo got wrong menu: %p expected %p\n",
+ i, mbi.hMenu, hmenu);
+ ok( !bMenuVisible == !mbi.fBarFocused, "test %d GetMenuBarInfo.fBarFocused (%d) is wrong\n",
+ i, mbi.fBarFocused != 0);
+ ok( !(bMenuVisible && (state & MF_HILITE)) == !mbi.fFocused,
+ "test %d GetMenuBarInfo.fFocused (%d) is wrong\n", i, mbi.fFocused != 0);
+ }
}
return 0;
}
@@ -1993,6 +2111,12 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
switch (msg) {
+ case WM_INITMENUPOPUP:
+ popmenu = (HMENU) wParam;
+ break;
+ case WM_UNINITMENUPOPUP:
+ popmenu = NULL;
+ break;
case WM_ENTERMENULOOP:
bMenuVisible = TRUE;
break;
@@ -2954,6 +3078,7 @@ START_TEST(menu)
test_menu_locked_by_window();
test_subpopup_locked_by_menu();
test_menu_ownerdraw();
+ test_getmenubarinfo();
test_menu_bmp_and_string();
/* test Get/SetMenuInfo if available */
if( pGetMenuInfo && pSetMenuInfo) {
--
1.6.3.1
More information about the wine-patches
mailing list