Store window properties in the server. Moved property.c to dlls/user.

This commit is contained in:
Alexandre Julliard 2001-10-12 19:10:26 +00:00
parent d8a8c1131d
commit 7a2017dd65
11 changed files with 655 additions and 412 deletions

View File

@ -23,6 +23,7 @@ C_SRCS = \
mouse.c \
msg16.c \
network.c \
property.c \
resource.c \
text.c \
thunk.c \

299
dlls/user/property.c Normal file
View File

@ -0,0 +1,299 @@
/*
* Window properties
*
* Copyright 1995, 1996, 2001 Alexandre Julliard
*/
#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/server.h"
#include "heap.h"
/* size of buffer needed to store an atom string */
#define ATOM_BUFFER_SIZE 256
/***********************************************************************
* get_properties
*
* Retrieve the list of properties of a given window.
* Returned buffer must be freed by caller.
*/
static property_data_t *get_properties( HWND hwnd, int *count )
{
property_data_t *ret = NULL;
SERVER_START_VAR_REQ( get_window_properties, REQUEST_MAX_VAR_SIZE )
{
req->window = hwnd;
if (!SERVER_CALL())
{
size_t size = server_data_size(req);
if (size)
{
property_data_t *data = server_data_ptr(req);
if ((ret = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( ret, data, size );
*count = size / sizeof(*data);
}
}
}
SERVER_END_VAR_REQ;
return ret;
}
/***********************************************************************
* EnumPropsA_relay
*
* relay to call the EnumProps callback function from EnumPropsEx
*/
static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
{
PROPENUMPROCA func = (PROPENUMPROCA)lparam;
return func( hwnd, str, handle );
}
/***********************************************************************
* EnumPropsW_relay
*
* relay to call the EnumProps callback function from EnumPropsEx
*/
static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
{
PROPENUMPROCW func = (PROPENUMPROCW)lparam;
return func( hwnd, str, handle );
}
/***********************************************************************
* EnumPropsA (USER32.@)
*/
INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
{
return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
}
/***********************************************************************
* EnumPropsW (USER32.@)
*/
INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
{
return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
}
/***********************************************************************
* GetPropA (USER32.@)
*/
HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
{
ATOM atom;
HANDLE ret = 0;
if (!HIWORD(str)) atom = LOWORD(str);
else if (!(atom = GlobalFindAtomA( str ))) return 0;
SERVER_START_REQ( get_window_property )
{
req->window = hwnd;
req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle;
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* GetPropW (USER32.@)
*/
HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
{
ATOM atom;
HANDLE ret = 0;
if (!HIWORD(str)) atom = LOWORD(str);
else if (!(atom = GlobalFindAtomW( str ))) return 0;
SERVER_START_REQ( get_window_property )
{
req->window = hwnd;
req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle;
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* SetPropA (USER32.@)
*/
BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
{
ATOM atom;
BOOL ret;
if (!HIWORD(str)) atom = LOWORD(str);
else if (!(atom = GlobalAddAtomA( str ))) return FALSE;
SERVER_START_REQ( set_window_property )
{
req->window = hwnd;
req->atom = atom;
req->string = (HIWORD(str) != 0);
req->handle = handle;
ret = !SERVER_CALL_ERR();
}
SERVER_END_REQ;
if (HIWORD(str)) GlobalDeleteAtom( atom );
return ret;
}
/***********************************************************************
* SetPropW (USER32.@)
*/
BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
{
ATOM atom;
BOOL ret;
if (!HIWORD(str)) atom = LOWORD(str);
else if (!(atom = GlobalAddAtomW( str ))) return FALSE;
SERVER_START_REQ( set_window_property )
{
req->window = hwnd;
req->atom = atom;
req->string = (HIWORD(str) != 0);
req->handle = handle;
ret = !SERVER_CALL_ERR();
}
SERVER_END_REQ;
if (HIWORD(str)) GlobalDeleteAtom( atom );
return ret;
}
/***********************************************************************
* RemovePropA (USER32.@)
*/
HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
{
ATOM atom;
HANDLE ret = 0;
if (!HIWORD(str)) return RemovePropW( hwnd, MAKEINTATOMW(LOWORD(str)) );
if ((atom = GlobalAddAtomA( str )))
{
ret = RemovePropW( hwnd, MAKEINTATOMW(atom) );
GlobalDeleteAtom( atom );
}
return ret;
}
/***********************************************************************
* RemovePropW (USER32.@)
*/
HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
{
ATOM atom;
HANDLE ret = 0;
if (!HIWORD(str)) atom = LOWORD(str);
else if (!(atom = GlobalAddAtomW( str ))) return 0;
SERVER_START_REQ( remove_window_property )
{
req->window = hwnd;
req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle;
}
SERVER_END_REQ;
if (HIWORD(str)) GlobalDeleteAtom( atom );
return ret;
}
/***********************************************************************
* EnumPropsExA (USER32.@)
*/
INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
{
int ret = -1, i, count;
property_data_t *list = get_properties( hwnd, &count );
if (list)
{
for (i = 0; i < count; i++)
{
char string[ATOM_BUFFER_SIZE];
if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
}
HeapFree( GetProcessHeap(), 0, list );
}
return ret;
}
/***********************************************************************
* EnumPropsExW (USER32.@)
*/
INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
{
int ret = -1, i, count;
property_data_t *list = get_properties( hwnd, &count );
if (list)
{
for (i = 0; i < count; i++)
{
WCHAR string[ATOM_BUFFER_SIZE];
if (!GlobalGetAtomNameW( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
}
HeapFree( GetProcessHeap(), 0, list );
}
return ret;
}
/***********************************************************************
* EnumProps (USER.27)
*/
INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
{
int ret = -1, i, count;
property_data_t *list = get_properties( hwnd, &count );
if (list)
{
char *string = SEGPTR_ALLOC( ATOM_BUFFER_SIZE );
for (i = 0; i < count; i++)
{
if (list[i].string) /* it was a string originally */
{
if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
ret = func( hwnd, SEGPTR_GET(string), list[i].handle );
}
else
ret = func( hwnd, list[i].atom, list[i].handle );
if (!ret) break;
}
SEGPTR_FREE( string );
HeapFree( GetProcessHeap(), 0, list );
}
return ret;
}

View File

@ -35,7 +35,6 @@ typedef struct tagWND
LPWSTR text; /* Window text */
void *pVScroll; /* Vertical scroll-bar info */
void *pHScroll; /* Horizontal scroll-bar info */
void *pProp; /* Pointer to properties list */
struct tagDCE *dce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
HGLOBAL16 hmemTaskQ; /* Task queue global memory handle */
HRGN hrgnUpdate; /* Update region */
@ -122,8 +121,6 @@ extern void CARET_GetRect(LPRECT lprc); /* windows/caret.c */
extern BOOL16 DRAG_QueryUpdate( HWND, SEGPTR, BOOL );
extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ); /* windows/defwnd.c */
extern void PROPERTY_RemoveWindowProps( HWND hwnd ); /* windows/property.c */
/* Classes functions */
struct tagCLASS; /* opaque structure */
struct builtin_class_descr;

View File

@ -132,6 +132,14 @@ struct wake_up_reply
};
typedef struct
{
atom_t atom;
short string;
handle_t handle;
} property_data_t;
@ -1644,6 +1652,46 @@ struct get_window_tree_request
};
struct set_window_property_request
{
struct request_header __header;
user_handle_t window;
atom_t atom;
int string;
handle_t handle;
};
struct remove_window_property_request
{
struct request_header __header;
user_handle_t window;
atom_t atom;
handle_t handle;
};
struct get_window_property_request
{
struct request_header __header;
user_handle_t window;
atom_t atom;
handle_t handle;
};
struct get_window_properties_request
{
struct request_header __header;
user_handle_t window;
/* VARARG(props,properties); */
};
enum request
{
REQ_new_process,
@ -1775,6 +1823,10 @@ enum request
REQ_get_window_parents,
REQ_get_window_children,
REQ_get_window_tree,
REQ_set_window_property,
REQ_remove_window_property,
REQ_get_window_property,
REQ_get_window_properties,
REQ_NB_REQUESTS
};
@ -1911,8 +1963,12 @@ union generic_request
struct get_window_parents_request get_window_parents;
struct get_window_children_request get_window_children;
struct get_window_tree_request get_window_tree;
struct set_window_property_request set_window_property;
struct remove_window_property_request remove_window_property;
struct get_window_property_request get_window_property;
struct get_window_properties_request get_window_properties;
};
#define SERVER_PROTOCOL_VERSION 58
#define SERVER_PROTOCOL_VERSION 59
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -133,6 +133,14 @@ struct wake_up_reply
int signaled; /* wait result */
};
/* structure returned in the list of window properties */
typedef struct
{
atom_t atom; /* property atom */
short string; /* was atom a string originally? */
handle_t handle; /* handle stored in property */
} property_data_t;
/****************************************************************/
/* Request declarations */
@ -1469,3 +1477,38 @@ enum message_type
user_handle_t first_child; /* first child */
user_handle_t last_child; /* last child */
@END
/* Set a window property */
@REQ(set_window_property)
user_handle_t window; /* handle to the window */
atom_t atom; /* property atom (high-word set if it was a string) */
int string; /* was atom a string originally? */
handle_t handle; /* handle to store */
@END
/* Remove a window property */
@REQ(remove_window_property)
user_handle_t window; /* handle to the window */
atom_t atom; /* property atom */
@REPLY
handle_t handle; /* handle stored in property */
@END
/* Get a window property */
@REQ(get_window_property)
user_handle_t window; /* handle to the window */
atom_t atom; /* property atom */
@REPLY
handle_t handle; /* handle stored in property */
@END
/* Get the list of properties of a window */
@REQ(get_window_properties)
user_handle_t window; /* handle to the window */
@REPLY
VARARG(props,properties); /* list of properties */
@END

View File

@ -194,6 +194,10 @@ DECL_HANDLER(get_window_info);
DECL_HANDLER(get_window_parents);
DECL_HANDLER(get_window_children);
DECL_HANDLER(get_window_tree);
DECL_HANDLER(set_window_property);
DECL_HANDLER(remove_window_property);
DECL_HANDLER(get_window_property);
DECL_HANDLER(get_window_properties);
#ifdef WANT_REQUEST_HANDLERS
@ -329,6 +333,10 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_window_parents,
(req_handler)req_get_window_children,
(req_handler)req_get_window_tree,
(req_handler)req_set_window_property,
(req_handler)req_remove_window_property,
(req_handler)req_get_window_property,
(req_handler)req_get_window_properties,
};
#endif /* WANT_REQUEST_HANDLERS */

View File

@ -271,6 +271,23 @@ static size_t dump_varargs_input_records( const void *req )
return get_size(req);
}
static size_t dump_varargs_properties( const void *req )
{
const property_data_t *prop = get_data(req);
size_t len = get_size(req) / sizeof(*prop);
fputc( '{', stderr );
while (len > 0)
{
fprintf( stderr, "{atom=%04x,str=%d,handle=%08x}",
prop->atom, prop->string, prop->handle );
prop++;
if (--len) fputc( ',', stderr );
}
fputc( '}', stderr );
return get_size(req);
}
typedef void (*dump_func)( const void *req );
/* Everything below this line is generated automatically by tools/make_requests */
@ -1743,6 +1760,47 @@ static void dump_get_window_tree_reply( const struct get_window_tree_request *re
fprintf( stderr, " last_child=%08x", req->last_child );
}
static void dump_set_window_property_request( const struct set_window_property_request *req )
{
fprintf( stderr, " window=%08x,", req->window );
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " string=%d,", req->string );
fprintf( stderr, " handle=%d", req->handle );
}
static void dump_remove_window_property_request( const struct remove_window_property_request *req )
{
fprintf( stderr, " window=%08x,", req->window );
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_remove_window_property_reply( const struct remove_window_property_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
}
static void dump_get_window_property_request( const struct get_window_property_request *req )
{
fprintf( stderr, " window=%08x,", req->window );
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_get_window_property_reply( const struct get_window_property_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
}
static void dump_get_window_properties_request( const struct get_window_properties_request *req )
{
fprintf( stderr, " window=%08x", req->window );
}
static void dump_get_window_properties_reply( const struct get_window_properties_request *req )
{
fprintf( stderr, " props=" );
cur_pos += dump_varargs_properties( req );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@ -1873,6 +1931,10 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_window_parents_request,
(dump_func)dump_get_window_children_request,
(dump_func)dump_get_window_tree_request,
(dump_func)dump_set_window_property_request,
(dump_func)dump_remove_window_property_request,
(dump_func)dump_get_window_property_request,
(dump_func)dump_get_window_properties_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@ -2005,6 +2067,10 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_window_parents_reply,
(dump_func)dump_get_window_children_reply,
(dump_func)dump_get_window_tree_reply,
(dump_func)0,
(dump_func)dump_remove_window_property_reply,
(dump_func)dump_get_window_property_reply,
(dump_func)dump_get_window_properties_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@ -2137,6 +2203,10 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_window_parents",
"get_window_children",
"get_window_tree",
"set_window_property",
"remove_window_property",
"get_window_property",
"get_window_properties",
};
/* ### make_requests end ### */

View File

@ -12,6 +12,22 @@
#include "process.h"
#include "user.h"
/* a window property */
struct property
{
unsigned short type; /* property type (see below) */
atom_t atom; /* property atom */
handle_t handle; /* property handle (user-defined storage) */
};
enum property_type
{
PROP_TYPE_FREE, /* free entry */
PROP_TYPE_STRING, /* atom that was originally a string */
PROP_TYPE_ATOM /* plain atom */
};
struct window
{
struct window *parent; /* parent window */
@ -23,7 +39,10 @@ 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 */
unsigned int atom; /* class atom */
atom_t atom; /* class atom */
int prop_inuse; /* number of in-use window properties */
int prop_alloc; /* number of allocated window properties */
struct property *properties; /* window properties array */
};
static struct window *top_window; /* top-level (desktop) window */
@ -83,6 +102,118 @@ static void link_window( struct window *win, struct window *parent, struct windo
}
}
/* set a window property */
static void set_property( struct window *win, atom_t atom, handle_t handle,
enum property_type type )
{
int i, free = -1;
struct property *new_props;
/* check if it exists already */
for (i = 0; i < win->prop_inuse; i++)
{
if (win->properties[i].type == PROP_TYPE_FREE)
{
free = i;
continue;
}
if (win->properties[i].atom == atom)
{
win->properties[i].type = type;
win->properties[i].handle = handle;
return;
}
}
/* need to add an entry */
if (!grab_global_atom( atom )) return;
if (free == -1)
{
/* no free entry */
if (win->prop_inuse >= win->prop_alloc)
{
/* need to grow the array */
if (!(new_props = realloc( win->properties,
sizeof(*new_props) * (win->prop_alloc + 16) )))
{
set_error( STATUS_NO_MEMORY );
release_global_atom( atom );
return;
}
win->prop_alloc += 16;
win->properties = new_props;
}
free = win->prop_inuse++;
}
win->properties[free].atom = atom;
win->properties[free].type = type;
win->properties[free].handle = handle;
}
/* remove a window property */
static handle_t remove_property( struct window *win, atom_t atom )
{
int i;
for (i = 0; i < win->prop_inuse; i++)
{
if (win->properties[i].type == PROP_TYPE_FREE) continue;
if (win->properties[i].atom == atom)
{
release_global_atom( atom );
win->properties[i].type = PROP_TYPE_FREE;
return win->properties[i].handle;
}
}
/* FIXME: last error? */
return 0;
}
/* find a window property */
static handle_t get_property( struct window *win, atom_t atom )
{
int i;
for (i = 0; i < win->prop_inuse; i++)
{
if (win->properties[i].type == PROP_TYPE_FREE) continue;
if (win->properties[i].atom == atom) return win->properties[i].handle;
}
/* FIXME: last error? */
return 0;
}
/* destroy all properties of a window */
inline static void destroy_properties( struct window *win )
{
int i;
if (!win->properties) return;
for (i = 0; i < win->prop_inuse; i++)
{
if (win->properties[i].type == PROP_TYPE_FREE) continue;
release_global_atom( win->properties[i].atom );
}
free( win->properties );
}
/* enum all properties into the data array */
static int enum_properties( struct window *win, property_data_t *data, int max )
{
int i, count;
for (i = count = 0; i < win->prop_inuse && count < max; i++)
{
if (win->properties[i].type == PROP_TYPE_FREE) continue;
data->atom = win->properties[i].atom;
data->string = (win->properties[i].type == PROP_TYPE_STRING);
data->handle = win->properties[i].handle;
data++;
count++;
}
return count;
}
/* destroy a window */
static void destroy_window( struct window *win )
{
@ -104,14 +235,14 @@ static void destroy_window( struct window *win )
if (win->thread->queue) queue_cleanup_window( win->thread, win->handle );
free_user_handle( win->handle );
destroy_properties( win );
unlink_window( win );
memset( win, 0x55, sizeof(*win) );
free( 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,
unsigned int atom )
static struct window *create_window( struct window *parent, struct window *owner, atom_t atom )
{
struct window *win = mem_alloc( sizeof(*win) );
if (!win) return NULL;
@ -128,6 +259,9 @@ static struct window *create_window( struct window *parent, struct window *owner
win->first_unlinked = NULL;
win->thread = current;
win->atom = atom;
win->prop_inuse = 0;
win->prop_alloc = 0;
win->properties = NULL;
if (parent) /* put it on parent unlinked list */
{
@ -340,3 +474,43 @@ DECL_HANDLER(get_window_tree)
req->first_child = win->first_child ? win->first_child->handle : 0;
req->last_child = win->last_child ? win->last_child->handle : 0;
}
/* set a window property */
DECL_HANDLER(set_window_property)
{
struct window *win = get_window( req->window );
if (win) set_property( win, req->atom, req->handle,
req->string ? PROP_TYPE_STRING : PROP_TYPE_ATOM );
}
/* remove a window property */
DECL_HANDLER(remove_window_property)
{
struct window *win = get_window( req->window );
req->handle = 0;
if (win) req->handle = remove_property( win, req->atom );
}
/* get a window property */
DECL_HANDLER(get_window_property)
{
struct window *win = get_window( req->window );
req->handle = 0;
if (win) req->handle = get_property( win, req->atom );
}
/* get the list of properties of a window */
DECL_HANDLER(get_window_properties)
{
int count = 0;
property_data_t *data = get_req_data(req);
struct window *win = get_window( req->window );
if (win) count = enum_properties( win, data, get_req_data_size(req) / sizeof(*data) );
set_req_data_size( req, count * sizeof(*data) );
}

View File

@ -26,7 +26,6 @@ C_SRCS = \
multimon.c \
nonclient.c \
painting.c \
property.c \
queue.c \
rect.c \
scroll.c \

View File

@ -1,401 +0,0 @@
/*
* Window properties
*
* Copyright 1995, 1996 Alexandre Julliard
*/
#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "win.h"
#include "heap.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(prop);
typedef struct tagPROPERTY
{
struct tagPROPERTY *next; /* Next property in window list */
HANDLE handle; /* User's data */
LPSTR string; /* Property string (or atom) */
} PROPERTY;
#define MAX_ATOM_LEN 255
/***********************************************************************
* PROP_FindProp
*/
static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str )
{
ATOM atom;
PROPERTY *prop;
WND *pWnd = WIN_FindWndPtr( hwnd );
if (!pWnd) return NULL;
if (HIWORD(str))
{
atom = GlobalFindAtomA( str );
for (prop = pWnd->pProp; prop; prop = prop->next)
{
if (HIWORD(prop->string))
{
if (!lstrcmpiA( prop->string, str )) goto END;
}
else if (LOWORD(prop->string) == atom) goto END;
}
}
else /* atom */
{
atom = LOWORD(str);
for (prop = pWnd->pProp; (prop); prop = prop->next)
{
if (HIWORD(prop->string))
{
if (GlobalFindAtomA( prop->string ) == atom) goto END;
}
else if (LOWORD(prop->string) == atom) goto END;
}
}
prop = NULL;
END:
WIN_ReleaseWndPtr(pWnd);
return prop;
}
/***********************************************************************
* GetPropA (USER32.@)
*/
HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
{
PROPERTY *prop = PROP_FindProp( hwnd, str );
if (HIWORD(str))
TRACE("(%08x,'%s'): returning %08x\n",
hwnd, str, prop ? prop->handle : 0 );
else
TRACE("(%08x,#%04x): returning %08x\n",
hwnd, LOWORD(str), prop ? prop->handle : 0 );
return prop ? prop->handle : 0;
}
/***********************************************************************
* GetPropW (USER32.@)
*/
HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
{
LPSTR strA;
HANDLE ret;
if (!HIWORD(str)) return GetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
ret = GetPropA( hwnd, strA );
HeapFree( GetProcessHeap(), 0, strA );
return ret;
}
/***********************************************************************
* SetPropA (USER32.@)
*/
BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
{
PROPERTY *prop;
if (HIWORD(str))
TRACE("%04x '%s' %08x\n", hwnd, str, handle );
else
TRACE("%04x #%04x %08x\n",
hwnd, LOWORD(str), handle );
if (!(prop = PROP_FindProp( hwnd, str )))
{
/* We need to create it */
WND *pWnd = WIN_FindWndPtr( hwnd );
if (!pWnd) return FALSE;
if (!(prop = HeapAlloc( GetProcessHeap(), 0, sizeof(*prop) )))
{
WIN_ReleaseWndPtr(pWnd);
return FALSE;
}
if (!(prop->string = SEGPTR_STRDUP(str)))
{
HeapFree( GetProcessHeap(), 0, prop );
WIN_ReleaseWndPtr(pWnd);
return FALSE;
}
prop->next = pWnd->pProp;
pWnd->pProp = prop;
WIN_ReleaseWndPtr(pWnd);
}
prop->handle = handle;
return TRUE;
}
/***********************************************************************
* SetPropW (USER32.@)
*/
BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
{
BOOL ret;
LPSTR strA;
if (!HIWORD(str))
return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
ret = SetPropA( hwnd, strA, handle );
HeapFree( GetProcessHeap(), 0, strA );
return ret;
}
/***********************************************************************
* RemovePropA (USER32.@)
*/
HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
{
ATOM atom;
HANDLE handle;
PROPERTY **pprop, *prop;
WND *pWnd = WIN_FindWndPtr( hwnd );
if (HIWORD(str))
TRACE("%04x '%s'\n", hwnd, str );
else
TRACE("%04x #%04x\n", hwnd, LOWORD(str));
if (!pWnd) return (HANDLE)0;
if (HIWORD(str))
{
atom = GlobalFindAtomA( str );
for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
{
if (HIWORD((*pprop)->string))
{
if (!lstrcmpiA( (*pprop)->string, str )) break;
}
else if (LOWORD((*pprop)->string) == atom) break;
}
}
else /* atom */
{
atom = LOWORD(str);
for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
{
if (HIWORD((*pprop)->string))
{
if (GlobalFindAtomA( (*pprop)->string ) == atom) break;
}
else if (LOWORD((*pprop)->string) == atom) break;
}
}
WIN_ReleaseWndPtr(pWnd);
if (!*pprop) return 0;
prop = *pprop;
handle = prop->handle;
*pprop = prop->next;
SEGPTR_FREE(prop->string);
HeapFree( GetProcessHeap(), 0, prop );
return handle;
}
/***********************************************************************
* RemovePropW (USER32.@)
*/
HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
{
LPSTR strA;
HANDLE ret;
if (!HIWORD(str))
return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
ret = RemovePropA( hwnd, strA );
HeapFree( GetProcessHeap(), 0, strA );
return ret;
}
/***********************************************************************
* PROPERTY_RemoveWindowProps
*
* Remove all properties of a window.
*/
void PROPERTY_RemoveWindowProps( HWND hwnd )
{
PROPERTY *prop, *next;
WND *pWnd = WIN_FindWndPtr( hwnd );
if (!pWnd) return;
for (prop = pWnd->pProp; (prop); prop = next)
{
next = prop->next;
SEGPTR_FREE( prop->string );
HeapFree( GetProcessHeap(), 0, prop );
}
pWnd->pProp = NULL;
WIN_ReleaseWndPtr( pWnd );
}
/***********************************************************************
* EnumProps (USER.27)
*/
INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
{
PROPERTY *prop, *next;
WND *pWnd;
INT16 ret = -1;
TRACE("%04x %08x\n", hwnd, (UINT)func );
if (!(pWnd = WIN_FindWndPtr16( hwnd ))) return -1;
for (prop = pWnd->pProp; (prop); prop = next)
{
/* Already get the next in case the callback */
/* function removes the current property. */
next = prop->next;
/* SDK docu seems to suggest that EnumProps16 does not retrieve
* the string in case of an atom handle, in contrast to Win32 */
TRACE(" Callback: handle=%08x str=%s\n",
prop->handle, debugstr_a(prop->string) );
ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
if (!ret) break;
}
WIN_ReleaseWndPtr(pWnd);
return ret;
}
/* relay to call the EnumProps callback function from EnumPropsEx */
static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
{
PROPENUMPROCA func = (PROPENUMPROCA)lparam;
return func( hwnd, str, handle );
}
/***********************************************************************
* EnumPropsA (USER32.@)
*/
INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
{
return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
}
/***********************************************************************
* EnumPropsExA (USER32.@)
*/
INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
{
PROPERTY *prop, *next;
WND *pWnd;
INT ret = -1;
char atomStr[MAX_ATOM_LEN+1];
char *pStr;
TRACE("%04x %p %08lx\n", hwnd, func, lParam);
if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
for (prop = pWnd->pProp; (prop); prop = next)
{
/* Already get the next in case the callback */
/* function removes the current property. */
next = prop->next;
if (!HIWORD(prop->string))
{ /* get "real" string the atom points to.
* This seems to be done for Win32 only */
if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
{
ERR("huh ? Atom %04x not an atom ??\n", LOWORD(prop->string));
atomStr[0] = '\0';
}
pStr = atomStr;
}
else
pStr = prop->string;
TRACE(" Callback: handle=%08x str='%s'\n",
prop->handle, prop->string );
ret = func( hwnd, pStr, prop->handle, lParam );
if (!ret) break;
}
WIN_ReleaseWndPtr(pWnd);
return ret;
}
/* relay to call the EnumProps callback function from EnumPropsEx */
static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
{
PROPENUMPROCW func = (PROPENUMPROCW)lparam;
return func( hwnd, str, handle );
}
/***********************************************************************
* EnumPropsW (USER32.@)
*/
INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
{
return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
}
/***********************************************************************
* EnumPropsExW (USER32.@)
*/
INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
{
PROPERTY *prop, *next;
WND *pWnd;
INT ret = -1;
char atomStr[MAX_ATOM_LEN+1];
char *pStr;
LPWSTR strW;
TRACE("%04x %p %08lx\n", hwnd, func, lParam);
if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
for (prop = pWnd->pProp; (prop); prop = next)
{
/* Already get the next in case the callback */
/* function removes the current property. */
next = prop->next;
if (!HIWORD(prop->string))
{ /* get "real" string the atom points to.
* This seems to be done for Win32 only */
if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
{
ERR("huh ? Atom %04x not an atom ??\n",
(ATOM)LOWORD(prop->string));
atomStr[0] = '\0';
}
pStr = atomStr;
}
else
pStr = prop->string;
TRACE(" Callback: handle=%08x str='%s'\n",
prop->handle, prop->string );
strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
ret = func( hwnd, strW, prop->handle, lParam );
HeapFree( GetProcessHeap(), 0, strW );
if (!ret) break;
}
WIN_ReleaseWndPtr(pWnd);
return ret;
}

View File

@ -549,7 +549,6 @@ static void WIN_DestroyWindow( HWND hwnd )
/* free resources associated with the window */
TIMER_RemoveWindowTimers( hwnd );
PROPERTY_RemoveWindowProps( hwnd );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
wndPtr->hmemTaskQ = 0;
@ -646,7 +645,6 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop->dce = NULL;
pWndDesktop->pVScroll = NULL;
pWndDesktop->pHScroll = NULL;
pWndDesktop->pProp = NULL;
pWndDesktop->wIDmenu = 0;
pWndDesktop->helpContext = 0;
pWndDesktop->flags = 0;
@ -859,7 +857,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32;
wndPtr->pVScroll = NULL;
wndPtr->pHScroll = NULL;
wndPtr->pProp = NULL;
wndPtr->userdata = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
? MENU_GetSysMenu( hwnd, 0 ) : 0;