mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[User32]
- Add context hack from wine. Pass alt tab info calls to win32k. - From wine: Alexandre Julliard : user32: Automatically load comctl32 when one of its classes is requested. svn path=/trunk/; revision=60858
This commit is contained in:
parent
16c4fe33fb
commit
01263aac8b
|
@ -39,3 +39,4 @@ extern const struct builtin_class_descr SCROLL_builtin_class;
|
|||
extern const struct builtin_class_descr STATIC_builtin_class;
|
||||
|
||||
ATOM WINAPI RegisterClassExWOWW(WNDCLASSEXW *,LPDWORD,WORD,DWORD,BOOL);
|
||||
BOOL FASTCALL VersionRegisterClass(PCWSTR,LPCWSTR,HANDLE,HMODULE *);
|
||||
|
|
|
@ -39,7 +39,7 @@ ClassNameToVersion(
|
|||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING SectionName;
|
||||
WCHAR SeactionNameBuf[256] = {0};
|
||||
WCHAR SeactionNameBuf[MAX_PATH] = {0};
|
||||
ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) };
|
||||
|
||||
if (IS_ATOM(lpszClass))
|
||||
|
@ -113,9 +113,12 @@ ClassNameToVersion(
|
|||
return lpszClass;
|
||||
}
|
||||
|
||||
//
|
||||
// Ref: http://yvs-it.blogspot.com/2010/04/initcommoncontrolsex.html
|
||||
//
|
||||
BOOL
|
||||
FASTCALL
|
||||
VersionRegisterClass(
|
||||
Real_VersionRegisterClass(
|
||||
PCWSTR pszClass,
|
||||
LPCWSTR lpLibFileName,
|
||||
HANDLE Contex,
|
||||
|
@ -125,7 +128,7 @@ VersionRegisterClass(
|
|||
HMODULE hLibModule;
|
||||
PREGISTERCLASSNAMEW pRegisterClassNameW;
|
||||
UNICODE_STRING ClassName;
|
||||
WCHAR ClassNameBuf[256] = {0};
|
||||
WCHAR ClassNameBuf[MAX_PATH] = {0};
|
||||
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { sizeof(Frame), 1 };
|
||||
|
||||
RtlActivateActivationContextUnsafeFast(&Frame, Contex);
|
||||
|
@ -174,6 +177,117 @@ Error_Exit:
|
|||
return Ret;
|
||||
}
|
||||
|
||||
//
|
||||
// Use wine hack to process extened context classes.
|
||||
//
|
||||
/***********************************************************************
|
||||
* is_comctl32_class
|
||||
*/
|
||||
static BOOL is_comctl32_class( const WCHAR *name )
|
||||
{
|
||||
static const WCHAR classesW[][20] =
|
||||
{
|
||||
{'C','o','m','b','o','B','o','x','E','x','3','2',0},
|
||||
{'m','s','c','t','l','s','_','h','o','t','k','e','y','3','2',0},
|
||||
{'m','s','c','t','l','s','_','p','r','o','g','r','e','s','s','3','2',0},
|
||||
{'m','s','c','t','l','s','_','s','t','a','t','u','s','b','a','r','3','2',0},
|
||||
{'m','s','c','t','l','s','_','t','r','a','c','k','b','a','r','3','2',0},
|
||||
{'m','s','c','t','l','s','_','u','p','d','o','w','n','3','2',0},
|
||||
{'N','a','t','i','v','e','F','o','n','t','C','t','l',0},
|
||||
{'R','e','B','a','r','W','i','n','d','o','w','3','2',0},
|
||||
{'S','y','s','A','n','i','m','a','t','e','3','2',0},
|
||||
{'S','y','s','D','a','t','e','T','i','m','e','P','i','c','k','3','2',0},
|
||||
{'S','y','s','H','e','a','d','e','r','3','2',0},
|
||||
{'S','y','s','I','P','A','d','d','r','e','s','s','3','2',0},
|
||||
{'S','y','s','L','i','s','t','V','i','e','w','3','2',0},
|
||||
{'S','y','s','M','o','n','t','h','C','a','l','3','2',0},
|
||||
{'S','y','s','P','a','g','e','r',0},
|
||||
{'S','y','s','T','a','b','C','o','n','t','r','o','l','3','2',0},
|
||||
{'S','y','s','T','r','e','e','V','i','e','w','3','2',0},
|
||||
{'T','o','o','l','b','a','r','W','i','n','d','o','w','3','2',0},
|
||||
{'t','o','o','l','t','i','p','s','_','c','l','a','s','s','3','2',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;
|
||||
}
|
||||
|
||||
BOOL
|
||||
FASTCALL
|
||||
VersionRegisterClass(
|
||||
PCWSTR pszClass,
|
||||
LPCWSTR lpLibFileName,
|
||||
HANDLE Contex,
|
||||
HMODULE * phLibModule)
|
||||
{
|
||||
// Should be lpLibFileName.....
|
||||
static const WCHAR comctl32W[] = {'c','o','m','c','t','l','3','2','.','d','l','l',0};
|
||||
//
|
||||
PREGISTERCLASSNAMEW pRegisterClassNameW;
|
||||
UNICODE_STRING ClassName;
|
||||
WCHAR ClassNameBuf[MAX_PATH] = {0};
|
||||
BOOL Ret = FALSE;
|
||||
HMODULE hLibModule = NULL;
|
||||
|
||||
if (is_comctl32_class( pszClass ))
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
hLibModule = GetModuleHandleW( comctl32W );
|
||||
if (!hLibModule) hLibModule = LoadLibraryW(comctl32W);
|
||||
if ( hLibModule )
|
||||
{
|
||||
if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, "RegisterClassNameW")))
|
||||
{
|
||||
if (IS_ATOM(pszClass))
|
||||
{
|
||||
ClassName.Buffer = (LPWSTR)&ClassNameBuf;
|
||||
ClassName.MaximumLength = sizeof(ClassNameBuf);
|
||||
if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), &ClassName))
|
||||
{
|
||||
ERR("Error while verifying ATOM\n");
|
||||
_SEH2_YIELD(goto Error_Exit);
|
||||
}
|
||||
pszClass = (PCWSTR)&ClassNameBuf;
|
||||
}
|
||||
Ret = pRegisterClassNameW(pszClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
Error_Exit:
|
||||
if ( Ret || !hLibModule )
|
||||
{
|
||||
if ( phLibModule ) *phLibModule = hLibModule;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD save_error = GetLastError();
|
||||
FreeLibrary(hLibModule);
|
||||
SetLastError(save_error);
|
||||
}
|
||||
TRACE( "%s retrying after loading comctl32\n", debugstr_w(pszClass) );
|
||||
return Ret;
|
||||
}
|
||||
TRACE("NO ComCtl32 Class %S!\n",pszClass);
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -185,8 +299,10 @@ GetClassInfoExA(
|
|||
LPWNDCLASSEXA lpwcx)
|
||||
{
|
||||
UNICODE_STRING ClassName = {0};
|
||||
BOOL Ret;
|
||||
LPCSTR pszMenuName;
|
||||
HMODULE hLibModule;
|
||||
DWORD save_error;
|
||||
BOOL Ret, ClassFound = FALSE;
|
||||
|
||||
TRACE("%p class/atom: %s/%04x %p\n", hInstance,
|
||||
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
||||
|
@ -230,11 +346,34 @@ GetClassInfoExA(
|
|||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
Ret = NtUserGetClassInfo(hInstance,
|
||||
for(;;)
|
||||
{
|
||||
Ret = NtUserGetClassInfo( hInstance,
|
||||
&ClassName,
|
||||
(LPWNDCLASSEXW)lpwcx,
|
||||
(LPWSTR *)&pszMenuName,
|
||||
TRUE);
|
||||
if (Ret) break;
|
||||
if (!ClassFound)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
|
||||
save_error == ERROR_CLASS_DOES_NOT_EXIST )
|
||||
{
|
||||
ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
|
||||
if (ClassFound) continue;
|
||||
}
|
||||
}
|
||||
if (hLibModule)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
FreeLibrary(hLibModule);
|
||||
SetLastError(save_error);
|
||||
hLibModule = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (Ret)
|
||||
{
|
||||
lpwcx->lpszClassName = lpszClass;
|
||||
|
@ -261,8 +400,10 @@ GetClassInfoExW(
|
|||
LPWNDCLASSEXW lpwcx)
|
||||
{
|
||||
UNICODE_STRING ClassName = {0};
|
||||
BOOL Ret;
|
||||
LPWSTR pszMenuName;
|
||||
HMODULE hLibModule;
|
||||
DWORD save_error;
|
||||
BOOL Ret, ClassFound = FALSE;
|
||||
|
||||
TRACE("%p class/atom: %S/%04x %p\n", hInstance,
|
||||
IS_ATOM(lpszClass) ? NULL : lpszClass,
|
||||
|
@ -305,11 +446,34 @@ GetClassInfoExW(
|
|||
RegisterSystemControls();
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Ret = NtUserGetClassInfo( hInstance,
|
||||
&ClassName,
|
||||
lpwcx,
|
||||
&pszMenuName,
|
||||
FALSE);
|
||||
if (Ret) break;
|
||||
if (!ClassFound)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
|
||||
save_error == ERROR_CLASS_DOES_NOT_EXIST )
|
||||
{
|
||||
ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
|
||||
if (ClassFound) continue;
|
||||
}
|
||||
}
|
||||
if (hLibModule)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
FreeLibrary(hLibModule);
|
||||
SetLastError(save_error);
|
||||
hLibModule = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (Ret)
|
||||
{
|
||||
lpwcx->lpszClassName = lpszClass;
|
||||
|
@ -1265,6 +1429,9 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
|||
UNICODE_STRING MenuName = {0};
|
||||
CLSMENUNAME clsMenuName;
|
||||
ANSI_STRING AnsiMenuName;
|
||||
HMODULE hLibModule;
|
||||
DWORD save_error;
|
||||
BOOL ClassFound = FALSE;
|
||||
|
||||
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
|
||||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
||||
|
@ -1338,6 +1505,8 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
|||
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
|
||||
clsMenuName.pusMenuName = &MenuName;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Atom = NtUserRegisterClassExWOW( &WndClass,
|
||||
&ClassName,
|
||||
NULL, //PUNICODE_STRING ClsNVersion,
|
||||
|
@ -1346,6 +1515,27 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
|
|||
dwFlags,
|
||||
pdwWowData);
|
||||
|
||||
if (Atom) break;
|
||||
if (!ClassFound)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
|
||||
save_error == ERROR_CLASS_DOES_NOT_EXIST )
|
||||
{
|
||||
ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
|
||||
if (ClassFound) continue;
|
||||
}
|
||||
}
|
||||
if (hLibModule)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
FreeLibrary(hLibModule);
|
||||
SetLastError(save_error);
|
||||
hLibModule = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
||||
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
|
||||
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
|
||||
|
|
|
@ -169,7 +169,9 @@ User32CreateWindowEx(DWORD dwExStyle,
|
|||
UNICODE_STRING ClassName;
|
||||
WNDCLASSEXA wceA;
|
||||
WNDCLASSEXW wceW;
|
||||
BOOL Unicode;
|
||||
HMODULE hLibModule;
|
||||
DWORD save_error;
|
||||
BOOL Unicode, ClassFound = FALSE;
|
||||
HWND Handle = NULL;
|
||||
|
||||
#if 0
|
||||
|
@ -262,6 +264,8 @@ User32CreateWindowEx(DWORD dwExStyle,
|
|||
|
||||
if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Handle = NtUserCreateWindowEx(dwExStyle,
|
||||
plstrClassName,
|
||||
NULL,
|
||||
|
@ -277,6 +281,25 @@ User32CreateWindowEx(DWORD dwExStyle,
|
|||
lpParam,
|
||||
dwFlags,
|
||||
NULL);
|
||||
if (Handle) break;
|
||||
if (!ClassFound)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
if ( save_error == ERROR_CANNOT_FIND_WND_CLASS )
|
||||
{
|
||||
ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
|
||||
if (ClassFound) continue;
|
||||
}
|
||||
}
|
||||
if (hLibModule)
|
||||
{
|
||||
save_error = GetLastError();
|
||||
FreeLibrary(hLibModule);
|
||||
SetLastError(save_error);
|
||||
hLibModule = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
|
||||
|
@ -845,7 +868,7 @@ FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL WINAPI
|
||||
GetAltTabInfoA(HWND hwnd,
|
||||
|
@ -854,13 +877,12 @@ GetAltTabInfoA(HWND hwnd,
|
|||
LPSTR pszItemText,
|
||||
UINT cchItemText)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return NtUserGetAltTabInfo(hwnd,iItem,pati,(LPWSTR)pszItemText,cchItemText,TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL WINAPI
|
||||
GetAltTabInfoW(HWND hwnd,
|
||||
|
@ -869,8 +891,7 @@ GetAltTabInfoW(HWND hwnd,
|
|||
LPWSTR pszItemText,
|
||||
UINT cchItemText)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return NtUserGetAltTabInfo(hwnd,iItem,pati,pszItemText,cchItemText,FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue