server: Allow to send a name instead of an atom when creating a window class.

This commit is contained in:
Alexandre Julliard 2007-11-01 13:02:01 +01:00
parent bfe88a00f8
commit 0762d98f7c
5 changed files with 63 additions and 35 deletions

View File

@ -295,16 +295,15 @@ static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
* CLASS_RegisterClass
*
* The real RegisterClass() functionality.
* The atom is deleted no matter what.
*/
static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
static CLASS *CLASS_RegisterClass( LPCWSTR name, HINSTANCE hInstance, BOOL local,
DWORD style, INT classExtra, INT winExtra )
{
CLASS *classPtr;
BOOL ret;
TRACE("atom=0x%x hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
atom, hInstance, style, classExtra, winExtra );
TRACE("name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
debugstr_w(name), hInstance, style, classExtra, winExtra );
/* Fix the extra bytes value */
@ -319,25 +318,22 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
WARN("Win extra bytes %d is > 40\n", winExtra );
classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
if (!classPtr)
{
GlobalDeleteAtom( atom );
return NULL;
}
if (!classPtr) return NULL;
SERVER_START_REQ( create_class )
{
req->local = local;
req->atom = atom;
req->style = style;
req->instance = hInstance;
req->extra = classExtra;
req->win_extra = winExtra;
req->client_ptr = classPtr;
if (IS_INTRESOURCE(name)) req->atom = LOWORD(name);
else wine_server_add_data( req, name, strlenW(name) * sizeof(WCHAR) );
ret = !wine_server_call_err( req );
classPtr->atomName = reply->atom;
}
SERVER_END_REQ;
GlobalDeleteAtom( atom ); /* the server increased the atom ref count */
if (!ret)
{
HeapFree( GetProcessHeap(), 0, classPtr );
@ -349,7 +345,6 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
classPtr->cbWndExtra = winExtra;
classPtr->cbClsExtra = classExtra;
classPtr->hInstance = hInstance;
classPtr->atomName = atom;
/* Other non-null values must be set by caller */
@ -368,12 +363,9 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, BOOL local,
*/
static WNDPROC register_builtin( const struct builtin_class_descr *descr )
{
ATOM atom;
CLASS *classPtr;
if (!(atom = GlobalAddAtomW( descr->name ))) return 0;
if (!(classPtr = CLASS_RegisterClass( atom, user32_module, FALSE,
if (!(classPtr = CLASS_RegisterClass( descr->name, user32_module, FALSE,
descr->style, 0, descr->extra ))) return 0;
classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor );
@ -506,14 +498,25 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
}
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
if (!IS_INTRESOURCE(wc->lpszClassName))
{
WCHAR name[MAX_ATOM_LEN + 1];
if (!(classPtr = CLASS_RegisterClass( atom, instance, !(wc->style & CS_GLOBALCLASS),
wc->style, wc->cbClsExtra, wc->cbWndExtra )))
return 0;
if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, name, MAX_ATOM_LEN + 1 )) return 0;
classPtr = CLASS_RegisterClass( name, instance, !(wc->style & CS_GLOBALCLASS),
wc->style, wc->cbClsExtra, wc->cbWndExtra );
}
else
{
classPtr = CLASS_RegisterClass( (LPCWSTR)wc->lpszClassName, instance,
!(wc->style & CS_GLOBALCLASS), wc->style,
wc->cbClsExtra, wc->cbWndExtra );
}
if (!classPtr) return 0;
atom = classPtr->atomName;
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
atom, wc->lpfnWndProc, instance, wc->hbrBackground,
TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
debugstr_a(wc->lpszClassName), atom, wc->lpfnWndProc, instance, wc->hbrBackground,
wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
classPtr->hIcon = wc->hIcon;
@ -544,14 +547,14 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
}
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
if (!(classPtr = CLASS_RegisterClass( atom, instance, !(wc->style & CS_GLOBALCLASS),
if (!(classPtr = CLASS_RegisterClass( wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS),
wc->style, wc->cbClsExtra, wc->cbWndExtra )))
return 0;
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
atom, wc->lpfnWndProc, instance, wc->hbrBackground,
atom = classPtr->atomName;
TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
debugstr_w(wc->lpszClassName), atom, wc->lpfnWndProc, instance, wc->hbrBackground,
wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
classPtr->hIcon = wc->hIcon;

View File

@ -3594,10 +3594,12 @@ struct create_class_request
int extra;
int win_extra;
void* client_ptr;
/* VARARG(name,unicode_str); */
};
struct create_class_reply
{
struct reply_header __header;
atom_t atom;
};
@ -4880,6 +4882,6 @@ union generic_reply
struct set_completion_info_reply set_completion_info_reply;
};
#define SERVER_PROTOCOL_VERSION 324
#define SERVER_PROTOCOL_VERSION 325
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -142,32 +142,45 @@ void *get_class_client_ptr( struct window_class *class )
DECL_HANDLER(create_class)
{
struct window_class *class;
atom_t atom;
class = find_class( current->process, req->atom, req->instance );
if (get_req_data_size())
{
atom = add_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
if (!atom) return;
}
else
{
atom = req->atom;
if (!grab_global_atom( NULL, atom )) return;
}
class = find_class( current->process, atom, req->instance );
if (class && !class->local == !req->local)
{
set_win32_error( ERROR_CLASS_ALREADY_EXISTS );
release_global_atom( NULL, atom );
return;
}
if (req->extra < 0 || req->extra > 4096 || req->win_extra < 0 || req->win_extra > 4096)
{
/* don't allow stupid values here */
set_error( STATUS_INVALID_PARAMETER );
release_global_atom( NULL, atom );
return;
}
if (!grab_global_atom( NULL, req->atom )) return;
if (!(class = create_class( current->process, req->extra, req->local )))
{
release_global_atom( NULL, req->atom );
release_global_atom( NULL, atom );
return;
}
class->atom = req->atom;
class->atom = atom;
class->instance = req->instance;
class->style = req->style;
class->win_extra = req->win_extra;
class->client_ptr = req->client_ptr;
reply->atom = atom;
}
/* destroy a window class */

View File

@ -2600,6 +2600,9 @@ enum message_type
int extra; /* number of extra class bytes */
int win_extra; /* number of window extra bytes */
void* client_ptr; /* pointer to class in client address space */
VARARG(name,unicode_str); /* class name */
@REPLY
atom_t atom; /* resulting class atom */
@END

View File

@ -3192,7 +3192,14 @@ static void dump_create_class_request( const struct create_class_request *req )
fprintf( stderr, " instance=%p,", req->instance );
fprintf( stderr, " extra=%d,", req->extra );
fprintf( stderr, " win_extra=%d,", req->win_extra );
fprintf( stderr, " client_ptr=%p", req->client_ptr );
fprintf( stderr, " client_ptr=%p,", req->client_ptr );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
}
static void dump_create_class_reply( const struct create_class_reply *req )
{
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_destroy_class_request( const struct destroy_class_request *req )
@ -4106,7 +4113,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_start_hook_chain_reply,
(dump_func)0,
(dump_func)dump_get_hook_info_reply,
(dump_func)0,
(dump_func)dump_create_class_reply,
(dump_func)dump_destroy_class_reply,
(dump_func)dump_set_class_info_reply,
(dump_func)dump_set_clipboard_info_reply,