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