user32: Cache the window class name on the client side.
This commit is contained in:
parent
1ee62a8d72
commit
8b42238b5b
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(class);
|
WINE_DEFAULT_DEBUG_CHANNEL(class);
|
||||||
|
|
||||||
|
#define MAX_ATOM_LEN 255 /* from dlls/kernel32/atom.c */
|
||||||
|
|
||||||
typedef struct tagCLASS
|
typedef struct tagCLASS
|
||||||
{
|
{
|
||||||
struct list entry; /* Entry in class list */
|
struct list entry; /* Entry in class list */
|
||||||
|
@ -56,12 +58,12 @@ typedef struct tagCLASS
|
||||||
HCURSOR hCursor; /* Default cursor */
|
HCURSOR hCursor; /* Default cursor */
|
||||||
HBRUSH hbrBackground; /* Default background */
|
HBRUSH hbrBackground; /* Default background */
|
||||||
ATOM atomName; /* Name of the class */
|
ATOM atomName; /* Name of the class */
|
||||||
|
WCHAR name[MAX_ATOM_LEN + 1];
|
||||||
} CLASS;
|
} CLASS;
|
||||||
|
|
||||||
static struct list class_list = LIST_INIT( class_list );
|
static struct list class_list = LIST_INIT( class_list );
|
||||||
|
|
||||||
#define CLASS_OTHER_PROCESS ((CLASS *)1)
|
#define CLASS_OTHER_PROCESS ((CLASS *)1)
|
||||||
#define MAX_ATOM_LEN 255 /* from dlls/kernel32/atom.c */
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* get_class_ptr
|
* get_class_ptr
|
||||||
|
@ -283,29 +285,37 @@ void CLASS_FreeModuleClasses( HMODULE16 hModule )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CLASS_FindClassByAtom
|
* CLASS_FindClass
|
||||||
*
|
*
|
||||||
* Return a pointer to the class.
|
* Return a pointer to the class.
|
||||||
* hinstance has been normalized by the caller.
|
* hinstance has been normalized by the caller.
|
||||||
*/
|
*/
|
||||||
static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
|
static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance )
|
||||||
{
|
{
|
||||||
struct list *ptr;
|
struct list *ptr;
|
||||||
|
ATOM atom = get_int_atom_value( name );
|
||||||
|
|
||||||
USER_Lock();
|
USER_Lock();
|
||||||
|
|
||||||
LIST_FOR_EACH( ptr, &class_list )
|
LIST_FOR_EACH( ptr, &class_list )
|
||||||
{
|
{
|
||||||
CLASS *class = LIST_ENTRY( ptr, CLASS, entry );
|
CLASS *class = LIST_ENTRY( ptr, CLASS, entry );
|
||||||
if (class->atomName != atom) continue;
|
if (atom)
|
||||||
|
{
|
||||||
|
if (class->atomName != atom) continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!name || strcmpiW( class->name, name )) continue;
|
||||||
|
}
|
||||||
if (!hinstance || !class->local || class->hInstance == hinstance)
|
if (!hinstance || !class->local || class->hInstance == hinstance)
|
||||||
{
|
{
|
||||||
TRACE("0x%04x %p -> %p\n", atom, hinstance, class);
|
TRACE("%s %p -> %p\n", debugstr_w(name), hinstance, class);
|
||||||
return class;
|
return class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
USER_Unlock();
|
USER_Unlock();
|
||||||
TRACE("0x%04x %p -> not found\n", atom, hinstance);
|
TRACE("%s %p -> not found\n", debugstr_w(name), hinstance);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +349,10 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, HINSTANCE hInstance, BOOL local
|
||||||
classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
|
classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
|
||||||
if (!classPtr) return NULL;
|
if (!classPtr) return NULL;
|
||||||
|
|
||||||
|
classPtr->atomName = get_int_atom_value( name );
|
||||||
|
if (!classPtr->atomName && name) strcpyW( classPtr->name, name );
|
||||||
|
else GlobalGetAtomNameW( classPtr->atomName, classPtr->name, sizeof(classPtr->name)/sizeof(WCHAR) );
|
||||||
|
|
||||||
SERVER_START_REQ( create_class )
|
SERVER_START_REQ( create_class )
|
||||||
{
|
{
|
||||||
req->local = local;
|
req->local = local;
|
||||||
|
@ -347,8 +361,8 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, HINSTANCE hInstance, BOOL local
|
||||||
req->extra = classExtra;
|
req->extra = classExtra;
|
||||||
req->win_extra = winExtra;
|
req->win_extra = winExtra;
|
||||||
req->client_ptr = classPtr;
|
req->client_ptr = classPtr;
|
||||||
if (!(req->atom = get_int_atom_value(name)) && name)
|
req->atom = classPtr->atomName;
|
||||||
wine_server_add_data( req, name, strlenW(name) * sizeof(WCHAR) );
|
if (!req->atom && name) wine_server_add_data( req, name, strlenW(name) * sizeof(WCHAR) );
|
||||||
ret = !wine_server_call_err( req );
|
ret = !wine_server_call_err( req );
|
||||||
classPtr->atomName = reply->atom;
|
classPtr->atomName = reply->atom;
|
||||||
}
|
}
|
||||||
|
@ -942,6 +956,7 @@ static ULONG_PTR CLASS_SetClassLong( HWND hwnd, INT offset, LONG_PTR newval,
|
||||||
if (!set_server_info( hwnd, offset, newval, size )) break;
|
if (!set_server_info( hwnd, offset, newval, size )) break;
|
||||||
retval = class->atomName;
|
retval = class->atomName;
|
||||||
class->atomName = newval;
|
class->atomName = newval;
|
||||||
|
GlobalGetAtomNameW( newval, class->name, sizeof(class->name)/sizeof(WCHAR) );
|
||||||
break;
|
break;
|
||||||
case GCL_CBCLSEXTRA: /* cannot change this one */
|
case GCL_CBCLSEXTRA: /* cannot change this one */
|
||||||
SetLastError( ERROR_INVALID_PARAMETER );
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
@ -982,21 +997,14 @@ DWORD WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
|
||||||
*/
|
*/
|
||||||
INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
|
INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
|
||||||
{
|
{
|
||||||
char tmpbuf[MAX_ATOM_LEN + 1];
|
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
|
||||||
INT ret;
|
DWORD len;
|
||||||
|
|
||||||
TRACE("%p %p %d\n", hwnd, buffer, count);
|
|
||||||
|
|
||||||
if (count <= 0) return 0;
|
if (count <= 0) return 0;
|
||||||
|
if (!GetClassNameW( hwnd, tmpbuf, sizeof(tmpbuf)/sizeof(WCHAR) )) return 0;
|
||||||
ret = GlobalGetAtomNameA( GetClassLongW( hwnd, GCW_ATOM ), tmpbuf, MAX_ATOM_LEN + 1 );
|
RtlUnicodeToMultiByteN( buffer, count - 1, &len, tmpbuf, strlenW(tmpbuf) * sizeof(WCHAR) );
|
||||||
if (ret)
|
buffer[len] = 0;
|
||||||
{
|
return len;
|
||||||
ret = min(count - 1, ret);
|
|
||||||
memcpy(buffer, tmpbuf, ret);
|
|
||||||
buffer[ret] = 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1005,19 +1013,32 @@ INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
|
||||||
*/
|
*/
|
||||||
INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
|
INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
|
||||||
{
|
{
|
||||||
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
|
CLASS *class;
|
||||||
INT ret;
|
INT ret;
|
||||||
|
|
||||||
TRACE("%p %p %d\n", hwnd, buffer, count);
|
TRACE("%p %p %d\n", hwnd, buffer, count);
|
||||||
|
|
||||||
if (count <= 0) return 0;
|
if (count <= 0) return 0;
|
||||||
|
|
||||||
ret = GlobalGetAtomNameW( GetClassLongW( hwnd, GCW_ATOM ), tmpbuf, MAX_ATOM_LEN + 1 );
|
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
|
||||||
if (ret)
|
|
||||||
|
if (class == CLASS_OTHER_PROCESS)
|
||||||
{
|
{
|
||||||
ret = min(count - 1, ret);
|
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
|
||||||
memcpy(buffer, tmpbuf, ret * sizeof(WCHAR));
|
|
||||||
buffer[ret] = 0;
|
ret = GlobalGetAtomNameW( GetClassLongW( hwnd, GCW_ATOM ), tmpbuf, MAX_ATOM_LEN + 1 );
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
ret = min(count - 1, ret);
|
||||||
|
memcpy(buffer, tmpbuf, ret * sizeof(WCHAR));
|
||||||
|
buffer[ret] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lstrcpynW( buffer, class->name, count );
|
||||||
|
release_class_ptr( class );
|
||||||
|
ret = strlenW( buffer );
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1096,14 +1117,23 @@ BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSW *wc )
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc )
|
BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc )
|
||||||
{
|
{
|
||||||
ATOM atom = HIWORD(name) ? GlobalFindAtomA( name ) : LOWORD(name);
|
ATOM atom;
|
||||||
CLASS *classPtr;
|
CLASS *classPtr;
|
||||||
|
|
||||||
TRACE("%p %s %x %p\n", hInstance, debugstr_a(name), atom, wc);
|
TRACE("%p %s %p\n", hInstance, debugstr_a(name), wc);
|
||||||
|
|
||||||
if (!hInstance) hInstance = user32_module;
|
if (!hInstance) hInstance = user32_module;
|
||||||
|
|
||||||
if (!atom || !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
|
if (!IS_INTRESOURCE(name))
|
||||||
|
{
|
||||||
|
WCHAR nameW[MAX_ATOM_LEN + 1];
|
||||||
|
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) ))
|
||||||
|
return FALSE;
|
||||||
|
classPtr = CLASS_FindClass( nameW, hInstance );
|
||||||
|
}
|
||||||
|
else classPtr = CLASS_FindClass( (LPCWSTR)name, hInstance );
|
||||||
|
|
||||||
|
if (!classPtr)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
|
SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1119,6 +1149,7 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc )
|
||||||
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
|
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
|
||||||
wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
|
wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
|
||||||
wc->lpszClassName = name;
|
wc->lpszClassName = name;
|
||||||
|
atom = classPtr->atomName;
|
||||||
release_class_ptr( classPtr );
|
release_class_ptr( classPtr );
|
||||||
|
|
||||||
/* We must return the atom of the class here instead of just TRUE. */
|
/* We must return the atom of the class here instead of just TRUE. */
|
||||||
|
@ -1131,14 +1162,14 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc )
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc )
|
BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc )
|
||||||
{
|
{
|
||||||
ATOM atom = HIWORD(name) ? GlobalFindAtomW( name ) : LOWORD(name);
|
ATOM atom;
|
||||||
CLASS *classPtr;
|
CLASS *classPtr;
|
||||||
|
|
||||||
TRACE("%p %s %x %p\n", hInstance, debugstr_w(name), atom, wc);
|
TRACE("%p %s %p\n", hInstance, debugstr_w(name), wc);
|
||||||
|
|
||||||
if (!hInstance) hInstance = user32_module;
|
if (!hInstance) hInstance = user32_module;
|
||||||
|
|
||||||
if (!atom || !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
|
if (!(classPtr = CLASS_FindClass( name, hInstance )))
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
|
SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1154,6 +1185,7 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc
|
||||||
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
|
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
|
||||||
wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
|
wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
|
||||||
wc->lpszClassName = name;
|
wc->lpszClassName = name;
|
||||||
|
atom = classPtr->atomName;
|
||||||
release_class_ptr( classPtr );
|
release_class_ptr( classPtr );
|
||||||
|
|
||||||
/* We must return the atom of the class here instead of just TRUE. */
|
/* We must return the atom of the class here instead of just TRUE. */
|
||||||
|
|
Loading…
Reference in New Issue