From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/user32/static.c | 1 + dlls/win32u/class.c | 30 +++++++++++++++++++++++++++--- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/tests/win32u.c | 4 ++-- dlls/win32u/window.c | 23 +++++++++++++++++++++++ include/ntuser.h | 13 +++++++++++++ 6 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/static.c b/dlls/user32/static.c index f3953f7610a..431381e3421 100644 --- a/dlls/user32/static.c +++ b/dlls/user32/static.c @@ -324,6 +324,7 @@ LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam LONG style = full_style & SS_TYPEMASK;
if (!IsWindow( hwnd )) return 0; + NtUserSetRealClassId(hwnd, REAL_CLASS_ID_STATIC);
switch (uMsg) { diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 396e2285797..8e640ddb525 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -612,13 +612,18 @@ ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ) return size / sizeof(WCHAR); }
+static const WCHAR real_class_id_str[][MAX_ATOM_LEN + 1] = { + { 'S', 't', 'a', 't', 'i', 'c', 0, }, /* REAL_CLASS_ID_STATIC */ +}; + /*********************************************************************** * 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 +653,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 e1b21917682..ec051d806bd 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -254,10 +254,10 @@ static void test_class(void) name.Length = 0xdead; name.MaximumLength = sizeof(buf); ret = NtUserGetClassName( hwnd, TRUE, &name ); - todo_wine ok( ret == 6, "NtUserGetClassName returned %lu\n", ret ); + ok( ret == 6, "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"Static" ), "buf = %s\n", debugstr_w(buf) ); + ok( !wcscmp( buf, L"Static" ), "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..412f1d73bd2 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -4491,6 +4491,26 @@ 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) return FALSE; + if (win == WND_OTHER_PROCESS || win == WND_DESKTOP) + { + ERR("Tried to set real window class on 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.@) */ @@ -5588,6 +5608,9 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) case NtUserCallHwndParam_ShowOwnedPopups: return show_owned_popups( hwnd, param );
+ case NtUserCallHwndParam_SetRealClassId: + return set_real_window_class_id( hwnd, param ); + /* temporary exports */ case NtUserSetWindowStyle: { diff --git a/include/ntuser.h b/include/ntuser.h index 171d32abe6e..1b3fc943a07 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -513,6 +513,13 @@ 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_STATIC, +}; +
HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ); BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd ); @@ -1208,6 +1215,7 @@ enum NtUserCallHwndParam_SetMDIClientInfo, NtUserCallHwndParam_SetWindowContextHelpId, NtUserCallHwndParam_ShowOwnedPopups, + NtUserCallHwndParam_SetRealClassId, /* temporary exports */ NtUserSetWindowStyle, }; @@ -1378,6 +1386,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 );