Jacek Caban : user32: Introduce get_class_info.

Alexandre Julliard julliard at winehq.org
Mon Mar 7 16:04:56 CST 2022


Module: wine
Branch: master
Commit: 5e75e5f66dc638ef9684f949e32a17a9df43fcdb
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5e75e5f66dc638ef9684f949e32a17a9df43fcdb

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar  7 14:41:03 2022 +0100

user32: Introduce get_class_info.

And use it in WIN_CreateWindowEx to trigger class registration.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/class.c        | 42 ++++++++++++++++++++++++++++++++++--------
 dlls/user32/user_private.h |  3 +--
 dlls/user32/win.c          | 29 +++++++++++------------------
 3 files changed, 46 insertions(+), 28 deletions(-)

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 */




More information about the wine-cvs mailing list