From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/user32/button.c | 1 + dlls/user32/combo.c | 1 + dlls/user32/defdlg.c | 2 ++ dlls/user32/edit.c | 1 + dlls/user32/listbox.c | 1 + dlls/user32/mdi.c | 1 + dlls/user32/menu.c | 4 +++- dlls/user32/scroll.c | 4 +++- dlls/user32/static.c | 1 + dlls/win32u/class.c | 38 +++++++++++++++++++++++++++++++++--- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/tests/win32u.c | 2 +- dlls/win32u/window.c | 22 +++++++++++++++++++++ include/ntuser.h | 21 ++++++++++++++++++++ 14 files changed, 94 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/button.c b/dlls/user32/button.c index 10a111562a7..24d5ac843e2 100644 --- a/dlls/user32/button.c +++ b/dlls/user32/button.c @@ -202,6 +202,7 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, WIN_SetStyle( hWnd, style, BS_TYPEMASK & ~style ); } set_button_state( hWnd, BST_UNCHECKED ); + NtUserSetRealClassId( hWnd, REAL_CLASS_ID_BUTTON ); return 0;
case WM_ERASEBKGND: diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c index 6afd841f82a..73fa2422e52 100644 --- a/dlls/user32/combo.c +++ b/dlls/user32/combo.c @@ -537,6 +537,7 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG CBForceDummyResize(lphc); }
+ NtUserSetRealClassId(hwnd, REAL_CLASS_ID_COMBOBOX); TRACE("init done\n"); return 0; } diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c index 88b64ee469c..c6462c0b879 100644 --- a/dlls/user32/defdlg.c +++ b/dlls/user32/defdlg.c @@ -416,6 +416,8 @@ static LRESULT USER_DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar
LRESULT WINAPI USER_DefDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode ) { + if (msg == WM_CREATE) + NtUserSetRealClassId( hwnd, REAL_CLASS_ID_DIALOG ); if (unicode) return USER_DefDlgProcW( hwnd, msg, wParam, lParam ); else diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 39f429813d6..59459d41658 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -4928,6 +4928,7 @@ LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, B result = EDIT_WM_Create(es, nameW); HeapFree(GetProcessHeap(), 0, nameW); } + NtUserSetRealClassId(hwnd, REAL_CLASS_ID_EDIT); break;
case WM_CUT: diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c index 0e925973e84..3dc1e54e91d 100644 --- a/dlls/user32/listbox.c +++ b/dlls/user32/listbox.c @@ -2652,6 +2652,7 @@ LRESULT ListBoxWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam CREATESTRUCTW *lpcs = (CREATESTRUCTW *)lParam; if (lpcs->style & LBS_COMBOBOX) lphc = lpcs->lpCreateParams; if (!LISTBOX_Create( hwnd, lphc )) return -1; + NtUserSetRealClassId( hwnd, REAL_CLASS_ID_LISTBOX ); TRACE("creating hwnd %p descr %p\n", hwnd, (void *)GetWindowLongPtrW( hwnd, 0 ) ); return 0; } diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c index f579298544a..a45ab3383f2 100644 --- a/dlls/user32/mdi.c +++ b/dlls/user32/mdi.c @@ -1025,6 +1025,7 @@ LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
if (!hBmpClose) hBmpClose = CreateMDIMenuBitmap();
+ NtUserSetRealClassId(hwnd, REAL_CLASS_ID_MDI_CLIENT); TRACE("Client created: hwnd %p, Window menu %p, idFirst = %04x\n", hwnd, ci->hWindowMenu, ci->idFirstChild ); return 0; diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 4ba6fa71028..47457117b3a 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -192,8 +192,10 @@ LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM { switch(message) { - case WM_DESTROY: case WM_CREATE: + NtUserSetRealClassId( hwnd, REAL_CLASS_ID_MENU ); + /* Fall through. */ + case WM_DESTROY: case WM_MOUSEACTIVATE: case WM_PAINT: case WM_PRINTCLIENT: diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 788b5091698..b1f460c032f 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -237,6 +237,9 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA { switch(message) { + case WM_CREATE: + NtUserSetRealClassId( hwnd, REAL_CLASS_ID_SCROLLBAR ); + /* Fall through. */ case WM_KEYDOWN: case WM_KEYUP: case WM_ENABLE: @@ -250,7 +253,6 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA case WM_SYSTIMER: case WM_SETFOCUS: case WM_KILLFOCUS: - case WM_CREATE: case WM_ERASEBKGND: case WM_GETDLGCODE: case WM_PAINT: diff --git a/dlls/user32/static.c b/dlls/user32/static.c index f3953f7610a..40c2d9fbfb9 100644 --- a/dlls/user32/static.c +++ b/dlls/user32/static.c @@ -333,6 +333,7 @@ LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ERR("Unknown style 0x%02lx\n", style ); return -1; } + NtUserSetRealClassId(hwnd, REAL_CLASS_ID_STATIC); STATIC_InitColours(); break;
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 396e2285797..b35618d80c2 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -612,13 +612,26 @@ ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ) return size / sizeof(WCHAR); }
+static const WCHAR real_class_id_str[][MAX_ATOM_LEN + 1] = { + { 'B', 'u', 't', 't', 'o', 'n', 0, }, /* REAL_CLASS_ID_BUTTON */ + { 'C', 'o', 'm', 'b', 'o', 'B', 'o', 'x', 0, }, /* REAL_CLASS_ID_COMBOBOX */ + { 'E', 'd', 'i', 't', 0, }, /* REAL_CLASS_ID_EDIT */ + { 'L', 'i', 's', 't', 'B', 'o', 'x', 0, }, /* REAL_CLASS_ID_LISTBOX */ + { 'S', 'c', 'r', 'o', 'l', 'l', 'B', 'a', 'r', 0, }, /* REAL_CLASS_ID_SCROLLBAR */ + { 'S', 't', 'a', 't', 'i', 'c', 0, }, /* REAL_CLASS_ID_STATIC */ + { 'M', 'D', 'I', 'C', 'l', 'i', 'e', 'n', 't', 0, }, /* REAL_CLASS_ID_MDI_CLIENT */ + { '#', '3', '2', '7', '6', '8', 0, }, /* REAL_CLASS_ID_MENU */ + { '#', '3', '2', '7', '7', '0', 0, }, /* REAL_CLASS_ID_DIALOG */ +}; + /*********************************************************************** * NtUserGetClassName (win32u.@) */ INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name ) { + const WCHAR *basename = NULL; CLASS *class; - int ret; + int ret = 0;
TRACE( "%p %x %p\n", hwnd, real, name );
@@ -648,9 +661,28 @@ INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name ) return NtUserGetAtomName( atom, name ); }
- ret = min( name->MaximumLength / sizeof(WCHAR) - 1, lstrlenW(class->basename) ); - if (ret) memcpy( name->Buffer, class->basename, ret * sizeof(WCHAR) ); + if (real) + { + WND *wnd; + + if (!(wnd = get_win_ptr( hwnd ))) + { + RtlSetLastWin32Error( ERROR_INVALID_WINDOW_HANDLE ); + goto exit; + } + + if (wnd->real_class_id) + basename = real_class_id_str[wnd->real_class_id - 1]; + release_win_ptr(wnd); + } + + if (!basename) + basename = (const WCHAR *)class->basename; + + ret = min( name->MaximumLength / sizeof(WCHAR) - 1, lstrlenW(basename) ); + if (ret) memcpy( name->Buffer, basename, ret * sizeof(WCHAR) ); name->Buffer[ret] = 0; +exit: release_class_ptr( class ); return ret; } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index b39e38db5d6..3b861f0200a 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -86,6 +86,7 @@ typedef struct tagWND struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */ int pixel_format; /* Pixel format set by the graphics driver */ int internal_pixel_format; /* Internal pixel format set via WGL_WINE_pixel_format_passthrough */ + unsigned int real_class_id; /* "Real" window class ID, set by user32 standard control window procedures. */ int cbWndExtra; /* class cbWndExtra at window creation */ DWORD_PTR userdata; /* User private data */ DWORD wExtra[1]; /* Window extra bytes */ diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 1d70eb9fbb0..e2a84f448ab 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -255,7 +255,7 @@ static void test_class(void) ok( ret == 4, "NtUserGetClassName returned %lu\n", ret ); ok( name.Length == 0xdead, "Length = %u\n", name.Length ); ok( name.MaximumLength == sizeof(buf), "MaximumLength = %u\n", name.MaximumLength ); - todo_wine ok( !wcscmp( buf, L"Edit" ), "buf = %s\n", debugstr_w(buf) ); + ok( !wcscmp( buf, L"Edit" ), "buf = %s\n", debugstr_w(buf) );
/* Get normal class instead of real class. */ memset( buf, 0xcc, sizeof(buf) ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4a57e0abde7..ae9a24125e5 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -4491,6 +4491,25 @@ BOOL show_owned_popups( HWND owner, BOOL show ) return TRUE; }
+static BOOL set_real_window_class_id( HWND hwnd, DWORD param ) +{ + WND *win = get_win_ptr( hwnd ); + + if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) + { + ERR("Can't set real window class for a window belonging to another process\n"); + return FALSE; + } + + if (!win->real_class_id) + { + FIXME("Real class ID currently set in-process only.\n"); + win->real_class_id = param; + } + release_win_ptr( win ); + return TRUE; +} + /******************************************************************* * NtUserFlashWindowEx (win32u.@) */ @@ -5595,6 +5614,9 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) return set_window_style( hwnd, style->styleNew, style->styleOld ); }
+ case NtUserCallHwndParam_SetRealClassId: + return set_real_window_class_id( hwnd, param ); + default: FIXME( "invalid code %u\n", (int)code ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 171d32abe6e..f9211277eee 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -513,6 +513,21 @@ struct ime_driver_call_params
#define WM_SYSTIMER 0x0118
+/* Internal real window class ID values. */ +enum wine_real_class_id +{ + REAL_CLASS_ID_NONE = 0, + REAL_CLASS_ID_BUTTON, + REAL_CLASS_ID_COMBOBOX, + REAL_CLASS_ID_EDIT, + REAL_CLASS_ID_LISTBOX, + REAL_CLASS_ID_SCROLLBAR, + REAL_CLASS_ID_STATIC, + REAL_CLASS_ID_MDI_CLIENT, + REAL_CLASS_ID_MENU, + REAL_CLASS_ID_DIALOG, +}; +
HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ); BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd ); @@ -1208,6 +1223,7 @@ enum NtUserCallHwndParam_SetMDIClientInfo, NtUserCallHwndParam_SetWindowContextHelpId, NtUserCallHwndParam_ShowOwnedPopups, + NtUserCallHwndParam_SetRealClassId, /* temporary exports */ NtUserSetWindowStyle, }; @@ -1378,6 +1394,11 @@ static inline BOOL NtUserShowOwnedPopups( HWND hwnd, BOOL show ) return NtUserCallHwndParam( hwnd, show, NtUserCallHwndParam_ShowOwnedPopups ); }
+static inline BOOL NtUserSetRealClassId( HWND hwnd, DWORD real_class_id ) +{ + return NtUserCallHwndParam( hwnd, real_class_id, NtUserCallHwndParam_SetRealClassId ); +} + /* Wine extensions */ BOOL WINAPI __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput );