diff --git a/dlls/user32/class.c b/dlls/user32/class.c index 31b02e4658f..647a6b9b2bf 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -211,6 +211,16 @@ static BOOL set_server_info( HWND hwnd, INT offset, LONG_PTR newval, UINT size ) } +static void init_class_name( UNICODE_STRING *str, const WCHAR *name ) +{ + if (IS_INTRESOURCE( name )) + { + str->Buffer = (WCHAR *)name; + str->Length = str->MaximumLength = 0; + } + else RtlInitUnicodeString( str, name ); +} + /*********************************************************************** * CLASS_GetMenuNameA * @@ -253,7 +263,6 @@ static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name ) else classPtr->menuName = (LPWSTR)name; } - /*********************************************************************** * CLASS_SetMenuNameW * @@ -313,7 +322,7 @@ static CLASS *find_class( HINSTANCE module, const WCHAR *name ) { if (wcsicmp( class->name, name )) continue; } - if (!class->local || (class->instance & ~0xffff) == instance) + if (!class->local || !module || (class->instance & ~0xffff) == instance) { TRACE("%s %Ix -> %p\n", debugstr_w(name), instance, class); return class; @@ -323,7 +332,7 @@ static CLASS *find_class( HINSTANCE module, const WCHAR *name ) return NULL; } -const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, WCHAR *combined, BOOL register_class ) +static const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, WCHAR *combined, BOOL register_class ) { ACTCTX_SECTION_KEYED_DATA data; struct wndclass_redirect_data @@ -397,11 +406,12 @@ const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, W * * Return a pointer to the class. */ -static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance ) +static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance, UNICODE_STRING *name_str ) { CLASS *class; - GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */ + if (name != (LPCWSTR)DESKTOP_CLASS_ATOM && (IS_INTRESOURCE(name) || wcsicmp( name, L"Message" ))) + GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */ if (!name) return NULL; @@ -417,6 +427,7 @@ static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance ) } if (!class) TRACE("%s %p -> not found\n", debugstr_w(name), hinstance); + else if (name_str) init_class_name( name_str, name ); return class; } @@ -1253,6 +1264,21 @@ BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSW *wc ) return ret; } +ATOM get_class_info( HINSTANCE instance, const WCHAR *name, UNICODE_STRING *name_str ) +{ + CLASS *class; + ATOM atom; + + if (!(class = CLASS_FindClass( name, instance, name_str ))) + { + SetLastError( ERROR_CLASS_DOES_NOT_EXIST ); + return FALSE; + } + + atom = class->atomName; + release_class_ptr( class ); + return atom; +} /*********************************************************************** * GetClassInfoExA (USER32.@) @@ -1277,9 +1303,9 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc ) WCHAR nameW[MAX_ATOM_LEN + 1]; if (!MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, ARRAY_SIZE( nameW ))) return FALSE; - classPtr = CLASS_FindClass( nameW, hInstance ); + classPtr = CLASS_FindClass( nameW, hInstance, NULL ); } - else classPtr = CLASS_FindClass( (LPCWSTR)name, hInstance ); + else classPtr = CLASS_FindClass( (LPCWSTR)name, hInstance, NULL ); if (!classPtr) { @@ -1323,7 +1349,7 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc if (!hInstance) hInstance = user32_module; - if (!(classPtr = CLASS_FindClass( name, hInstance ))) + if (!(classPtr = CLASS_FindClass( name, hInstance, NULL ))) { SetLastError( ERROR_CLASS_DOES_NOT_EXIST ); return FALSE; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index af4b1e439b2..6dc0cf8b3a1 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -160,8 +160,7 @@ extern BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar LRESULT *result, BOOL unicode, enum wm_char_mapping mapping ) DECLSPEC_HIDDEN; extern void winproc_init(void) DECLSPEC_HIDDEN; -extern const WCHAR *CLASS_GetVersionedName(const WCHAR *classname, UINT *basename_offset, - WCHAR *combined, BOOL register_class) DECLSPEC_HIDDEN; +extern ATOM get_class_info( HINSTANCE instance, const WCHAR *name, UNICODE_STRING *name_str ) DECLSPEC_HIDDEN; /* kernel callbacks */ diff --git a/dlls/user32/win.c b/dlls/user32/win.c index c580d040bf1..341c66c3d2d 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -126,7 +126,7 @@ void *free_user_handle( HANDLE handle, unsigned int type ) * * Create a window handle with the server. */ -static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, +static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name, HINSTANCE instance, BOOL unicode, DWORD style, DWORD ex_style ) { @@ -146,8 +146,8 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, req->awareness = awareness; req->style = style; req->ex_style = ex_style; - if (!(req->atom = get_int_atom_value( name )) && name) - wine_server_add_data( req, name, lstrlenW(name)*sizeof(WCHAR) ); + if (!(req->atom = get_int_atom_value( name->Buffer )) && name->Length) + wine_server_add_data( req, name->Buffer, name->Length ); if (!wine_server_call_err( req )) { handle = wine_server_ptr_handle( reply->handle ); @@ -184,7 +184,7 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, { struct user_thread_info *thread_info = get_user_thread_info(); - if (name == (LPCWSTR)DESKTOP_CLASS_ATOM) + if (name->Buffer == (LPCWSTR)DESKTOP_CLASS_ATOM) { if (!thread_info->top_window) thread_info->top_window = full_parent ? full_parent : handle; else assert( full_parent == thread_info->top_window ); @@ -1395,18 +1395,19 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, RECT rect; WND *wndPtr; HWND hwnd, parent, owner, top_child = 0; - const WCHAR *p = className; UINT win_dpi, thread_dpi = get_thread_dpi(); DPI_AWARENESS_CONTEXT context; MDICREATESTRUCTW mdi_cs; + UNICODE_STRING class; CBT_CREATEWNDW cbtc; CREATESTRUCTW cbcs; - className = CLASS_GetVersionedName(className, NULL, NULL, TRUE); + if (!get_class_info( module, className, &class )) return FALSE; TRACE("%s %s%s%s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n", unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName), - debugstr_w(p), p != className ? "->" : "", p != className ? debugstr_w(className) : "", + debugstr_w(className), class.Buffer != className ? "->" : "", + class.Buffer != className ? debugstr_wn(class.Buffer, class.Length / sizeof(WCHAR)) : "", cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams ); if(TRACE_ON(win)) dump_window_styles( cs->style, cs->dwExStyle ); @@ -1524,17 +1525,9 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, style = cs->style & ~WS_VISIBLE; ex_style = cs->dwExStyle & ~WS_EX_LAYERED; - if (!(wndPtr = create_window_handle( parent, owner, className, module, - unicode, style, ex_style ))) - { - WNDCLASSW wc; - /* if it's a comctl32 class, GetClassInfo will load it, then we can retry */ - if (GetLastError() != ERROR_INVALID_HANDLE || - !GetClassInfoW( 0, className, &wc ) || - !(wndPtr = create_window_handle( parent, owner, className, module, - unicode, style, ex_style ))) - return 0; - } + if (!(wndPtr = create_window_handle( parent, owner, &class, module, + unicode, style, ex_style ))) + return 0; hwnd = wndPtr->obj.handle; /* Fill the window structure */