server: Allow to specify the class name instead of the atom to create a window.
diff --git a/dlls/user32/class.c b/dlls/user32/class.c
index 9a1dd2f..2119de9 100644
--- a/dlls/user32/class.c
+++ b/dlls/user32/class.c
@@ -101,7 +101,7 @@
/***********************************************************************
* get_int_atom_value
*/
-static ATOM get_int_atom_value( LPCWSTR name )
+ATOM get_int_atom_value( LPCWSTR name )
{
UINT ret = 0;
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index d52c914..c5c5e35 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -48,6 +48,7 @@
/* Class functions */
struct tagCLASS; /* opaque structure */
struct tagWND;
+extern ATOM get_int_atom_value( LPCWSTR name );
extern void CLASS_RegisterBuiltinClasses(void);
extern void CLASS_AddWindow( struct tagCLASS *class, struct tagWND *win, BOOL unicode );
extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index f6f0512..023115e 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -95,7 +95,7 @@
*
* Create a window handle with the server.
*/
-static WND *create_window_handle( HWND parent, HWND owner, ATOM atom,
+static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
HINSTANCE instance, BOOL unicode )
{
WORD index;
@@ -113,8 +113,9 @@
{
req->parent = parent;
req->owner = owner;
- req->atom = atom;
req->instance = instance;
+ if (!(req->atom = get_int_atom_value( name )) && name)
+ wine_server_add_data( req, name, strlenW(name)*sizeof(WCHAR) );
if (!wine_server_call_err( req ))
{
handle = reply->handle;
@@ -857,7 +858,7 @@
*
* Implementation of CreateWindowEx().
*/
-static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, UINT flags )
+static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags )
{
INT sw = SW_SHOW;
WND *wndPtr;
@@ -867,7 +868,7 @@
TRACE("%s %s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
unicode ? debugstr_w((LPCWSTR)cs->lpszName) : debugstr_a(cs->lpszName),
- unicode ? debugstr_w((LPCWSTR)cs->lpszClass) : debugstr_a(cs->lpszClass),
+ debugstr_w(className),
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 );
@@ -968,7 +969,7 @@
SetLastError(ERROR_TLW_WITH_WSCHILD);
return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
}
- if (classAtom != LOWORD(DESKTOP_CLASS_ATOM)) /* are we creating the desktop itself? */
+ if (className != (LPCWSTR)DESKTOP_CLASS_ATOM) /* are we creating the desktop itself? */
parent = GetDesktopWindow();
}
@@ -983,7 +984,7 @@
/* Create the window structure */
- if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, unicode )))
+ if (!(wndPtr = create_window_handle( parent, owner, className, cs->hInstance, unicode )))
return 0;
hwnd = wndPtr->hwndSelf;
@@ -1135,31 +1136,9 @@
HWND16 parent, HMENU16 menu,
HINSTANCE16 instance, LPVOID data )
{
- ATOM classAtom;
CREATESTRUCTA cs;
char buffer[256];
- /* Find the class atom */
-
- if (HIWORD(className))
- {
- if (!(classAtom = GlobalFindAtomA( className )))
- {
- ERR( "bad class name %s\n", debugstr_a(className) );
- return 0;
- }
- }
- else
- {
- classAtom = LOWORD(className);
- if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
- {
- ERR( "bad atom %x\n", classAtom);
- return 0;
- }
- className = buffer;
- }
-
/* Fix the coordinates */
cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
@@ -1178,7 +1157,24 @@
cs.lpszClass = className;
cs.dwExStyle = exStyle;
- return HWND_16( WIN_CreateWindowEx( &cs, classAtom, 0 ));
+ if (!IS_INTRESOURCE(className))
+ {
+ WCHAR bufferW[256];
+
+ if (!MultiByteToWideChar( CP_ACP, 0, className, -1, bufferW, sizeof(bufferW)/sizeof(WCHAR) ))
+ return 0;
+ return HWND_16( WIN_CreateWindowEx( &cs, bufferW, 0 ));
+ }
+ else
+ {
+ if (!GlobalGetAtomNameA( LOWORD(className), buffer, sizeof(buffer) ))
+ {
+ ERR( "bad atom %x\n", LOWORD(className));
+ return 0;
+ }
+ cs.lpszClass = buffer;
+ return HWND_16( WIN_CreateWindowEx( &cs, (LPCWSTR)className, 0 ));
+ }
}
@@ -1191,32 +1187,7 @@
HWND parent, HMENU menu,
HINSTANCE instance, LPVOID data )
{
- ATOM classAtom;
CREATESTRUCTA cs;
- char buffer[256];
-
- /* Find the class atom */
-
- if (HIWORD(className))
- {
- if (!(classAtom = GlobalFindAtomA( className )))
- {
- ERR( "bad class name %s\n", debugstr_a(className) );
- return 0;
- }
- }
- else
- {
- classAtom = LOWORD(className);
- if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
- {
- ERR( "bad atom %x\n", classAtom);
- return 0;
- }
- className = buffer;
- }
-
- /* Create the window */
cs.lpCreateParams = data;
cs.hInstance = instance;
@@ -1231,7 +1202,14 @@
cs.lpszClass = className;
cs.dwExStyle = exStyle;
- return WIN_CreateWindowEx( &cs, classAtom, WIN_ISWIN32 );
+ if (!IS_INTRESOURCE(className))
+ {
+ WCHAR bufferW[256];
+ if (!MultiByteToWideChar( CP_ACP, 0, className, -1, bufferW, sizeof(bufferW)/sizeof(WCHAR) ))
+ return 0;
+ return WIN_CreateWindowEx( &cs, bufferW, WIN_ISWIN32 );
+ }
+ return WIN_CreateWindowEx( &cs, (LPCWSTR)className, WIN_ISWIN32 );
}
@@ -1244,32 +1222,7 @@
HWND parent, HMENU menu,
HINSTANCE instance, LPVOID data )
{
- ATOM classAtom;
CREATESTRUCTW cs;
- WCHAR buffer[256];
-
- /* Find the class atom */
-
- if (HIWORD(className))
- {
- if (!(classAtom = GlobalFindAtomW( className )))
- {
- ERR( "bad class name %s\n", debugstr_w(className) );
- return 0;
- }
- }
- else
- {
- classAtom = LOWORD(className);
- if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
- {
- ERR( "bad atom %x\n", classAtom);
- return 0;
- }
- className = buffer;
- }
-
- /* Create the window */
cs.lpCreateParams = data;
cs.hInstance = instance;
@@ -1286,7 +1239,7 @@
/* Note: we rely on the fact that CREATESTRUCTA and */
/* CREATESTRUCTW have the same layout. */
- return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, WIN_ISWIN32 | WIN_ISUNICODE );
+ return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, className, WIN_ISWIN32 | WIN_ISUNICODE );
}
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 8d1485e..1643070 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2746,6 +2746,7 @@
user_handle_t owner;
atom_t atom;
void* instance;
+ /* VARARG(class,unicode_str); */
};
struct create_window_reply
{
@@ -4883,6 +4884,6 @@
struct set_completion_info_reply set_completion_info_reply;
};
-#define SERVER_PROTOCOL_VERSION 326
+#define SERVER_PROTOCOL_VERSION 327
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index f2e33ef..5cb951d 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2030,6 +2030,7 @@
user_handle_t owner; /* owner window */
atom_t atom; /* class atom */
void* instance; /* module instance */
+ VARARG(class,unicode_str); /* class name */
@REPLY
user_handle_t handle; /* created window */
user_handle_t parent; /* full handle of parent */
diff --git a/server/trace.c b/server/trace.c
index a6d3ee5..2460cde 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2526,7 +2526,9 @@
fprintf( stderr, " parent=%p,", req->parent );
fprintf( stderr, " owner=%p,", req->owner );
fprintf( stderr, " atom=%04x,", req->atom );
- fprintf( stderr, " instance=%p", req->instance );
+ fprintf( stderr, " instance=%p,", req->instance );
+ fprintf( stderr, " class=" );
+ dump_varargs_unicode_str( cur_size );
}
static void dump_create_window_reply( const struct create_window_reply *req )
diff --git a/server/window.c b/server/window.c
index ae24bd6..3e8219b 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1561,6 +1561,7 @@
DECL_HANDLER(create_window)
{
struct window *win, *parent, *owner = NULL;
+ atom_t atom;
reply->handle = 0;
@@ -1580,7 +1581,13 @@
else /* owner must be a top-level window */
while (!is_desktop_window(owner->parent)) owner = owner->parent;
}
- if (!(win = create_window( parent, owner, req->atom, req->instance ))) return;
+
+ if (get_req_data_size())
+ atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
+ else
+ atom = req->atom;
+
+ if (!(win = create_window( parent, owner, atom, req->instance ))) return;
reply->handle = win->handle;
reply->parent = win->parent ? win->parent->handle : 0;