mirror of
https://github.com/reactos/wine.git
synced 2024-12-11 21:36:20 +00:00
user32: Enable window class redirection.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
31c7a7157d
commit
bdb048a50e
@ -161,6 +161,32 @@ static BOOL is_comctl32_class( const WCHAR *name )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL is_builtin_class( const WCHAR *name )
|
||||||
|
{
|
||||||
|
static const WCHAR classesW[][20] =
|
||||||
|
{
|
||||||
|
{'B','u','t','t','o','n',0},
|
||||||
|
{'C','o','m','b','o','B','o','x',0},
|
||||||
|
{'C','o','m','b','o','L','B','o','x',0},
|
||||||
|
{'E','d','i','t',0},
|
||||||
|
{'I','M','E',0},
|
||||||
|
{'L','i','s','t','B','o','x',0},
|
||||||
|
{'M','D','I','C','l','i','e','n','t',0},
|
||||||
|
{'S','c','r','o','l','l','b','a','r',0},
|
||||||
|
{'S','t','a','t','i','c',0},
|
||||||
|
};
|
||||||
|
|
||||||
|
int min = 0, max = (sizeof(classesW) / sizeof(classesW[0])) - 1;
|
||||||
|
|
||||||
|
while (min <= max)
|
||||||
|
{
|
||||||
|
int res, pos = (min + max) / 2;
|
||||||
|
if (!(res = strcmpiW( name, classesW[pos] ))) return TRUE;
|
||||||
|
if (res < 0) max = pos - 1;
|
||||||
|
else min = pos + 1;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* set_server_info
|
* set_server_info
|
||||||
@ -299,6 +325,32 @@ static void CLASS_FreeClass( CLASS *classPtr )
|
|||||||
USER_Unlock();
|
USER_Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const WCHAR *CLASS_GetVersionedName( const WCHAR *name )
|
||||||
|
{
|
||||||
|
ACTCTX_SECTION_KEYED_DATA data;
|
||||||
|
struct wndclass_redirect_data
|
||||||
|
{
|
||||||
|
ULONG size;
|
||||||
|
DWORD res;
|
||||||
|
ULONG name_len;
|
||||||
|
ULONG name_offset;
|
||||||
|
ULONG module_len;
|
||||||
|
ULONG module_offset;
|
||||||
|
} *wndclass;
|
||||||
|
|
||||||
|
if (IS_INTRESOURCE( name ))
|
||||||
|
return name;
|
||||||
|
|
||||||
|
if (is_comctl32_class( name ) || is_builtin_class( name ))
|
||||||
|
return name;
|
||||||
|
|
||||||
|
data.cbSize = sizeof(data);
|
||||||
|
if (!FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, name, &data))
|
||||||
|
return name;
|
||||||
|
|
||||||
|
wndclass = (struct wndclass_redirect_data *)data.lpData;
|
||||||
|
return (const WCHAR *)((BYTE *)wndclass + wndclass->name_offset);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CLASS_FindClass
|
* CLASS_FindClass
|
||||||
@ -315,6 +367,8 @@ static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance )
|
|||||||
|
|
||||||
if (!name) return NULL;
|
if (!name) return NULL;
|
||||||
|
|
||||||
|
name = CLASS_GetVersionedName( name );
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
USER_Lock();
|
USER_Lock();
|
||||||
@ -561,6 +615,8 @@ ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
|
|||||||
*/
|
*/
|
||||||
ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
||||||
{
|
{
|
||||||
|
const WCHAR *classname = NULL;
|
||||||
|
WCHAR name[MAX_ATOM_LEN + 1];
|
||||||
ATOM atom;
|
ATOM atom;
|
||||||
CLASS *classPtr;
|
CLASS *classPtr;
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
@ -577,10 +633,9 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
|||||||
|
|
||||||
if (!IS_INTRESOURCE(wc->lpszClassName))
|
if (!IS_INTRESOURCE(wc->lpszClassName))
|
||||||
{
|
{
|
||||||
WCHAR name[MAX_ATOM_LEN + 1];
|
|
||||||
|
|
||||||
if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, name, MAX_ATOM_LEN + 1 )) 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),
|
classname = CLASS_GetVersionedName( name );
|
||||||
|
classPtr = CLASS_RegisterClass( classname, instance, !(wc->style & CS_GLOBALCLASS),
|
||||||
wc->style, wc->cbClsExtra, wc->cbWndExtra );
|
wc->style, wc->cbClsExtra, wc->cbWndExtra );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -592,9 +647,9 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
|||||||
if (!classPtr) return 0;
|
if (!classPtr) return 0;
|
||||||
atom = classPtr->atomName;
|
atom = classPtr->atomName;
|
||||||
|
|
||||||
TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
TRACE("name=%s%s%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,
|
debugstr_a(wc->lpszClassName), classname != name ? "->" : "", classname != name ? debugstr_w(classname) : "",
|
||||||
wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
|
atom, wc->lpfnWndProc, instance, wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
|
||||||
|
|
||||||
classPtr->hIcon = wc->hIcon;
|
classPtr->hIcon = wc->hIcon;
|
||||||
classPtr->hIconSm = wc->hIconSm;
|
classPtr->hIconSm = wc->hIconSm;
|
||||||
@ -617,6 +672,7 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
|||||||
*/
|
*/
|
||||||
ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
|
ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
|
||||||
{
|
{
|
||||||
|
const WCHAR *classname;
|
||||||
ATOM atom;
|
ATOM atom;
|
||||||
CLASS *classPtr;
|
CLASS *classPtr;
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
@ -631,15 +687,17 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
|
|||||||
}
|
}
|
||||||
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
|
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
|
||||||
|
|
||||||
if (!(classPtr = CLASS_RegisterClass( wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS),
|
classname = CLASS_GetVersionedName( wc->lpszClassName );
|
||||||
|
if (!(classPtr = CLASS_RegisterClass( classname, instance, !(wc->style & CS_GLOBALCLASS),
|
||||||
wc->style, wc->cbClsExtra, wc->cbWndExtra )))
|
wc->style, wc->cbClsExtra, wc->cbWndExtra )))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
atom = classPtr->atomName;
|
atom = classPtr->atomName;
|
||||||
|
|
||||||
TRACE("name=%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
TRACE("name=%s%s%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,
|
debugstr_w(wc->lpszClassName), classname != wc->lpszClassName ? "->" : "",
|
||||||
wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
|
classname != wc->lpszClassName ? debugstr_w(classname) : "", atom, wc->lpfnWndProc, instance,
|
||||||
|
wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
|
||||||
|
|
||||||
classPtr->hIcon = wc->hIcon;
|
classPtr->hIcon = wc->hIcon;
|
||||||
classPtr->hIconSm = wc->hIconSm;
|
classPtr->hIconSm = wc->hIconSm;
|
||||||
@ -682,6 +740,7 @@ BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
|
|||||||
|
|
||||||
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
|
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
|
||||||
|
|
||||||
|
className = CLASS_GetVersionedName( className );
|
||||||
SERVER_START_REQ( destroy_class )
|
SERVER_START_REQ( destroy_class )
|
||||||
{
|
{
|
||||||
req->instance = wine_server_client_ptr( hInstance );
|
req->instance = wine_server_client_ptr( hInstance );
|
||||||
|
@ -1243,7 +1243,6 @@ static void test_actctx_classes(void)
|
|||||||
ok(ret, "Failed to get class info.\n");
|
ok(ret, "Failed to get class info.\n");
|
||||||
|
|
||||||
ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
|
ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
|
||||||
todo_wine
|
|
||||||
ok(ret, "Failed to get class info.\n");
|
ok(ret, "Failed to get class info.\n");
|
||||||
|
|
||||||
ret = UnregisterClassA("MyTestClass", hinst);
|
ret = UnregisterClassA("MyTestClass", hinst);
|
||||||
@ -1262,7 +1261,6 @@ todo_wine
|
|||||||
|
|
||||||
wc.lpszClassName = "MyTestClass";
|
wc.lpszClassName = "MyTestClass";
|
||||||
class = RegisterClassA(&wc);
|
class = RegisterClassA(&wc);
|
||||||
todo_wine
|
|
||||||
ok(class == 0, "Expected failure.\n");
|
ok(class == 0, "Expected failure.\n");
|
||||||
|
|
||||||
ret = DeactivateActCtx(0, cookie);
|
ret = DeactivateActCtx(0, cookie);
|
||||||
@ -1277,28 +1275,23 @@ todo_wine
|
|||||||
|
|
||||||
wc.lpszClassName = "MyTestClass";
|
wc.lpszClassName = "MyTestClass";
|
||||||
class = RegisterClassA(&wc);
|
class = RegisterClassA(&wc);
|
||||||
todo_wine
|
|
||||||
ok(class != 0, "Failed to register class\n");
|
ok(class != 0, "Failed to register class\n");
|
||||||
|
|
||||||
ret = DeactivateActCtx(0, cookie);
|
ret = DeactivateActCtx(0, cookie);
|
||||||
ok(ret, "Failed to deactivate context.\n");
|
ok(ret, "Failed to deactivate context.\n");
|
||||||
|
|
||||||
ret = GetClassInfoA(hinst, "MyTestClass", &wc);
|
ret = GetClassInfoA(hinst, "MyTestClass", &wc);
|
||||||
todo_wine
|
|
||||||
ok(!ret, "Expected failure.\n");
|
ok(!ret, "Expected failure.\n");
|
||||||
|
|
||||||
ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
|
ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc);
|
||||||
todo_wine
|
|
||||||
ok(ret, "Failed to get class info.\n");
|
ok(ret, "Failed to get class info.\n");
|
||||||
|
|
||||||
ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
|
ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
|
||||||
todo_wine
|
|
||||||
ok(ret, "Failed to unregister class.\n");
|
ok(ret, "Failed to unregister class.\n");
|
||||||
|
|
||||||
/* Register regular name first, it's not considered when versioned name is registered. */
|
/* Register regular name first, it's not considered when versioned name is registered. */
|
||||||
wc.lpszClassName = "MyTestClass";
|
wc.lpszClassName = "MyTestClass";
|
||||||
class = RegisterClassA(&wc);
|
class = RegisterClassA(&wc);
|
||||||
todo_wine
|
|
||||||
ok(class != 0, "Failed to register class.\n");
|
ok(class != 0, "Failed to register class.\n");
|
||||||
|
|
||||||
ret = ActivateActCtx(context, &cookie);
|
ret = ActivateActCtx(context, &cookie);
|
||||||
@ -1306,14 +1299,12 @@ todo_wine
|
|||||||
|
|
||||||
wc.lpszClassName = "MyTestClass";
|
wc.lpszClassName = "MyTestClass";
|
||||||
class = RegisterClassA(&wc);
|
class = RegisterClassA(&wc);
|
||||||
todo_wine
|
|
||||||
ok(class != 0, "Failed to register class.\n");
|
ok(class != 0, "Failed to register class.\n");
|
||||||
|
|
||||||
ret = DeactivateActCtx(0, cookie);
|
ret = DeactivateActCtx(0, cookie);
|
||||||
ok(ret, "Failed to deactivate context.\n");
|
ok(ret, "Failed to deactivate context.\n");
|
||||||
|
|
||||||
ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
|
ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst);
|
||||||
todo_wine
|
|
||||||
ok(ret, "Failed to unregister class.\n");
|
ok(ret, "Failed to unregister class.\n");
|
||||||
|
|
||||||
ret = UnregisterClassA("MyTestClass", hinst);
|
ret = UnregisterClassA("MyTestClass", hinst);
|
||||||
|
Loading…
Reference in New Issue
Block a user