user32: Implement Get/SetClassLongPtrA/W.

This commit is contained in:
Ge van Geldorp 2006-07-10 08:59:22 +02:00 committed by Alexandre Julliard
parent c142bd9115
commit 54afeb02de
4 changed files with 128 additions and 102 deletions

View File

@ -102,7 +102,7 @@ inline static void release_class_ptr( CLASS *ptr )
* *
* Set class info with the wine server. * Set class info with the wine server.
*/ */
static BOOL set_server_info( HWND hwnd, INT offset, LONG newval ) static BOOL set_server_info( HWND hwnd, INT offset, LONG_PTR newval, UINT size )
{ {
BOOL ret; BOOL ret;
@ -131,8 +131,14 @@ static BOOL set_server_info( HWND hwnd, INT offset, LONG newval )
assert( offset >= 0 ); assert( offset >= 0 );
req->flags = SET_CLASS_EXTRA; req->flags = SET_CLASS_EXTRA;
req->extra_offset = offset; req->extra_offset = offset;
req->extra_size = sizeof(newval); req->extra_size = size;
memcpy( &req->extra_value, &newval, sizeof(newval) ); if ( size == sizeof(LONG) )
{
LONG newlong = newval;
memcpy( &req->extra_value, &newlong, sizeof(LONG) );
}
else
memcpy( &req->extra_value, &newval, sizeof(LONG_PTR) );
break; break;
} }
ret = !wine_server_call_err( req ); ret = !wine_server_call_err( req );
@ -634,12 +640,15 @@ WORD WINAPI GetClassWord( HWND hwnd, INT offset )
/*********************************************************************** /***********************************************************************
* GetClassLongW (USER32.@) * CLASS_GetClassLong
*
* Implementation of GetClassLong(Ptr)A/W
*/ */
DWORD WINAPI GetClassLongW( HWND hwnd, INT offset ) static ULONG_PTR CLASS_GetClassLong( HWND hwnd, INT offset, UINT size,
BOOL unicode )
{ {
CLASS *class; CLASS *class;
DWORD retvalue = 0; ULONG_PTR retvalue = 0;
TRACE("%p %d\n", hwnd, offset); TRACE("%p %d\n", hwnd, offset);
@ -652,7 +661,7 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
req->window = hwnd; req->window = hwnd;
req->flags = 0; req->flags = 0;
req->extra_offset = (offset >= 0) ? offset : -1; req->extra_offset = (offset >= 0) ? offset : -1;
req->extra_size = (offset >= 0) ? sizeof(retvalue) : 0; req->extra_size = (offset >= 0) ? size : 0;
if (!wine_server_call_err( req )) if (!wine_server_call_err( req ))
{ {
switch(offset) switch(offset)
@ -676,13 +685,24 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
retvalue = reply->old_extra; retvalue = reply->old_extra;
break; break;
case GCLP_HMODULE: case GCLP_HMODULE:
retvalue = (DWORD)reply->old_instance; retvalue = (ULONG_PTR)reply->old_instance;
break; break;
case GCW_ATOM: case GCW_ATOM:
retvalue = reply->old_atom; retvalue = reply->old_atom;
break; break;
default: default:
if (offset >= 0) memcpy( &retvalue, &reply->old_extra_value, sizeof(retvalue) ); if (offset >= 0)
{
if (size == sizeof(DWORD))
{
DWORD retdword;
memcpy( &retdword, &reply->old_extra_value, sizeof(DWORD) );
retvalue = retdword;
}
else
memcpy( &retvalue, &reply->old_extra_value,
sizeof(ULONG_PTR) );
}
else SetLastError( ERROR_INVALID_INDEX ); else SetLastError( ERROR_INVALID_INDEX );
break; break;
} }
@ -694,8 +714,17 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
if (offset >= 0) if (offset >= 0)
{ {
if (offset <= class->cbClsExtra - sizeof(LONG)) if (offset <= class->cbClsExtra - size)
memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) ); {
if (size == sizeof(DWORD))
{
DWORD retdword;
memcpy( &retdword, (char *)(class + 1) + offset, sizeof(DWORD) );
retvalue = retdword;
}
else
memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(ULONG_PTR) );
}
else else
SetLastError( ERROR_INVALID_INDEX ); SetLastError( ERROR_INVALID_INDEX );
release_class_ptr( class ); release_class_ptr( class );
@ -705,37 +734,41 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
switch(offset) switch(offset)
{ {
case GCLP_HBRBACKGROUND: case GCLP_HBRBACKGROUND:
retvalue = (DWORD)class->hbrBackground; retvalue = (ULONG_PTR)class->hbrBackground;
break; break;
case GCLP_HCURSOR: case GCLP_HCURSOR:
retvalue = (DWORD)class->hCursor; retvalue = (ULONG_PTR)class->hCursor;
break; break;
case GCLP_HICON: case GCLP_HICON:
retvalue = (DWORD)class->hIcon; retvalue = (ULONG_PTR)class->hIcon;
break; break;
case GCLP_HICONSM: case GCLP_HICONSM:
retvalue = (DWORD)class->hIconSm; retvalue = (ULONG_PTR)class->hIconSm;
break; break;
case GCL_STYLE: case GCL_STYLE:
retvalue = (DWORD)class->style; retvalue = class->style;
break; break;
case GCL_CBWNDEXTRA: case GCL_CBWNDEXTRA:
retvalue = (DWORD)class->cbWndExtra; retvalue = class->cbWndExtra;
break; break;
case GCL_CBCLSEXTRA: case GCL_CBCLSEXTRA:
retvalue = (DWORD)class->cbClsExtra; retvalue = class->cbClsExtra;
break; break;
case GCLP_HMODULE: case GCLP_HMODULE:
retvalue = (DWORD)class->hInstance; retvalue = (ULONG_PTR)class->hInstance;
break; break;
case GCLP_WNDPROC: case GCLP_WNDPROC:
retvalue = (DWORD)WINPROC_GetProc( class->winproc, TRUE ); retvalue = (ULONG_PTR)WINPROC_GetProc( class->winproc, unicode );
break; break;
case GCLP_MENUNAME: case GCLP_MENUNAME:
retvalue = (DWORD)CLASS_GetMenuNameW( class ); retvalue = (ULONG_PTR)CLASS_GetMenuNameW( class );
if (unicode)
retvalue = (ULONG_PTR)CLASS_GetMenuNameW( class );
else
retvalue = (ULONG_PTR)CLASS_GetMenuNameA( class );
break; break;
case GCW_ATOM: case GCW_ATOM:
retvalue = (DWORD)class->atomName; retvalue = class->atomName;
break; break;
default: default:
SetLastError( ERROR_INVALID_INDEX ); SetLastError( ERROR_INVALID_INDEX );
@ -746,35 +779,22 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
} }
/***********************************************************************
* GetClassLongW (USER32.@)
*/
DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
{
return CLASS_GetClassLong( hwnd, offset, sizeof(DWORD), TRUE );
}
/*********************************************************************** /***********************************************************************
* GetClassLongA (USER32.@) * GetClassLongA (USER32.@)
*/ */
DWORD WINAPI GetClassLongA( HWND hwnd, INT offset ) DWORD WINAPI GetClassLongA( HWND hwnd, INT offset )
{ {
CLASS *class; return CLASS_GetClassLong( hwnd, offset, sizeof(DWORD), FALSE );
DWORD retvalue;
if (offset != GCLP_WNDPROC && offset != GCLP_MENUNAME)
return GetClassLongW( hwnd, offset );
TRACE("%p %d\n", hwnd, offset);
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == CLASS_OTHER_PROCESS)
{
FIXME( "offset %d not supported on other process window %p\n", offset, hwnd );
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
if (offset == GCLP_WNDPROC)
retvalue = (DWORD)WINPROC_GetProc( class->winproc, FALSE );
else /* GCL_MENUNAME */
retvalue = (DWORD)CLASS_GetMenuNameA( class );
release_class_ptr( class );
return retvalue;
} }
@ -813,12 +833,15 @@ WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
/*********************************************************************** /***********************************************************************
* SetClassLongW (USER32.@) * CLASS_SetClassLong
*
* Implementation of SetClassLong(Ptr)A/W
*/ */
DWORD WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval ) static ULONG_PTR CLASS_SetClassLong( HWND hwnd, INT offset, LONG_PTR newval,
UINT size, BOOL unicode )
{ {
CLASS *class; CLASS *class;
DWORD retval = 0; ULONG_PTR retval = 0;
TRACE("%p %d %lx\n", hwnd, offset, newval); TRACE("%p %d %lx\n", hwnd, offset, newval);
@ -826,57 +849,72 @@ DWORD WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
if (offset >= 0) if (offset >= 0)
{ {
if (set_server_info( hwnd, offset, newval )) if (set_server_info( hwnd, offset, newval, size ))
{ {
void *ptr = (char *)(class + 1) + offset; void *ptr = (char *)(class + 1) + offset;
memcpy( &retval, ptr, sizeof(retval) ); if ( size == sizeof(LONG) )
memcpy( ptr, &newval, sizeof(newval) ); {
DWORD retdword;
LONG newlong = newval;
memcpy( &retdword, ptr, sizeof(DWORD) );
memcpy( ptr, &newlong, sizeof(LONG) );
retval = retdword;
}
else
{
memcpy( &retval, ptr, sizeof(ULONG_PTR) );
memcpy( ptr, &newval, sizeof(LONG_PTR) );
}
} }
} }
else switch(offset) else switch(offset)
{ {
case GCLP_MENUNAME: case GCLP_MENUNAME:
CLASS_SetMenuNameW( class, (LPCWSTR)newval ); if ( unicode )
CLASS_SetMenuNameW( class, (LPCWSTR)newval );
else
CLASS_SetMenuNameA( class, (LPCSTR)newval );
retval = 0; /* Old value is now meaningless anyway */ retval = 0; /* Old value is now meaningless anyway */
break; break;
case GCLP_WNDPROC: case GCLP_WNDPROC:
retval = (DWORD)WINPROC_GetProc( class->winproc, TRUE ); retval = (ULONG_PTR)WINPROC_GetProc( class->winproc, unicode );
class->winproc = WINPROC_AllocProc( NULL, (WNDPROC)newval ); class->winproc = WINPROC_AllocProc( unicode ? NULL : (WNDPROC)newval,
unicode ? (WNDPROC)newval : NULL );
break; break;
case GCLP_HBRBACKGROUND: case GCLP_HBRBACKGROUND:
retval = (DWORD)class->hbrBackground; retval = (ULONG_PTR)class->hbrBackground;
class->hbrBackground = (HBRUSH)newval; class->hbrBackground = (HBRUSH)newval;
break; break;
case GCLP_HCURSOR: case GCLP_HCURSOR:
retval = (DWORD)class->hCursor; retval = (ULONG_PTR)class->hCursor;
class->hCursor = (HCURSOR)newval; class->hCursor = (HCURSOR)newval;
break; break;
case GCLP_HICON: case GCLP_HICON:
retval = (DWORD)class->hIcon; retval = (ULONG_PTR)class->hIcon;
class->hIcon = (HICON)newval; class->hIcon = (HICON)newval;
break; break;
case GCLP_HICONSM: case GCLP_HICONSM:
retval = (DWORD)class->hIconSm; retval = (ULONG_PTR)class->hIconSm;
class->hIconSm = (HICON)newval; class->hIconSm = (HICON)newval;
break; break;
case GCL_STYLE: case GCL_STYLE:
if (!set_server_info( hwnd, offset, newval )) break; if (!set_server_info( hwnd, offset, newval, size )) break;
retval = (DWORD)class->style; retval = class->style;
class->style = newval; class->style = newval;
break; break;
case GCL_CBWNDEXTRA: case GCL_CBWNDEXTRA:
if (!set_server_info( hwnd, offset, newval )) break; if (!set_server_info( hwnd, offset, newval, size )) break;
retval = (DWORD)class->cbWndExtra; retval = class->cbWndExtra;
class->cbWndExtra = newval; class->cbWndExtra = newval;
break; break;
case GCLP_HMODULE: case GCLP_HMODULE:
if (!set_server_info( hwnd, offset, newval )) break; if (!set_server_info( hwnd, offset, newval, size )) break;
retval = (DWORD)class->hInstance; retval = (ULONG_PTR)class->hInstance;
class->hInstance = (HINSTANCE)newval; class->hInstance = (HINSTANCE)newval;
break; break;
case GCW_ATOM: case GCW_ATOM:
if (!set_server_info( hwnd, offset, newval )) break; if (!set_server_info( hwnd, offset, newval, size )) break;
retval = (DWORD)class->atomName; retval = class->atomName;
class->atomName = newval; class->atomName = newval;
break; break;
case GCL_CBCLSEXTRA: /* cannot change this one */ case GCL_CBCLSEXTRA: /* cannot change this one */
@ -891,33 +929,25 @@ DWORD WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
} }
/***********************************************************************
* SetClassLongW (USER32.@)
*/
DWORD WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
{
TRACE("%p %d %lx\n", hwnd, offset, newval);
return CLASS_SetClassLong( hwnd, offset, newval, sizeof(LONG), TRUE );
}
/*********************************************************************** /***********************************************************************
* SetClassLongA (USER32.@) * SetClassLongA (USER32.@)
*/ */
DWORD WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval ) DWORD WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
{ {
CLASS *class;
DWORD retval;
if (offset != GCLP_WNDPROC && offset != GCLP_MENUNAME)
return SetClassLongW( hwnd, offset, newval );
TRACE("%p %d %lx\n", hwnd, offset, newval); TRACE("%p %d %lx\n", hwnd, offset, newval);
if (!(class = get_class_ptr( hwnd, TRUE ))) return 0; return CLASS_SetClassLong( hwnd, offset, newval, sizeof(LONG), FALSE );
if (offset == GCLP_WNDPROC)
{
retval = (DWORD)WINPROC_GetProc( class->winproc, FALSE );
class->winproc = WINPROC_AllocProc( (WNDPROC)newval, NULL );
}
else /* GCL_MENUNAME */
{
CLASS_SetMenuNameA( class, (LPCSTR)newval );
retval = 0; /* Old value is now meaningless anyway */
}
release_class_ptr( class );
return retval;
} }
@ -1144,8 +1174,7 @@ BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
*/ */
ULONG_PTR WINAPI GetClassLongPtrA( HWND hwnd, INT offset ) ULONG_PTR WINAPI GetClassLongPtrA( HWND hwnd, INT offset )
{ {
FIXME("\n"); return CLASS_GetClassLong( hwnd, offset, sizeof(ULONG_PTR), FALSE );
return 0;
} }
/*********************************************************************** /***********************************************************************
@ -1153,8 +1182,7 @@ ULONG_PTR WINAPI GetClassLongPtrA( HWND hwnd, INT offset )
*/ */
ULONG_PTR WINAPI GetClassLongPtrW( HWND hwnd, INT offset ) ULONG_PTR WINAPI GetClassLongPtrW( HWND hwnd, INT offset )
{ {
FIXME("\n"); return CLASS_GetClassLong( hwnd, offset, sizeof(ULONG_PTR), TRUE );
return 0;
} }
/*********************************************************************** /***********************************************************************
@ -1162,8 +1190,7 @@ ULONG_PTR WINAPI GetClassLongPtrW( HWND hwnd, INT offset )
*/ */
ULONG_PTR WINAPI SetClassLongPtrW( HWND hwnd, INT offset, LONG_PTR newval ) ULONG_PTR WINAPI SetClassLongPtrW( HWND hwnd, INT offset, LONG_PTR newval )
{ {
FIXME("\n"); return CLASS_SetClassLong( hwnd, offset, newval, sizeof(LONG_PTR), TRUE );
return 0;
} }
/*********************************************************************** /***********************************************************************
@ -1171,6 +1198,5 @@ ULONG_PTR WINAPI SetClassLongPtrW( HWND hwnd, INT offset, LONG_PTR newval )
*/ */
ULONG_PTR WINAPI SetClassLongPtrA( HWND hwnd, INT offset, LONG_PTR newval ) ULONG_PTR WINAPI SetClassLongPtrA( HWND hwnd, INT offset, LONG_PTR newval )
{ {
FIXME("\n"); return CLASS_SetClassLong( hwnd, offset, newval, sizeof(LONG_PTR), FALSE );
return 0;
} }

View File

@ -3401,7 +3401,7 @@ struct set_class_info_request
void* instance; void* instance;
int extra_offset; int extra_offset;
size_t extra_size; size_t extra_size;
unsigned int extra_value; unsigned long extra_value;
}; };
struct set_class_info_reply struct set_class_info_reply
{ {
@ -3411,7 +3411,7 @@ struct set_class_info_reply
int old_extra; int old_extra;
int old_win_extra; int old_win_extra;
void* old_instance; void* old_instance;
unsigned int old_extra_value; unsigned long old_extra_value;
}; };
#define SET_CLASS_ATOM 0x0001 #define SET_CLASS_ATOM 0x0001
#define SET_CLASS_STYLE 0x0002 #define SET_CLASS_STYLE 0x0002
@ -4382,6 +4382,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 236 #define SERVER_PROTOCOL_VERSION 237
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -2384,14 +2384,14 @@ enum message_type
void* instance; /* module instance */ void* instance; /* module instance */
int extra_offset; /* offset to set in extra bytes */ int extra_offset; /* offset to set in extra bytes */
size_t extra_size; /* size 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 */ unsigned long extra_value; /* value to set in extra bytes */
@REPLY @REPLY
atom_t old_atom; /* previous class atom */ atom_t old_atom; /* previous class atom */
unsigned int old_style; /* previous class style */ unsigned int old_style; /* previous class style */
int old_extra; /* previous number of class extra bytes */ int old_extra; /* previous number of class extra bytes */
int old_win_extra; /* previous number of window extra bytes */ int old_win_extra; /* previous number of window extra bytes */
void* old_instance; /* previous module instance */ void* old_instance; /* previous module instance */
unsigned int old_extra_value; /* old value in extra bytes */ unsigned long old_extra_value; /* old value in extra bytes */
@END @END
#define SET_CLASS_ATOM 0x0001 #define SET_CLASS_ATOM 0x0001
#define SET_CLASS_STYLE 0x0002 #define SET_CLASS_STYLE 0x0002

