server: Allow to specify the class name instead of the atom to create a window.

This commit is contained in:
Alexandre Julliard 2007-11-02 15:16:25 +01:00
parent beab2c17e9
commit 1fc461f98b
7 changed files with 50 additions and 85 deletions

View File

@ -101,7 +101,7 @@ static inline void release_class_ptr( CLASS *ptr )
/***********************************************************************
* get_int_atom_value
*/
static ATOM get_int_atom_value( LPCWSTR name )
ATOM get_int_atom_value( LPCWSTR name )
{
UINT ret = 0;

View File

@ -48,6 +48,7 @@ extern WNDPROC EDIT_winproc_handle;
/* 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 );

View File

@ -95,7 +95,7 @@ static void *user_handles[NB_USER_HANDLES];
*
* 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 @@ static WND *create_window_handle( HWND parent, HWND owner, ATOM atom,
{
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 @@ static void dump_window_styles( DWORD style, DWORD exstyle )
*
* 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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, UINT flags )
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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, UINT flags )
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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, UINT flags )
/* 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 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
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 @@ HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
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 WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
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 @@ HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
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 WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
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 @@ HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
/* 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 );
}

View File

@ -2746,6 +2746,7 @@ struct create_window_request
user_handle_t owner;
atom_t atom;
void* instance;
/* VARARG(class,unicode_str); */
};
struct create_window_reply
{
@ -4883,6 +4884,6 @@ union generic_reply
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 */

View File

@ -2030,6 +2030,7 @@ enum message_type
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 */

View File

@ -2526,7 +2526,9 @@ static void dump_create_window_request( const struct create_window_request *req
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 )

View File

@ -1561,6 +1561,7 @@ static void set_window_region( struct window *win, struct region *region, int re
DECL_HANDLER(create_window)
{
struct window *win, *parent, *owner = NULL;
atom_t atom;
reply->handle = 0;
@ -1580,7 +1581,13 @@ DECL_HANDLER(create_window)
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;