From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/defwnd.c | 18 ------------------ dlls/win32u/defwnd.c | 14 ++++++++++++++ dlls/win32u/font.c | 22 ++++++++++++++++++++++ dlls/win32u/tests/win32u.c | 9 +++++++++ dlls/win32u/win32u_private.h | 1 + 5 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index 16442b6899e..c72789ac963 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -145,16 +145,6 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam result = NC_HandleSysCommand( hwnd, wParam, lParam ); break;
- case WM_GETTEXTLENGTH: - { - WND *wndPtr = WIN_GetPtr( hwnd ); - if (wndPtr && wndPtr->text) - result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, lstrlenW(wndPtr->text), - NULL, 0, NULL, NULL ); - WIN_ReleasePtr( wndPtr ); - } - break; - case WM_GETTEXT: if (wParam) { @@ -325,14 +315,6 @@ LRESULT WINAPI DefWindowProcW( result = NC_HandleSysCommand( hwnd, wParam, lParam ); break;
- case WM_GETTEXTLENGTH: - { - WND *wndPtr = WIN_GetPtr( hwnd ); - if (wndPtr && wndPtr->text) result = (LRESULT)lstrlenW(wndPtr->text); - WIN_ReleasePtr( wndPtr ); - } - break; - case WM_GETTEXT: if (wParam) { diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index 90323e304fc..c54dbdb710c 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2505,6 +2505,20 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, handle_nc_paint( hwnd , (HRGN)1 ); /* repaint caption */ break;
+ case WM_GETTEXTLENGTH: + { + WND *win = get_win_ptr( hwnd ); + if (win && win->text) + { + if (ansi) + result = win32u_wctomb_size( &ansi_cp, win->text, wcslen( win->text )); + else + result = wcslen( win->text ); + } + release_win_ptr( win ); + } + break; + case WM_SETICON: result = (LRESULT)set_window_icon( hwnd, wparam, (HICON)lparam ); if ((get_window_long( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION) diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 39b195fe25a..5bf59903308 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -3230,6 +3230,28 @@ DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *sr return ret; }
+DWORD win32u_wctomb_size( CPTABLEINFO *info, const WCHAR *src, DWORD srclen ) +{ + DWORD ret; + + if (info->CodePage == CP_UTF8) + { + RtlUnicodeToUTF8N( NULL, 0, &ret, src, srclen * sizeof(WCHAR) ); + } + else if(info->DBCSCodePage) + { + WCHAR *uni2cp = info->WideCharTable; + for (ret = srclen; srclen; srclen--, src++) + if (uni2cp[*src] & 0xff00) ret++; + } + else + { + ret = srclen; + } + + return ret; +} + DWORD win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *src, DWORD srclen ) { DWORD ret; diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 11820859358..dc1638f37ab 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -494,6 +494,12 @@ static void test_window_text(void) ok( len == 4, "len = %d\n", len ); ok( !lstrcmpW( buf, L"test" ), "buf = %s\n", wine_dbgstr_w(buf) );
+ res = NtUserMessageCall( hwnd, WM_GETTEXTLENGTH, 0, 0, 0, NtUserDefWindowProc, TRUE ); + ok( res == 4, "res = %Id\n", res ); + + res = NtUserMessageCall( hwnd, WM_GETTEXTLENGTH, 0, 0, 0, NtUserDefWindowProc, FALSE ); + ok( res == 4, "res = %Id\n", res ); + res = NtUserMessageCall( hwnd, WM_SETTEXT, 0, (LPARAM)"TestA", 0, NtUserDefWindowProc, TRUE ); ok( res == 1, "res = %Id\n", res );
@@ -502,6 +508,9 @@ static void test_window_text(void) ok( len == 5, "len = %d\n", len ); ok( !lstrcmpW( buf, L"TestA" ), "buf = %s\n", wine_dbgstr_w(buf) );
+ res = NtUserMessageCall( hwnd, WM_GETTEXTLENGTH, 0, 0, 0, NtUserDefWindowProc, TRUE ); + ok( res == 5, "res = %Id\n", res ); + DestroyWindow( hwnd ); }
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 808d3f83e37..468375f1ddf 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -575,6 +575,7 @@ DWORD win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *sr DWORD srclen ) DECLSPEC_HIDDEN; DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *src, DWORD srclen ) DECLSPEC_HIDDEN; +DWORD win32u_wctomb_size( CPTABLEINFO *info, const WCHAR *src, DWORD srclen ) DECLSPEC_HIDDEN;
static inline WCHAR *win32u_wcsdup( const WCHAR *str ) {
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117387
Your paranoid android.
=== debian11 (32 bit Chinese:China report) ===
user32: msg.c:6881: Test failed: SetFocus(hwnd) on a button: 8: the msg sequence is not complete: expected 0000 - actual 0006
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/defwnd.c | 71 -------------------------------------------- dlls/win32u/defwnd.c | 34 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 71 deletions(-)
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index c72789ac963..d29846ad623 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -30,8 +30,6 @@ #include "win.h" #include "user_private.h" #include "controls.h" -#include "wine/server.h" -#include "wine/exception.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(win); @@ -73,28 +71,6 @@ HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) }
-static LPARAM DEFWND_GetTextA( WND *wndPtr, LPSTR dest, WPARAM wParam ) -{ - LPARAM result = 0; - - __TRY - { - if (wndPtr->text) - { - if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1, - dest, wParam, NULL, NULL )) dest[wParam-1] = 0; - result = strlen( dest ); - } - else dest[0] = '\0'; - } - __EXCEPT_PAGE_FAULT - { - return 0; - } - __ENDTRY - return result; -} - /*********************************************************************** * DefWindowProcA (USER32.@) * @@ -145,19 +121,6 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam result = NC_HandleSysCommand( hwnd, wParam, lParam ); break;
- case WM_GETTEXT: - if (wParam) - { - LPSTR dest = (LPSTR)lParam; - WND *wndPtr = WIN_GetPtr( hwnd ); - - if (!wndPtr) break; - result = DEFWND_GetTextA( wndPtr, dest, wParam ); - - WIN_ReleasePtr( wndPtr ); - } - break; - case WM_IME_CHAR: if (HIBYTE(wParam)) PostMessageA( hwnd, WM_CHAR, HIBYTE(wParam), lParam ); PostMessageA( hwnd, WM_CHAR, LOBYTE(wParam), lParam ); @@ -236,28 +199,6 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam }
-static LPARAM DEFWND_GetTextW( WND *wndPtr, LPWSTR dest, WPARAM wParam ) -{ - LPARAM result = 0; - - __TRY - { - if (wndPtr->text) - { - lstrcpynW( dest, wndPtr->text, wParam ); - result = lstrlenW( dest ); - } - else dest[0] = '\0'; - } - __EXCEPT_PAGE_FAULT - { - return 0; - } - __ENDTRY - - return result; -} - /*********************************************************************** * DefWindowProcW (USER32.@) Calls default window message handler * @@ -315,18 +256,6 @@ LRESULT WINAPI DefWindowProcW( result = NC_HandleSysCommand( hwnd, wParam, lParam ); break;
- case WM_GETTEXT: - if (wParam) - { - LPWSTR dest = (LPWSTR)lParam; - WND *wndPtr = WIN_GetPtr( hwnd ); - - if (!wndPtr) break; - result = DEFWND_GetTextW( wndPtr, dest, wParam ); - WIN_ReleasePtr( wndPtr ); - } - break; - case WM_IME_CHAR: PostMessageW( hwnd, WM_CHAR, wParam, lParam ); break; diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index c54dbdb710c..af51b933d49 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2519,6 +2519,40 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, } break;
+ case WM_GETTEXT: + if (wparam) + { + WND *win; + + if (!(win = get_win_ptr( hwnd ))) break; + + __TRY + { + if (ansi) + { + char *dest = (char *)lparam; + if (win->text) + result = win32u_wctomb( &ansi_cp, dest, wparam - 1, + win->text, wcslen( win->text )); + dest[result] = 0; + } + else + { + WCHAR *dest = (WCHAR *)lparam; + if (win->text) result = min( wcslen( win->text ), wparam - 1 ); + if (result) memcpy( dest, win->text, result * sizeof(WCHAR) ); + dest[result] = 0; + } + } + __EXCEPT + { + } + __ENDTRY + + release_win_ptr( win ); + } + break; + case WM_SETICON: result = (LRESULT)set_window_icon( hwnd, wparam, (HICON)lparam ); if ((get_window_long( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION)
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/menu.c | 212 ++------------------------------------------- dlls/win32u/menu.c | 123 ++++++++++++++++++++++++++ include/ntuser.h | 2 + 3 files changed, 131 insertions(+), 206 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 74a43eaab1a..df260b063d9 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -96,91 +96,6 @@ const struct builtin_class_descr MENU_builtin_class = };
-/*********************************************************************** - * debug_print_menuitem - * - * Print a menuitem in readable form. - */ - -#define debug_print_menuitem(pre, mp, post) \ - do { if (TRACE_ON(menu)) do_debug_print_menuitem(pre, mp, post); } while (0) - -#define MENUOUT(text) \ - TRACE("%s%s", (count++ ? "," : ""), (text)) - -#define MENUFLAG(bit,text) \ - do { \ - if (flags & (bit)) { flags &= ~(bit); MENUOUT ((text)); } \ - } while (0) - -static void do_debug_print_menuitem(const char *prefix, const MENUITEM *mp, - const char *postfix) -{ - static const char * const hbmmenus[] = { "HBMMENU_CALLBACK", "", "HBMMENU_SYSTEM", - "HBMMENU_MBAR_RESTORE", "HBMMENU_MBAR_MINIMIZE", "UNKNOWN BITMAP", "HBMMENU_MBAR_CLOSE", - "HBMMENU_MBAR_CLOSE_D", "HBMMENU_MBAR_MINIMIZE_D", "HBMMENU_POPUP_CLOSE", - "HBMMENU_POPUP_RESTORE", "HBMMENU_POPUP_MAXIMIZE", "HBMMENU_POPUP_MINIMIZE"}; - TRACE("%s ", prefix); - if (mp) { - UINT flags = mp->fType; - TRACE( "{ ID=0x%Ix", mp->wID); - if ( mp->hSubMenu) - TRACE( ", Sub=%p", mp->hSubMenu); - if (flags) { - int count = 0; - TRACE( ", fType="); - MENUFLAG( MFT_SEPARATOR, "sep"); - MENUFLAG( MFT_OWNERDRAW, "own"); - MENUFLAG( MFT_BITMAP, "bit"); - MENUFLAG(MF_POPUP, "pop"); - MENUFLAG(MFT_MENUBARBREAK, "barbrk"); - MENUFLAG(MFT_MENUBREAK, "brk"); - MENUFLAG(MFT_RADIOCHECK, "radio"); - MENUFLAG(MFT_RIGHTORDER, "rorder"); - MENUFLAG(MF_SYSMENU, "sys"); - MENUFLAG(MFT_RIGHTJUSTIFY, "right"); /* same as MF_HELP */ - if (flags) - TRACE( "+0x%x", flags); - } - flags = mp->fState; - if (flags) { - int count = 0; - TRACE( ", State="); - MENUFLAG(MFS_GRAYED, "grey"); - MENUFLAG(MFS_DEFAULT, "default"); - MENUFLAG(MFS_DISABLED, "dis"); - MENUFLAG(MFS_CHECKED, "check"); - MENUFLAG(MFS_HILITE, "hi"); - MENUFLAG(MF_USECHECKBITMAPS, "usebit"); - MENUFLAG(MF_MOUSESELECT, "mouse"); - if (flags) - TRACE( "+0x%x", flags); - } - if (mp->hCheckBit) - TRACE( ", Chk=%p", mp->hCheckBit); - if (mp->hUnCheckBit) - TRACE( ", Unc=%p", mp->hUnCheckBit); - if (mp->text) - TRACE( ", Text=%s", debugstr_w(mp->text)); - if (mp->dwItemData) - TRACE( ", ItemData=0x%08Ix", mp->dwItemData); - if (mp->hbmpItem) - { - if( IS_MAGIC_BITMAP(mp->hbmpItem)) - TRACE( ", hbitmap=%s", hbmmenus[ (INT_PTR)mp->hbmpItem + 1]); - else - TRACE( ", hbitmap=%p", mp->hbmpItem); - } - TRACE( " }"); - } else - TRACE( "NULL"); - TRACE(" %s\n", postfix); -} - -#undef MENUOUT -#undef MENUFLAG - - /*********************************************************************** * MENU_GetMenu * @@ -1012,122 +927,6 @@ BOOL WINAPI IsMenu( HMENU menu ) return FALSE; }
-/********************************************************************** - * GetMenuItemInfo_common - */ - -static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT id, BOOL bypos, - LPMENUITEMINFOW lpmii, BOOL unicode) -{ - POPUPMENU *menu; - MENUITEM *item; - UINT pos; - - menu = find_menu_item(hmenu, id, bypos ? MF_BYPOSITION : 0, &pos); - - item = menu ? &menu->items[pos] : NULL; - - debug_print_menuitem("GetMenuItemInfo_common: ", item, ""); - - if (!menu) - { - SetLastError( ERROR_MENU_ITEM_NOT_FOUND); - return FALSE; - } - - if( lpmii->fMask & MIIM_TYPE) { - if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) { - release_menu_ptr(menu); - WARN("invalid combination of fMask bits used\n"); - /* this does not happen on Win9x/ME */ - SetLastError( ERROR_INVALID_PARAMETER); - return FALSE; - } - lpmii->fType = item->fType & MENUITEMINFO_TYPE_MASK; - if (item->hbmpItem && !IS_MAGIC_BITMAP(item->hbmpItem)) - lpmii->fType |= MFT_BITMAP; - lpmii->hbmpItem = item->hbmpItem; /* not on Win9x/ME */ - if( lpmii->fType & MFT_BITMAP) { - lpmii->dwTypeData = (LPWSTR) item->hbmpItem; - lpmii->cch = 0; - } else if( lpmii->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) { - /* this does not happen on Win9x/ME */ - lpmii->dwTypeData = 0; - lpmii->cch = 0; - } - } - - /* copy the text string */ - if ((lpmii->fMask & (MIIM_TYPE|MIIM_STRING))) { - if (!item->text) { - if(lpmii->dwTypeData && lpmii->cch) { - if( unicode) - *((WCHAR *)lpmii->dwTypeData) = 0; - else - *((CHAR *)lpmii->dwTypeData) = 0; - } - lpmii->cch = 0; - } else { - int len; - if (unicode) - { - len = lstrlenW(item->text); - if(lpmii->dwTypeData && lpmii->cch) - lstrcpynW(lpmii->dwTypeData, item->text, lpmii->cch); - } - else - { - len = WideCharToMultiByte( CP_ACP, 0, item->text, -1, NULL, - 0, NULL, NULL ) - 1; - if(lpmii->dwTypeData && lpmii->cch) - if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1, - (LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL )) - ((LPSTR)lpmii->dwTypeData)[lpmii->cch - 1] = 0; - } - /* if we've copied a substring we return its length */ - if(lpmii->dwTypeData && lpmii->cch) - if (lpmii->cch <= len + 1) - lpmii->cch--; - else - lpmii->cch = len; - else { - /* return length of string */ - /* not on Win9x/ME if fType & MFT_BITMAP */ - lpmii->cch = len; - } - } - } - - if (lpmii->fMask & MIIM_FTYPE) - lpmii->fType = item->fType & MENUITEMINFO_TYPE_MASK; - - if (lpmii->fMask & MIIM_BITMAP) - lpmii->hbmpItem = item->hbmpItem; - - if (lpmii->fMask & MIIM_STATE) - lpmii->fState = item->fState & MENUITEMINFO_STATE_MASK; - - if (lpmii->fMask & MIIM_ID) - lpmii->wID = item->wID; - - if (lpmii->fMask & MIIM_SUBMENU) - lpmii->hSubMenu = item->hSubMenu; - else { - /* hSubMenu is always cleared - * (not on Win9x/ME ) */ - lpmii->hSubMenu = 0; - } - - if (lpmii->fMask & MIIM_CHECKMARKS) { - lpmii->hbmpChecked = item->hCheckBit; - lpmii->hbmpUnchecked = item->hUnCheckBit; - } - if (lpmii->fMask & MIIM_DATA) - lpmii->dwItemData = item->dwItemData; - - release_menu_ptr(menu); - return TRUE; -}
/********************************************************************** * GetMenuItemInfoA (USER32.@) @@ -1144,10 +943,10 @@ BOOL WINAPI GetMenuItemInfoA( HMENU hmenu, UINT item, BOOL bypos, } memcpy( &mii, lpmii, lpmii->cbSize); mii.cbSize = sizeof( mii); - ret = GetMenuItemInfo_common (hmenu, item, bypos, - (LPMENUITEMINFOW)&mii, FALSE); + ret = NtUserThunkedMenuItemInfo( hmenu, item, bypos ? MF_BYPOSITION : 0, + NtUserGetMenuItemInfoA, (MENUITEMINFOW *)&mii, NULL ); mii.cbSize = lpmii->cbSize; - memcpy( lpmii, &mii, mii.cbSize); + memcpy( lpmii, &mii, mii.cbSize ); return ret; }
@@ -1166,9 +965,10 @@ BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos, } memcpy( &mii, lpmii, lpmii->cbSize); mii.cbSize = sizeof( mii); - ret = GetMenuItemInfo_common (hmenu, item, bypos, &mii, TRUE); + ret = NtUserThunkedMenuItemInfo( hmenu, item, bypos ? MF_BYPOSITION : 0, + NtUserGetMenuItemInfoW, &mii, NULL ); mii.cbSize = lpmii->cbSize; - memcpy( lpmii, &mii, mii.cbSize); + memcpy( lpmii, &mii, mii.cbSize ); return ret; }
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 6a464047427..ca2c018f7e1 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -992,6 +992,123 @@ UINT get_menu_state( HMENU handle, UINT item_id, UINT flags ) return state; }
+static BOOL get_menu_item_info( HMENU handle, UINT id, UINT flags, MENUITEMINFOW *info, BOOL ansi ) +{ + POPUPMENU *menu; + MENUITEM *item; + UINT pos; + + if (!info || info->cbSize != sizeof(*info)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + menu = find_menu_item( handle, id, flags, &pos ); + item = menu ? &menu->items[pos] : NULL; + TRACE( "%s\n", debugstr_menuitem( item )); + if (!menu) + { + SetLastError( ERROR_MENU_ITEM_NOT_FOUND); + return FALSE; + } + + if (info->fMask & MIIM_TYPE) + { + if (info->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) + { + release_menu_ptr( menu ); + WARN( "invalid combination of fMask bits used\n" ); + /* this does not happen on Win9x/ME */ + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + info->fType = item->fType & MENUITEMINFO_TYPE_MASK; + if (item->hbmpItem && !IS_MAGIC_BITMAP(item->hbmpItem)) + info->fType |= MFT_BITMAP; + info->hbmpItem = item->hbmpItem; /* not on Win9x/ME */ + if (info->fType & MFT_BITMAP) + { + info->dwTypeData = (WCHAR *)item->hbmpItem; + info->cch = 0; + } + else if (info->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) + { + /* this does not happen on Win9x/ME */ + info->dwTypeData = 0; + info->cch = 0; + } + } + + /* copy the text string */ + if ((info->fMask & (MIIM_TYPE|MIIM_STRING))) + { + if (!item->text) + { + if (info->dwTypeData && info->cch) + { + if (ansi) + *((char *)info->dwTypeData) = 0; + else + *((WCHAR *)info->dwTypeData) = 0; + } + info->cch = 0; + } + else + { + DWORD len, text_len; + if (ansi) + { + text_len = wcslen( item->text ); + len = win32u_wctomb_size( &ansi_cp, item->text, text_len ); + if (info->dwTypeData && info->cch) + if (!win32u_wctomb( &ansi_cp, (char *)info->dwTypeData, info->cch, + item->text, text_len + 1 )) + ((char *)info->dwTypeData)[info->cch - 1] = 0; + } + else + { + len = lstrlenW( item->text ); + if (info->dwTypeData && info->cch) + lstrcpynW( info->dwTypeData, item->text, info->cch ); + } + + if (info->dwTypeData && info->cch) + { + /* if we've copied a substring we return its length */ + if (info->cch <= len + 1) + info->cch--; + else + info->cch = len; + } + else + { + /* return length of string, not on Win9x/ME if fType & MFT_BITMAP */ + info->cch = len; + } + } + } + + if (info->fMask & MIIM_FTYPE) info->fType = item->fType & MENUITEMINFO_TYPE_MASK; + if (info->fMask & MIIM_BITMAP) info->hbmpItem = item->hbmpItem; + if (info->fMask & MIIM_STATE) info->fState = item->fState & MENUITEMINFO_STATE_MASK; + if (info->fMask & MIIM_ID) info->wID = item->wID; + if (info->fMask & MIIM_DATA) info->dwItemData = item->dwItemData; + + if (info->fMask & MIIM_SUBMENU) info->hSubMenu = item->hSubMenu; + else info->hSubMenu = 0; /* hSubMenu is always cleared (not on Win9x/ME ) */ + + if (info->fMask & MIIM_CHECKMARKS) + { + info->hbmpChecked = item->hCheckBit; + info->hbmpUnchecked = item->hUnCheckBit; + } + + release_menu_ptr( menu ); + return TRUE; +} + /********************************************************************** * NtUserThunkedMenuItemInfo (win32u.@) */ @@ -1004,6 +1121,12 @@ UINT WINAPI NtUserThunkedMenuItemInfo( HMENU handle, UINT pos, UINT flags, UINT
switch (method) { + case NtUserGetMenuItemInfoA: + return get_menu_item_info( handle, pos, flags, info, TRUE ); + + case NtUserGetMenuItemInfoW: + return get_menu_item_info( handle, pos, flags, info, FALSE ); + case NtUserInsertMenuItem: if (!info || info->cbSize != sizeof(*info)) { diff --git a/include/ntuser.h b/include/ntuser.h index 6e6819038ac..d92332f13b9 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -224,6 +224,8 @@ enum NtUserSetMenuItemInfo, NtUserInsertMenuItem, /* Wine extensions */ + NtUserGetMenuItemInfoA, + NtUserGetMenuItemInfoW, NtUserGetMenuState, };
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/menu.c | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index df260b063d9..29a266d2312 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -476,42 +476,21 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UINT pos, LPCWSTR data, /******************************************************************* * GetMenuStringA (USER32.@) */ -INT WINAPI GetMenuStringA( - HMENU hMenu, /* [in] menuhandle */ - UINT wItemID, /* [in] menu item (dep. on wFlags) */ - LPSTR str, /* [out] outbuffer. If NULL, func returns entry length*/ - INT nMaxSiz, /* [in] length of buffer. if 0, func returns entry len*/ - UINT wFlags /* [in] MF_ flags */ -) +INT WINAPI GetMenuStringA( HMENU menu, UINT item, char *str, INT count, UINT flags ) { - POPUPMENU *menu; - MENUITEM *item; - UINT pos; - INT ret; - - TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags ); - if (str && nMaxSiz) str[0] = '\0'; - - if (!(menu = find_menu_item(hMenu, wItemID, wFlags, &pos))) - { - SetLastError( ERROR_MENU_ITEM_NOT_FOUND); - return 0; - } - item = &menu->items[pos]; + MENUITEMINFOA info; + int ret;
- if (!item->text) - ret = 0; - else if (!str || !nMaxSiz) - ret = WideCharToMultiByte( CP_ACP, 0, item->text, -1, NULL, 0, NULL, NULL ); - else - { - if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1, str, nMaxSiz, NULL, NULL )) - str[nMaxSiz-1] = 0; - ret = strlen(str); - } - release_menu_ptr(menu); + TRACE( "menu=%p item=%04x ptr=%p len=%d flags=%04x\n", menu, item, str, count, flags );
- TRACE("returning %s\n", debugstr_a(str)); + info.cbSize = sizeof(info); + info.fMask = MIIM_STRING; + info.dwTypeData = str; + info.cch = count; + ret = NtUserThunkedMenuItemInfo( menu, item, flags, NtUserGetMenuItemInfoA, + (MENUITEMINFOW *)&info, NULL ); + if (ret) ret = info.cch; + TRACE( "returning %s %d\n", debugstr_a( str ), ret ); return ret; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117390
Your paranoid android.
=== debian11 (32 bit report) ===
user32: msg.c:6881: Test failed: SetFocus(hwnd) on a button: 9: the msg sequence is not complete: expected 0000 - actual 0009
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/menu.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 29a266d2312..434353e8892 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -498,39 +498,20 @@ INT WINAPI GetMenuStringA( HMENU menu, UINT item, char *str, INT count, UINT fla /******************************************************************* * GetMenuStringW (USER32.@) */ -INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID, - LPWSTR str, INT nMaxSiz, UINT wFlags ) +INT WINAPI GetMenuStringW( HMENU menu, UINT item, WCHAR *str, INT count, UINT flags ) { - POPUPMENU *menu; - MENUITEM *item; - UINT pos; - INT ret; - - TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags ); - if (str && nMaxSiz) str[0] = '\0'; - - if (!(menu = find_menu_item(hMenu, wItemID, wFlags, &pos))) - { - SetLastError( ERROR_MENU_ITEM_NOT_FOUND); - return 0; - } - item = &menu->items[pos]; + MENUITEMINFOW info; + int ret;
- if (!str || !nMaxSiz) - ret = item->text ? lstrlenW(item->text) : 0; - else if (!item->text) - { - str[0] = 0; - ret = 0; - } - else - { - lstrcpynW( str, item->text, nMaxSiz ); - ret = lstrlenW(str); - } - release_menu_ptr(menu); + TRACE( "menu=%p item=%04x ptr=%p len=%d flags=%04x\n", menu, item, str, count, flags );
- TRACE("returning %s\n", debugstr_w(str)); + info.cbSize = sizeof(info); + info.fMask = MIIM_STRING; + info.dwTypeData = str; + info.cch = count; + ret = NtUserThunkedMenuItemInfo( menu, item, flags, NtUserGetMenuItemInfoW, &info, NULL ); + if (ret) ret = info.cch; + TRACE( "returning %s %d\n", debugstr_w( str ), ret ); return ret; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117391
Your paranoid android.
=== debian11 (32 bit WoW report) ===
user32: win.c:10976: Test failed: Expected foreground window 0, got 02A6009A win.c:10982: Test failed: Expected foreground window 001A0124, got 02A6009A win.c:11011: Test failed: Expected foreground window 001A0124, got 02A6009A win.c:11018: Test failed: Expected foreground window 001A0124, got 02A6009A win.c:11020: Test failed: GetActiveWindow() = 00000000 win.c:11020: Test failed: GetFocus() = 00000000 win.c:11021: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/menu.c | 12 ++---------- dlls/win32u/menu.c | 6 ++++++ include/ntuser.h | 1 + 3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 434353e8892..76144706771 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -537,17 +537,9 @@ INT WINAPI GetMenuItemCount( HMENU menu ) /********************************************************************** * GetMenuItemID (USER32.@) */ -UINT WINAPI GetMenuItemID( HMENU hMenu, INT nPos ) +UINT WINAPI GetMenuItemID( HMENU menu, INT pos ) { - POPUPMENU *menu; - UINT id, pos; - - if (!(menu = find_menu_item(hMenu, nPos, MF_BYPOSITION, &pos))) - return -1; - - id = menu->items[pos].fType & MF_POPUP ? -1 : menu->items[pos].wID; - release_menu_ptr(menu); - return id; + return NtUserThunkedMenuItemInfo( menu, pos, MF_BYPOSITION, NtUserGetMenuItemID, NULL, NULL ); }
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index ca2c018f7e1..5bb76520d9b 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -1121,6 +1121,12 @@ UINT WINAPI NtUserThunkedMenuItemInfo( HMENU handle, UINT pos, UINT flags, UINT
switch (method) { + case NtUserGetMenuItemID: + if (!(menu = find_menu_item( handle, pos, flags, &i ))) return -1; + ret = menu->items[i].fType & MF_POPUP ? -1 : menu->items[i].wID; + release_menu_ptr( menu ); + break; + case NtUserGetMenuItemInfoA: return get_menu_item_info( handle, pos, flags, info, TRUE );
diff --git a/include/ntuser.h b/include/ntuser.h index d92332f13b9..41b328376a9 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -224,6 +224,7 @@ enum NtUserSetMenuItemInfo, NtUserInsertMenuItem, /* Wine extensions */ + NtUserGetMenuItemID, NtUserGetMenuItemInfoA, NtUserGetMenuItemInfoW, NtUserGetMenuState,