View File

@ -2983,7 +2983,7 @@ static void dump_set_class_info_request( const struct set_class_info_request *re
fprintf( stderr, " instance=%p,", req->instance ); fprintf( stderr, " instance=%p,", req->instance );
fprintf( stderr, " extra_offset=%d,", req->extra_offset ); fprintf( stderr, " extra_offset=%d,", req->extra_offset );
fprintf( stderr, " extra_size=%lu,", (unsigned long)req->extra_size ); fprintf( stderr, " extra_size=%lu,", (unsigned long)req->extra_size );
fprintf( stderr, " extra_value=%08x", req->extra_value ); fprintf( stderr, " extra_value=%lx", req->extra_value );
} }
static void dump_set_class_info_reply( const struct set_class_info_reply *req ) static void dump_set_class_info_reply( const struct set_class_info_reply *req )
@ -2993,7 +2993,7 @@ static void dump_set_class_info_reply( const struct set_class_info_reply *req )
fprintf( stderr, " old_extra=%d,", req->old_extra ); fprintf( stderr, " old_extra=%d,", req->old_extra );
fprintf( stderr, " old_win_extra=%d,", req->old_win_extra ); fprintf( stderr, " old_win_extra=%d,", req->old_win_extra );
fprintf( stderr, " old_instance=%p,", req->old_instance ); fprintf( stderr, " old_instance=%p,", req->old_instance );
fprintf( stderr, " old_extra_value=%08x", req->old_extra_value ); fprintf( stderr, " old_extra_value=%lx", req->old_extra_value );
} }
static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req ) static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req )