Commit bfce151a authored by Alexandre Julliard's avatar Alexandre Julliard

Added window classes in the server, and support for inter-process

GetClassWord/Long (based on a patch by Mike McCormack). Various fixes to the class instance handling.
parent 08d01923
......@@ -128,41 +128,6 @@ static BOOL load_driver(void)
/***********************************************************************
* controls_init
*
* Register the classes for the builtin controls
*/
static void controls_init(void)
{
extern const struct builtin_class_descr BUTTON_builtin_class;
extern const struct builtin_class_descr COMBO_builtin_class;
extern const struct builtin_class_descr COMBOLBOX_builtin_class;
extern const struct builtin_class_descr DIALOG_builtin_class;
extern const struct builtin_class_descr DESKTOP_builtin_class;
extern const struct builtin_class_descr EDIT_builtin_class;
extern const struct builtin_class_descr ICONTITLE_builtin_class;
extern const struct builtin_class_descr LISTBOX_builtin_class;
extern const struct builtin_class_descr MDICLIENT_builtin_class;
extern const struct builtin_class_descr MENU_builtin_class;
extern const struct builtin_class_descr SCROLL_builtin_class;
extern const struct builtin_class_descr STATIC_builtin_class;
CLASS_RegisterBuiltinClass( &BUTTON_builtin_class );
CLASS_RegisterBuiltinClass( &COMBO_builtin_class );
CLASS_RegisterBuiltinClass( &COMBOLBOX_builtin_class );
CLASS_RegisterBuiltinClass( &DIALOG_builtin_class );
CLASS_RegisterBuiltinClass( &DESKTOP_builtin_class );
CLASS_RegisterBuiltinClass( &EDIT_builtin_class );
CLASS_RegisterBuiltinClass( &ICONTITLE_builtin_class );
CLASS_RegisterBuiltinClass( &LISTBOX_builtin_class );
CLASS_RegisterBuiltinClass( &MDICLIENT_builtin_class );
CLASS_RegisterBuiltinClass( &MENU_builtin_class );
CLASS_RegisterBuiltinClass( &SCROLL_builtin_class );
CLASS_RegisterBuiltinClass( &STATIC_builtin_class );
}
/***********************************************************************
* palette_init
*
* Patch the function pointers in GDI for SelectPalette and RealizePalette
......@@ -219,7 +184,7 @@ static void tweak_init(void)
/***********************************************************************
* USER initialisation routine
*/
static BOOL process_attach(void)
static BOOL process_attach( HINSTANCE inst )
{
HINSTANCE16 instance;
......@@ -243,7 +208,7 @@ static BOOL process_attach(void)
palette_init();
/* Initialize built-in window classes */
controls_init();
CLASS_RegisterBuiltinClasses( inst );
/* Initialize menus */
if (!MENU_Init()) return FALSE;
......@@ -304,7 +269,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
switch(reason)
{
case DLL_PROCESS_ATTACH:
ret = process_attach();
ret = process_attach( inst );
break;
case DLL_THREAD_DETACH:
thread_detach();
......
......@@ -137,13 +137,11 @@ inline static void unmap_str_16_to_32W( LPCWSTR str )
/* Class functions */
struct tagCLASS; /* opaque structure */
struct builtin_class_descr;
struct tagDCE;
extern ATOM CLASS_RegisterBuiltinClass( const struct builtin_class_descr *descr );
extern void CLASS_RegisterBuiltinClasses( HINSTANCE inst );
extern struct tagCLASS *CLASS_AddWindow( ATOM atom, HINSTANCE inst, WINDOWPROCTYPE type,
INT *winExtra, WNDPROC *winproc,
DWORD *style, struct tagDCE **dce );
extern void CLASS_RemoveWindow( struct tagCLASS *cls );
extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
/* Timer functions */
......
......@@ -2525,6 +2525,7 @@ struct create_window_request
user_handle_t parent;
user_handle_t owner;
atom_t atom;
void* instance;
int extra;
};
struct create_window_reply
......@@ -3052,6 +3053,67 @@ struct get_next_hook_reply
struct create_class_request
{
struct request_header __header;
int local;
atom_t atom;
unsigned int style;
void* instance;
int extra;
int win_extra;
};
struct create_class_reply
{
struct reply_header __header;
};
struct destroy_class_request
{
struct request_header __header;
atom_t atom;
void* instance;
};
struct destroy_class_reply
{
struct reply_header __header;
};
struct set_class_info_request
{
struct request_header __header;
user_handle_t window;
unsigned int flags;
atom_t atom;
unsigned int style;
int win_extra;
void* instance;
int extra_offset;
size_t extra_size;
unsigned int extra_value;
};
struct set_class_info_reply
{
struct reply_header __header;
atom_t old_atom;
unsigned int old_style;
int old_extra;
int old_win_extra;
void* old_instance;
unsigned int old_extra_value;
};
#define SET_CLASS_ATOM 0x0001
#define SET_CLASS_STYLE 0x0002
#define SET_CLASS_WINEXTRA 0x0004
#define SET_CLASS_INSTANCE 0x0008
#define SET_CLASS_EXTRA 0x0010
struct set_clipboard_info_request
{
struct request_header __header;
......@@ -3298,6 +3360,9 @@ enum request
REQ_start_hook_chain,
REQ_finish_hook_chain,
REQ_get_next_hook,
REQ_create_class,
REQ_destroy_class,
REQ_set_class_info,
REQ_set_clipboard_info,
REQ_open_token,
REQ_set_global_windows,
......@@ -3484,6 +3549,9 @@ union generic_request
struct start_hook_chain_request start_hook_chain_request;
struct finish_hook_chain_request finish_hook_chain_request;
struct get_next_hook_request get_next_hook_request;
struct create_class_request create_class_request;
struct destroy_class_request destroy_class_request;
struct set_class_info_request set_class_info_request;
struct set_clipboard_info_request set_clipboard_info_request;
struct open_token_request open_token_request;
struct set_global_windows_request set_global_windows_request;
......@@ -3668,11 +3736,14 @@ union generic_reply
struct start_hook_chain_reply start_hook_chain_reply;
struct finish_hook_chain_reply finish_hook_chain_reply;
struct get_next_hook_reply get_next_hook_reply;
struct create_class_reply create_class_reply;
struct destroy_class_reply destroy_class_reply;
struct set_class_info_reply set_class_info_reply;
struct set_clipboard_info_reply set_clipboard_info_reply;
struct open_token_reply open_token_reply;
struct set_global_windows_reply set_global_windows_reply;
};
#define SERVER_PROTOCOL_VERSION 128
#define SERVER_PROTOCOL_VERSION 129
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -9,6 +9,7 @@ C_SRCS = \
async.c \
atom.c \
change.c \
class.c \
clipboard.c \
console.c \
context_i386.c \
......
/*
* Server-side window class management
*
* Copyright (C) 2002 Mike McCormack
* Copyright (C) 2003 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "wine/list.h"
#include "request.h"
#include "object.h"
#include "process.h"
#include "user.h"
struct window_class
{
struct list entry; /* entry in process list */
struct process *process; /* process owning the class */
int count; /* reference count */
int local; /* local class? */
atom_t atom; /* class atom */
void *instance; /* module instance */
unsigned int style; /* class style */
int win_extra; /* number of window extra bytes */
int nb_extra_bytes; /* number of extra bytes */
char extra_bytes[1]; /* extra bytes storage */
};
static struct window_class *create_class( struct process *process, int extra_bytes, int local )
{
struct window_class *class;
if (!(class = mem_alloc( sizeof(*class) + extra_bytes - 1 ))) return NULL;
class->process = (struct process *)grab_object( process );
class->count = 0;
class->local = local;
class->nb_extra_bytes = extra_bytes;
memset( class->extra_bytes, 0, extra_bytes );
/* other fields are initialized by caller */
/* local classes have priority so we put them first in the list */
if (local) list_add_head( &process->classes, &class->entry );
else list_add_tail( &process->classes, &class->entry );
return class;
}
static void destroy_class( struct window_class *class )
{
list_remove( &class->entry );
release_object( class->process );
free( class );
}
void destroy_process_classes( struct process *process )
{
struct list *ptr;
while ((ptr = list_head( &process->classes )))
{
struct window_class *class = LIST_ENTRY( ptr, struct window_class, entry );
destroy_class( class );
}
}
static struct window_class *find_class( struct process *process, atom_t atom, void *instance )
{
struct list *ptr;
LIST_FOR_EACH( ptr, &process->classes )
{
struct window_class *class = LIST_ENTRY( ptr, struct window_class, entry );
if (class->atom != atom) continue;
if (!instance || !class->local || class->instance == instance) return class;
}
return NULL;
}
struct window_class *grab_class( struct process *process, atom_t atom, void *instance )
{
struct window_class *class = find_class( process, atom, instance );
if (class) class->count++;
else set_error( STATUS_INVALID_HANDLE );
return class;
}
void release_class( struct window_class *class )
{
assert( class->count > 0 );
class->count--;
}
atom_t get_class_atom( struct window_class *class )
{
return class->atom;
}
/* create a window class */
DECL_HANDLER(create_class)
{
struct window_class *class = find_class( current->process, req->atom, req->instance );
if (class && !class->local == !req->local)
{
set_win32_error( ERROR_CLASS_ALREADY_EXISTS );
return;
}
if (req->extra < 0 || req->extra > 4096) /* don't allow stupid values here */
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if (!grab_global_atom( req->atom )) return;
if (!(class = create_class( current->process, req->extra, req->local )))
{
release_global_atom( req->atom );
return;
}
class->atom = req->atom;
class->instance = req->instance;
class->style = req->style;
class->win_extra = req->win_extra;
}
/* destroy a window class */
DECL_HANDLER(destroy_class)
{
struct window_class *class = find_class( current->process, req->atom, req->instance );
if (!class)
set_error( STATUS_INVALID_HANDLE );
else if (class->count)
set_win32_error( ERROR_CLASS_HAS_WINDOWS );
else
destroy_class( class );
}
/* set some information in a class */
DECL_HANDLER(set_class_info)
{
struct window_class *class = get_window_class( req->window );
if (!class) return;
if (req->extra_size > sizeof(req->extra_value) ||
req->extra_offset < -1 ||
req->extra_offset > class->nb_extra_bytes - (int)req->extra_size)
{
set_win32_error( ERROR_INVALID_INDEX );
return;
}
if (req->extra_offset != -1)
{
memcpy( &reply->old_extra_value, class->extra_bytes + req->extra_offset, req->extra_size );
}
else if (req->flags & SET_CLASS_EXTRA)
{
set_win32_error( ERROR_INVALID_INDEX );
return;
}
reply->old_atom = class->atom;
reply->old_style = class->style;
reply->old_extra = class->nb_extra_bytes;
reply->old_win_extra = class->win_extra;
reply->old_instance = class->instance;
if (req->flags & SET_CLASS_ATOM)
{
if (!grab_global_atom( req->atom )) return;
release_global_atom( class->atom );
class->atom = req->atom;
}
if (req->flags & SET_CLASS_STYLE) class->style = req->style;
if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra;
if (req->flags & SET_CLASS_INSTANCE) class->instance = req->instance;
if (req->flags & SET_CLASS_EXTRA) memcpy( class->extra_bytes + req->extra_offset,
&req->extra_value, req->extra_size );
}
......@@ -44,6 +44,7 @@
#include "thread.h"
#include "request.h"
#include "console.h"
#include "user.h"
/* process structure */
......@@ -283,6 +284,7 @@ struct thread *create_process( int fd )
process->group_id = 0;
process->token = create_token();
list_init( &process->locks );
list_init( &process->classes );
gettimeofday( &process->start_time, NULL );
if ((process->next = first_process) != NULL) process->next->prev = process;
......@@ -597,6 +599,7 @@ static void process_killed( struct process *process )
if (dll->filename) free( dll->filename );
free( dll );
}
destroy_process_classes( process );
set_process_startup_state( process, STARTUP_ABORTED );
if (process->exe.file) release_object( process->exe.file );
process->exe.file = NULL;
......
......@@ -68,6 +68,7 @@ struct process
int suspend; /* global process suspend count */
int create_flags; /* process creation flags */
struct list locks; /* list of file locks owned by the process */
struct list classes; /* window classes owned by the process */
struct console_input*console; /* console input */
enum startup_state startup_state; /* startup state */
struct startup_info *startup_info; /* startup info while init is in progress */
......
......@@ -1780,6 +1780,7 @@ enum message_type
user_handle_t parent; /* parent window */
user_handle_t owner; /* owner window */
atom_t atom; /* class atom */
void* instance; /* module instance */
int extra; /* number of extra bytes */
@REPLY
user_handle_t handle; /* created window */
......@@ -2129,6 +2130,50 @@ enum message_type
@END
/* Create a window class */
@REQ(create_class)
int local; /* is it a local class? */
atom_t atom; /* class atom */
unsigned int style; /* class style */
void* instance; /* module instance */
int extra; /* number of extra class bytes */
int win_extra; /* number of window extra bytes */
@END
/* Destroy a window class */
@REQ(destroy_class)
atom_t atom; /* class atom */
void* instance; /* module instance */
@END
/* Set some information in a class */
@REQ(set_class_info)
user_handle_t window; /* handle to the window */
unsigned int flags; /* flags for info to set (see below) */
atom_t atom; /* class atom */
unsigned int style; /* class style */
int win_extra; /* number of window extra bytes */
void* instance; /* module instance */
int extra_offset; /* offset to set in extra bytes */
size_t extra_size; /* size to set in extra bytes */
unsigned int extra_value; /* value to set in extra bytes */
@REPLY
atom_t old_atom; /* previous class atom */
unsigned int old_style; /* previous class style */
int old_extra; /* previous number of class extra bytes */
int old_win_extra; /* previous number of window extra bytes */
void* old_instance; /* previous module instance */
unsigned int old_extra_value; /* old value in extra bytes */
@END
#define SET_CLASS_ATOM 0x0001
#define SET_CLASS_STYLE 0x0002
#define SET_CLASS_WINEXTRA 0x0004
#define SET_CLASS_INSTANCE 0x0008
#define SET_CLASS_EXTRA 0x0010
/* Set/get clipboard information */
@REQ(set_clipboard_info)
unsigned int flags; /* flags for fields to set (see below) */
......
......@@ -279,6 +279,9 @@ DECL_HANDLER(remove_hook);
DECL_HANDLER(start_hook_chain);
DECL_HANDLER(finish_hook_chain);
DECL_HANDLER(get_next_hook);
DECL_HANDLER(create_class);
DECL_HANDLER(destroy_class);
DECL_HANDLER(set_class_info);
DECL_HANDLER(set_clipboard_info);
DECL_HANDLER(open_token);
DECL_HANDLER(set_global_windows);
......@@ -464,6 +467,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_start_hook_chain,
(req_handler)req_finish_hook_chain,
(req_handler)req_get_next_hook,
(req_handler)req_create_class,
(req_handler)req_destroy_class,
(req_handler)req_set_class_info,
(req_handler)req_set_clipboard_info,
(req_handler)req_open_token,
(req_handler)req_set_global_windows,
......
......@@ -2096,6 +2096,7 @@ 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, " extra=%d", req->extra );
}
......@@ -2503,6 +2504,45 @@ static void dump_get_next_hook_reply( const struct get_next_hook_reply *req )
dump_varargs_unicode_str( cur_size );
}
static void dump_create_class_request( const struct create_class_request *req )
{
fprintf( stderr, " local=%d,", req->local );
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " style=%08x,", req->style );
fprintf( stderr, " instance=%p,", req->instance );
fprintf( stderr, " extra=%d,", req->extra );
fprintf( stderr, " win_extra=%d", req->win_extra );
}
static void dump_destroy_class_request( const struct destroy_class_request *req )
{
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " instance=%p", req->instance );
}
static void dump_set_class_info_request( const struct set_class_info_request *req )
{
fprintf( stderr, " window=%p,", req->window );
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " style=%08x,", req->style );
fprintf( stderr, " win_extra=%d,", req->win_extra );
fprintf( stderr, " instance=%p,", req->instance );
fprintf( stderr, " extra_offset=%d,", req->extra_offset );
fprintf( stderr, " extra_size=%d,", req->extra_size );
fprintf( stderr, " extra_value=%08x", req->extra_value );
}
static void dump_set_class_info_reply( const struct set_class_info_reply *req )
{
fprintf( stderr, " old_atom=%04x,", req->old_atom );
fprintf( stderr, " old_style=%08x,", req->old_style );
fprintf( stderr, " old_extra=%d,", req->old_extra );
fprintf( stderr, " old_win_extra=%d,", req->old_win_extra );
fprintf( stderr, " old_instance=%p,", req->old_instance );
fprintf( stderr, " old_extra_value=%08x", req->old_extra_value );
}
static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req )
{
fprintf( stderr, " flags=%08x,", req->flags );
......@@ -2726,6 +2766,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_start_hook_chain_request,
(dump_func)dump_finish_hook_chain_request,
(dump_func)dump_get_next_hook_request,
(dump_func)dump_create_class_request,
(dump_func)dump_destroy_class_request,
(dump_func)dump_set_class_info_request,
(dump_func)dump_set_clipboard_info_request,
(dump_func)dump_open_token_request,
(dump_func)dump_set_global_windows_request,
......@@ -2908,6 +2951,9 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_start_hook_chain_reply,
(dump_func)0,
(dump_func)dump_get_next_hook_reply,
(dump_func)0,
(dump_func)0,
(dump_func)dump_set_class_info_reply,
(dump_func)dump_set_clipboard_info_reply,
(dump_func)dump_open_token_reply,
(dump_func)dump_set_global_windows_reply,
......@@ -3090,6 +3136,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"start_hook_chain",
"finish_hook_chain",
"get_next_hook",
"create_class",
"destroy_class",
"set_class_info",
"set_clipboard_info",
"open_token",
"set_global_windows",
......
......@@ -27,6 +27,7 @@ struct thread;
struct window;
struct msg_queue;
struct hook_table;
struct window_class;
enum user_object
{
......@@ -72,5 +73,13 @@ extern int make_window_active( user_handle_t window );
extern struct thread *get_window_thread( user_handle_t handle );
extern user_handle_t window_from_point( int x, int y );
extern user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread );
extern struct window_class *get_window_class( user_handle_t window );
/* window class functions */
extern void destroy_process_classes( struct process *process );
extern struct window_class *grab_class( struct process *process, atom_t atom, void *instance );
extern void release_class( struct window_class *class );
extern atom_t get_class_atom( struct window_class *class );
#endif /* __WINE_SERVER_USER_H */
......@@ -63,6 +63,7 @@ struct window
struct window *prev; /* prev window in Z-order */
user_handle_t handle; /* full handle for this window */
struct thread *thread; /* thread owning the window */
struct window_class *class; /* window class */
atom_t atom; /* class atom */
user_handle_t last_active; /* last active popup */
rectangle_t window_rect; /* window rectangle */
......@@ -260,6 +261,7 @@ static void destroy_window( struct window *win )
free_user_handle( win->handle );
destroy_properties( win );
unlink_window( win );
release_class( win->class );
if (win->text) free( win->text );
memset( win, 0x55, sizeof(*win) );
free( win );
......@@ -267,13 +269,23 @@ static void destroy_window( struct window *win )
/* create a new window structure (note: the window is not linked in the window tree) */
static struct window *create_window( struct window *parent, struct window *owner, atom_t atom,
int extra_bytes )
void *instance, int extra_bytes )
{
struct window *win = mem_alloc( sizeof(*win) + extra_bytes - 1 );
if (!win) return NULL;
struct window *win;
struct window_class *class = grab_class( current->process, atom, instance );
if (!class) return NULL;
win = mem_alloc( sizeof(*win) + extra_bytes - 1 );
if (!win)
{
release_class( class );
return NULL;
}
if (!(win->handle = alloc_user_handle( win, USER_WINDOW )))
{
release_class( class );
free( win );
return NULL;
}
......@@ -283,6 +295,7 @@ static struct window *create_window( struct window *parent, struct window *owner
win->last_child = NULL;
win->first_unlinked = NULL;
win->thread = current;
win->class = class;
win->atom = atom;
win->last_active = win->handle;
win->style = 0;
......@@ -449,6 +462,15 @@ user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *threa
}
/* get the window class of a window */
struct window_class* get_window_class( user_handle_t window )
{
struct window *win;
if (!(win = get_window( window ))) return NULL;
return win->class;
}
/* create a window */
DECL_HANDLER(create_window)
{
......@@ -462,7 +484,7 @@ DECL_HANDLER(create_window)
{
if (!top_window)
{
if (!(top_window = create_window( NULL, NULL, req->atom, req->extra ))) return;
if (!(top_window = create_window( NULL, NULL, req->atom, req->instance, req->extra ))) return;
top_window->thread = NULL; /* no thread owns the desktop */
top_window->style = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
}
......@@ -481,7 +503,7 @@ DECL_HANDLER(create_window)
set_error( STATUS_ACCESS_DENIED );
return;
}
if (!(win = create_window( parent, owner, req->atom, req->extra ))) return;
if (!(win = create_window( parent, owner, req->atom, req->instance, req->extra ))) return;
reply->handle = win->handle;
}
}
......@@ -569,7 +591,7 @@ DECL_HANDLER(get_window_info)
{
reply->tid = get_thread_id( win->thread );
reply->pid = get_process_id( win->thread->process );
reply->atom = win->atom;
reply->atom = get_class_atom( win->class );
}
}
}
......@@ -648,7 +670,7 @@ DECL_HANDLER(get_window_children)
if (parent)
for (ptr = parent->first_child, total = 0; ptr; ptr = ptr->next)
{
if (req->atom && ptr->atom != req->atom) continue;
if (req->atom && get_class_atom(ptr->class) != req->atom) continue;
if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
total++;
}
......@@ -659,7 +681,7 @@ DECL_HANDLER(get_window_children)
{
for (ptr = parent->first_child; ptr && len; ptr = ptr->next)
{
if (req->atom && ptr->atom != req->atom) continue;
if (req->atom && get_class_atom(ptr->class) != req->atom) continue;
if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
*data++ = ptr->handle;
len -= sizeof(*data);
......
......@@ -62,23 +62,34 @@ 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, unsigned int extra_bytes )
static WND *create_window_handle( HWND parent, HWND owner, ATOM atom,
HINSTANCE instance, WINDOWPROCTYPE type )
{
BOOL res;
user_handle_t handle = 0;
WORD index;
WND *win = HeapAlloc( GetProcessHeap(), 0, sizeof(WND) + extra_bytes - sizeof(win->wExtra) );
WND *win;
DCE *dce;
INT extra_bytes;
DWORD clsStyle;
WNDPROC winproc;
struct tagCLASS *class;
user_handle_t handle = 0;
if (!win) return NULL;
if (!(class = CLASS_AddWindow( atom, instance, type, &extra_bytes, &winproc, &clsStyle, &dce )))
return NULL;
if (!(win = HeapAlloc( GetProcessHeap(), 0, sizeof(WND) + extra_bytes - sizeof(win->wExtra) )))
return NULL;
USER_Lock();
SERVER_START_REQ( create_window )
{
req->parent = parent;
req->owner = owner;
req->atom = atom;
req->extra = extra_bytes;
req->parent = parent;
req->owner = owner;
req->atom = atom;
req->instance = instance;
req->extra = extra_bytes;
if ((res = !wine_server_call_err( req ))) handle = reply->handle;
}
SERVER_END_REQ;
......@@ -92,9 +103,15 @@ static WND *create_window_handle( HWND parent, HWND owner, ATOM atom, unsigned i
index = LOWORD(handle) - FIRST_USER_HANDLE;
assert( index < NB_USER_HANDLES );
user_handles[index] = win;
win->hwndSelf = handle;
win->dwMagic = WND_MAGIC;
win->irefCount = 1;
win->hwndSelf = handle;
win->dwMagic = WND_MAGIC;
win->irefCount = 1;
win->class = class;
win->winproc = winproc;
win->dce = dce;
win->clsStyle = clsStyle;
win->cbWndExtra = extra_bytes;
memset( win->wExtra, 0, extra_bytes );
return win;
}
......@@ -669,7 +686,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
DCE_FreeWindowDCE( hwnd ); /* Always do this to catch orphaned DCs */
USER_Driver.pDestroyWindow( hwnd );
WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
CLASS_RemoveWindow( wndPtr->class );
wndPtr->class = NULL;
wndPtr->dwMagic = 0; /* Mark it as invalid */
WIN_ReleaseWndPtr( wndPtr );
......@@ -705,41 +721,28 @@ void WIN_DestroyThreadWindows( HWND hwnd )
*/
BOOL WIN_CreateDesktopWindow(void)
{
struct tagCLASS *class;
HWND hwndDesktop;
INT wndExtra;
DWORD clsStyle;
WNDPROC winproc;
DCE *dce;
CREATESTRUCTA cs;
RECT rect;
TRACE("Creating desktop window\n");
if (!WINPOS_CreateInternalPosAtom() ||
!(class = CLASS_AddWindow( (ATOM)LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W,
&wndExtra, &winproc, &clsStyle, &dce )))
return FALSE;
if (!WINPOS_CreateInternalPosAtom()) return FALSE;
pWndDesktop = create_window_handle( 0, 0, LOWORD(DESKTOP_CLASS_ATOM), wndExtra );
pWndDesktop = create_window_handle( 0, 0, LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W );
if (!pWndDesktop) return FALSE;
hwndDesktop = pWndDesktop->hwndSelf;
pWndDesktop->tid = 0; /* nobody owns the desktop */
pWndDesktop->parent = 0;
pWndDesktop->owner = 0;
pWndDesktop->class = class;
pWndDesktop->text = NULL;
pWndDesktop->hrgnUpdate = 0;
pWndDesktop->clsStyle = clsStyle;
pWndDesktop->dce = NULL;
pWndDesktop->pVScroll = NULL;
pWndDesktop->pHScroll = NULL;
pWndDesktop->helpContext = 0;
pWndDesktop->flags = 0;
pWndDesktop->hSysMenu = 0;
pWndDesktop->winproc = winproc;
pWndDesktop->cbWndExtra = wndExtra;
cs.lpCreateParams = NULL;
cs.hInstance = 0;
......@@ -970,13 +973,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
WINDOWPROCTYPE type )
{
INT sw = SW_SHOW;
struct tagCLASS *classPtr;
WND *wndPtr;
HWND hwnd, parent, owner;
INT wndExtra;
DWORD clsStyle;
WNDPROC winproc;
DCE *dce;
BOOL unicode = (type == WIN_PROC_32W);
TRACE("%s %s ex=%08lx style=%08lx %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
......@@ -1021,14 +1019,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
}
/* Find the window class */
if (!(classPtr = CLASS_AddWindow( classAtom, cs->hInstance, type,
&wndExtra, &winproc, &clsStyle, &dce )))
{
WARN("Bad class '%s'\n", cs->lpszClass );
return 0;
}
WIN_FixCoordinates(cs, &sw); /* fix default coordinates */
/* Correct the window style - stage 1
......@@ -1052,7 +1042,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
/* Create the window structure */
if (!(wndPtr = create_window_handle( parent, owner, classAtom, wndExtra )))
if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, type )))
{
TRACE("out of memory\n" );
return 0;
......@@ -1064,15 +1054,12 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->tid = GetCurrentThreadId();
wndPtr->owner = owner;
wndPtr->parent = parent;
wndPtr->class = classPtr;
wndPtr->winproc = winproc;
wndPtr->hInstance = cs->hInstance;
wndPtr->text = NULL;
wndPtr->hrgnUpdate = 0;
wndPtr->hrgnWnd = 0;
wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
wndPtr->dwExStyle = cs->dwExStyle;
wndPtr->clsStyle = clsStyle;
wndPtr->wIDmenu = 0;
wndPtr->helpContext = 0;
wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32;
......@@ -1080,9 +1067,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->pHScroll = NULL;
wndPtr->userdata = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0;
wndPtr->cbWndExtra = wndExtra;
if (wndExtra) memset( wndPtr->wExtra, 0, wndExtra);
/* Correct the window style - stage 2 */
......@@ -1109,9 +1093,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
/* Get class or window DC if needed */
if (clsStyle & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce;
else wndPtr->dce = NULL;
if (wndPtr->clsStyle & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
/* Set the window menu */
......@@ -1248,9 +1230,6 @@ HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
CREATESTRUCTA cs;
char buffer[256];
if(!instance)
instance=GetModuleHandleA(NULL);
if(exStyle & WS_EX_MDICHILD)
return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
......@@ -1307,9 +1286,6 @@ HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
CREATESTRUCTW cs;
WCHAR buffer[256];
if(!instance)
instance=GetModuleHandleW(NULL);
if(exStyle & WS_EX_MDICHILD)
return CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment