[COMCTL32]

- Add and install a manifest for comctl32 version 5.82. 
- Since our comctl32 tries to imitate both version 5 and version 6, register its classes twice, once while having the version 6 manifest active and once when having the version 5 active. 
- Register the themed versions of the built in controls while having the version 6 manifest active (and register them as global classes). This breaks theming of built in controls until versioned classes get implemented.
- Do not try to subclass the dialog class. This is incorrect and can lead to problems like in CORE-8534, CORE-12727, CORE-8387. This removes the background texture of the themed tabs which will be implemented in the future in uxtheme using api hooks.
This breaks a great deal of theming but keep in mind that it is in the middle of a transition to have them implemented correctly without the terrible side effects (broken ansi conversion, not always  using themes for built in controls. However comctl32 is now ready for versioned classes to be enabled.
CORE-12285

svn path=/trunk/; revision=73803
This commit is contained in:
Giannis Adamopoulos 2017-02-17 10:04:24 +00:00
parent e83d1d9365
commit bb9f71835f
6 changed files with 261 additions and 55 deletions

View file

@ -165,7 +165,7 @@ int MONTHCAL_MonthLength(int month, int year) DECLSPEC_HIDDEN;
int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace) DECLSPEC_HIDDEN;
LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) DECLSPEC_HIDDEN;
extern void THEMING_Initialize(void) DECLSPEC_HIDDEN;
extern void THEMING_Initialize(HANDLE hActCtx5, HANDLE hActCtx6) DECLSPEC_HIDDEN;
extern void THEMING_Uninitialize(void) DECLSPEC_HIDDEN;
extern LRESULT THEMING_CallOriginalClass(HWND, UINT, WPARAM, LPARAM) DECLSPEC_HIDDEN;
extern void THEMING_SetSubclassData(HWND, ULONG_PTR) DECLSPEC_HIDDEN;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.2600.2982" processorArchitecture="" publicKeyToken="6595b64144ccf1df"/>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.2600.2982" publicKeyToken="6595b64144ccf1df"/>
<file name="comctl32.dll">
<windowClass>Button</windowClass>
<windowClass>ButtonListBox</windowClass>
@ -12,7 +12,6 @@
<windowClass>NativeFontCtl</windowClass>
<windowClass>ReBarWindow32</windowClass>
<windowClass>ScrollBar</windowClass>
<windowClass>Static</windowClass>
<windowClass>SysAnimate32</windowClass>
<windowClass>SysDateTimePick32</windowClass>
<windowClass>SysHeader32</windowClass>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="5.82.2600.2982" publicKeyToken="6595b64144ccf1df"/>
<file name="comctl32.dll">
<windowClass versioned="no">Button</windowClass>
<windowClass versioned="no">ButtonListBox</windowClass>
<windowClass versioned="no">ComboBoxEx32</windowClass>
<windowClass versioned="no">ComboLBox</windowClass>
<windowClass versioned="no">Combobox</windowClass>
<windowClass versioned="no">Edit</windowClass>
<windowClass versioned="no">Listbox</windowClass>
<windowClass versioned="no">NativeFontCtl</windowClass>
<windowClass versioned="no">ReBarWindow32</windowClass>
<windowClass versioned="no">ScrollBar</windowClass>
<windowClass versioned="no">SysAnimate32</windowClass>
<windowClass versioned="no">SysDateTimePick32</windowClass>
<windowClass versioned="no">SysHeader32</windowClass>
<windowClass versioned="no">SysIPAddress32</windowClass>
<windowClass versioned="no">SysLink</windowClass>
<windowClass versioned="no">SysListView32</windowClass>
<windowClass versioned="no">SysMonthCal32</windowClass>
<windowClass versioned="no">SysPager</windowClass>
<windowClass versioned="no">SysTabControl32</windowClass>
<windowClass versioned="no">SysTreeView32</windowClass>
<windowClass versioned="no">ToolbarWindow32</windowClass>
<windowClass versioned="no">msctls_hotkey32</windowClass>
<windowClass versioned="no">msctls_progress32</windowClass>
<windowClass versioned="no">msctls_statusbar32</windowClass>
<windowClass versioned="no">msctls_trackbar32</windowClass>
<windowClass versioned="no">msctls_updown32</windowClass>
<windowClass versioned="no">tooltips_class32</windowClass>
</file>
</assembly>

View file

@ -60,20 +60,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
#define NAME L"microsoft.windows.common-controls"
#define VERSION L"6.0.2600.2982"
#define PUBLIC_KEY L"6595b64144ccf1df"
#ifdef __i386__
#define ARCH L"x86"
#elif defined __x86_64__
#define ARCH L"amd64"
#else
#define ARCH L"none"
#endif
static const WCHAR manifest_filename[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION L"_none_deadbeef.manifest";
static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LPWSTR COMCTL32_wSubclass = NULL;
@ -94,17 +80,69 @@ static const WCHAR strCC32SubclassInfo[] = {
'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
};
static BOOL create_manifest(BOOL install)
#ifdef __REACTOS__
#include <strsafe.h>
#define NAME L"microsoft.windows.common-controls"
#define VERSION_V5 L"5.82.2600.2982"
#define VERSION L"6.0.2600.2982"
#define PUBLIC_KEY L"6595b64144ccf1df"
#ifdef __i386__
#define ARCH L"x86"
#elif defined __x86_64__
#define ARCH L"amd64"
#else
#define ARCH L"none"
#endif
static const WCHAR manifest_filename[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION L"_none_deadbeef.manifest";
static const WCHAR manifest_filename_v5[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION_V5 L"_none_deadbeef.manifest";
static WCHAR* GetManifestPath(BOOL create, BOOL bV6)
{
WCHAR *pwszBuf;
HRESULT hres;
pwszBuf = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
if (!pwszBuf)
return NULL;
GetWindowsDirectoryW(pwszBuf, MAX_PATH);
hres = StringCchCatW(pwszBuf, MAX_PATH, L"\\winsxs");
if (FAILED(hres))
return NULL;
if (create)
CreateDirectoryW(pwszBuf, NULL);
hres = StringCchCatW(pwszBuf, MAX_PATH, L"\\manifests\\");
if (FAILED(hres))
return NULL;
if (create)
CreateDirectoryW(pwszBuf, NULL);
hres = StringCchCatW(pwszBuf, MAX_PATH, bV6 ? manifest_filename : manifest_filename_v5);
if (FAILED(hres))
return NULL;
return pwszBuf;
}
static BOOL create_manifest(BOOL install, BOOL bV6)
{
WCHAR *pwszBuf;
HRSRC hResInfo;
HGLOBAL hResData;
PVOID pManifest;
DWORD cchBuf, cbManifest, cbWritten;
DWORD cbManifest, cbWritten;
HANDLE hFile;
BOOL bRet = FALSE;
hResInfo = FindResourceW(COMCTL32_hModule, L"WINE_MANIFEST", (LPWSTR)RT_MANIFEST);
if (bV6)
hResInfo = FindResourceW(COMCTL32_hModule, L"WINE_MANIFEST", (LPWSTR)RT_MANIFEST);
else
hResInfo = FindResourceW(COMCTL32_hModule, L"WINE_MANIFESTV5", (LPWSTR)RT_MANIFEST);
if (!hResInfo)
return FALSE;
@ -120,17 +158,10 @@ static BOOL create_manifest(BOOL install)
if (!pManifest)
return FALSE;
cchBuf = GetWindowsDirectoryW(NULL, 0) * sizeof(WCHAR) + sizeof(L"\\winsxs\\manifests\\") + sizeof(manifest_filename);
pwszBuf = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, cchBuf * sizeof(WCHAR));
pwszBuf = GetManifestPath(TRUE, bV6);
if (!pwszBuf)
return FALSE;
GetWindowsDirectoryW(pwszBuf, cchBuf);
lstrcatW(pwszBuf, L"\\winsxs");
CreateDirectoryW(pwszBuf, NULL);
lstrcatW(pwszBuf, L"\\manifests\\");
CreateDirectoryW(pwszBuf, NULL);
lstrcatW(pwszBuf, manifest_filename);
if (install)
{
hFile = CreateFileW(pwszBuf, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
@ -155,6 +186,134 @@ static BOOL create_manifest(BOOL install)
return bRet;
}
static HANDLE CreateComctl32ActCtx(BOOL bV6)
{
HANDLE ret;
WCHAR* pwstrSource;
ACTCTXW ActCtx = {sizeof(ACTCTX)};
pwstrSource = GetManifestPath(FALSE, bV6);
if (!pwstrSource)
{
ERR("GetManifestPath failed! bV6=%d\n", bV6);
return INVALID_HANDLE_VALUE;
}
ActCtx.lpSource = pwstrSource;
ret = CreateActCtxW(&ActCtx);
HeapFree(GetProcessHeap(), 0, pwstrSource);
if (ret == INVALID_HANDLE_VALUE)
ERR("CreateActCtxW failed! bV6=%d\n", bV6);
return ret;
}
static void RegisterControls()
{
ANIMATE_Register ();
COMBOEX_Register ();
DATETIME_Register ();
FLATSB_Register ();
HEADER_Register ();
HOTKEY_Register ();
IPADDRESS_Register ();
LISTVIEW_Register ();
MONTHCAL_Register ();
NATIVEFONT_Register ();
PAGER_Register ();
PROGRESS_Register ();
REBAR_Register ();
STATUS_Register ();
SYSLINK_Register ();
TAB_Register ();
TOOLBAR_Register ();
TOOLTIPS_Register ();
TRACKBAR_Register ();
TREEVIEW_Register ();
UPDOWN_Register ();
}
static void UnregisterControls()
{
ANIMATE_Unregister ();
COMBOEX_Unregister ();
DATETIME_Unregister ();
FLATSB_Unregister ();
HEADER_Unregister ();
HOTKEY_Unregister ();
IPADDRESS_Unregister ();
LISTVIEW_Unregister ();
MONTHCAL_Unregister ();
NATIVEFONT_Unregister ();
PAGER_Unregister ();
PROGRESS_Unregister ();
REBAR_Unregister ();
STATUS_Unregister ();
SYSLINK_Unregister ();
TAB_Unregister ();
TOOLBAR_Unregister ();
TOOLTIPS_Unregister ();
TRACKBAR_Unregister ();
TREEVIEW_Unregister ();
UPDOWN_Unregister ();
}
static void InitializeClasses()
{
HANDLE hActCtx5, hActCtx6;
BOOL activated;
ULONG_PTR ulCookie;
/* like comctl32 5.82+ register all the common control classes */
/* Register the classes once no matter what */
hActCtx5 = CreateComctl32ActCtx(FALSE);
activated = (hActCtx5 != INVALID_HANDLE_VALUE ? ActivateActCtx(hActCtx5, &ulCookie) : FALSE);
RegisterControls(); /* Register the classes pretending to be v5 */
if (activated) DeactivateActCtx(0, ulCookie);
hActCtx6 = CreateComctl32ActCtx(TRUE);
if (hActCtx6 != INVALID_HANDLE_VALUE)
{
activated = ActivateActCtx(hActCtx6, &ulCookie);
RegisterControls(); /* Register the classes pretending to be v6 */
if (activated) DeactivateActCtx(0, ulCookie);
/* Initialize the themed controls only when the v6 manifest is present */
THEMING_Initialize (hActCtx5, hActCtx6);
}
}
static void UninitializeClasses()
{
HANDLE hActCtx5, hActCtx6;
BOOL activated;
ULONG_PTR ulCookie;
hActCtx5 = CreateComctl32ActCtx(FALSE);
activated = (hActCtx5 != INVALID_HANDLE_VALUE ? ActivateActCtx(hActCtx5, &ulCookie) : FALSE);
UnregisterControls();
if (activated) DeactivateActCtx(0, ulCookie);
hActCtx6 = CreateComctl32ActCtx(TRUE);
if (hActCtx6 != INVALID_HANDLE_VALUE)
{
activated = ActivateActCtx(hActCtx6, &ulCookie);
THEMING_Uninitialize();
UnregisterControls();
if (activated) DeactivateActCtx(0, ulCookie);
}
}
/***********************************************************************
* RegisterClassNameW [COMCTL32.@]
*
* Register window class again while using as SxS module.
*/
BOOLEAN WINAPI RegisterClassNameW(LPCWSTR className)
{
InitializeClasses();
return TRUE;
}
#endif
/***********************************************************************
* DllMain [Internal]
@ -192,6 +351,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
/* Get all the colors at DLL load */
COMCTL32_RefreshSysColors();
#ifndef __REACTOS__
/* like comctl32 5.82+ register all the common control classes */
ANIMATE_Register ();
COMBOEX_Register ();
@ -217,10 +377,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
/* subclass user32 controls */
THEMING_Initialize ();
#else
InitializeClasses();
#endif
break;
case DLL_PROCESS_DETACH:
if (lpvReserved) break;
#ifndef __REACTOS__
/* clean up subclassing */
THEMING_Uninitialize();
@ -246,7 +411,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
TRACKBAR_Unregister ();
TREEVIEW_Unregister ();
UPDOWN_Unregister ();
#else
UninitializeClasses();
#endif
/* delete local pattern brush */
DeleteObject (COMCTL32_hPattern55AABrush);
DeleteObject (COMCTL32_hPattern55AABitmap);
@ -991,12 +1158,22 @@ HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
{
TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
if (!create_manifest(bInstall))
#ifdef __REACTOS__
if (!create_manifest(bInstall, TRUE))
{
ERR("create_manifest failed!\n");
ERR("Failed to install comctl32 v6 manifest!\n");
return HRESULT_FROM_WIN32(GetLastError());
}
if (!create_manifest(bInstall, FALSE))
{
ERR("Failed to install comctl32 v5 manifest!\n");
return HRESULT_FROM_WIN32(GetLastError());
}
#endif
return S_OK;
}
@ -1856,15 +2033,3 @@ HRESULT WINAPI LoadIconMetric(HINSTANCE hinst, const WCHAR *name, int size, HICO
return LoadIconWithScaleDown(hinst, name, cx, cy, icon);
}
/***********************************************************************
* RegisterClassNameW [COMCTL32.@]
*
* Register window class again while using as SxS module.
*/
BOOLEAN WINAPI RegisterClassNameW(LPCWSTR className)
{
/* FIXME: actually register redirected user32 class,
comctl32 classes are registered by this module anyway */
return TRUE;
}

View file

@ -38,6 +38,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: comctl32.manifest */
WINE_MANIFEST RT_MANIFEST comctl32.manifest
WINE_MANIFESTV5 RT_MANIFEST comctl32v5.manifest
/* @makedep: idt_check.bmp */
IDT_CHECK BITMAP idt_check.bmp

View file

@ -30,8 +30,6 @@ extern LRESULT CALLBACK THEMING_ButtonSubclassProc (HWND, UINT, WPARAM, LPARAM,
ULONG_PTR) DECLSPEC_HIDDEN;
extern LRESULT CALLBACK THEMING_ComboSubclassProc (HWND, UINT, WPARAM, LPARAM,
ULONG_PTR) DECLSPEC_HIDDEN;
extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
ULONG_PTR) DECLSPEC_HIDDEN;
extern LRESULT CALLBACK THEMING_EditSubclassProc (HWND, UINT, WPARAM, LPARAM,
ULONG_PTR) DECLSPEC_HIDDEN;
extern LRESULT CALLBACK THEMING_ListBoxSubclassProc (HWND, UINT, WPARAM, LPARAM,
@ -48,7 +46,6 @@ static const struct ThemingSubclass
THEMING_SUBCLASSPROC subclassProc;
} subclasses[] = {
/* Note: list must be sorted by class name */
{dialogClass, THEMING_DialogSubclassProc},
{WC_BUTTONW, THEMING_ButtonSubclassProc},
{WC_COMBOBOXW, THEMING_ComboSubclassProc},
{comboLboxClass, THEMING_ListBoxSubclassProc},
@ -90,7 +87,6 @@ MAKE_SUBCLASS_PROC(2)
MAKE_SUBCLASS_PROC(3)
MAKE_SUBCLASS_PROC(4)
MAKE_SUBCLASS_PROC(5)
MAKE_SUBCLASS_PROC(6)
static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
subclass_proc0,
@ -98,8 +94,7 @@ static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
subclass_proc2,
subclass_proc3,
subclass_proc4,
subclass_proc5,
subclass_proc6
subclass_proc5
};
/***********************************************************************
@ -108,15 +103,15 @@ static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
* Register classes for standard controls that will shadow the system
* classes.
*/
void THEMING_Initialize (void)
void THEMING_Initialize (HANDLE hActCtx5, HANDLE hActCtx6)
{
unsigned int i;
static const WCHAR subclassPropName[] =
{ 'C','C','3','2','T','h','e','m','i','n','g','S','u','b','C','l',0 };
static const WCHAR refDataPropName[] =
{ 'C','C','3','2','T','h','e','m','i','n','g','D','a','t','a',0 };
if (!IsThemeActive()) return;
ULONG_PTR ulCookie;
BOOL ret, bActivated;
atSubclassProp = GlobalAddAtomW (subclassPropName);
atRefDataProp = GlobalAddAtomW (refDataPropName);
@ -126,7 +121,13 @@ void THEMING_Initialize (void)
WNDCLASSEXW class;
class.cbSize = sizeof(class);
if (!GetClassInfoExW (NULL, subclasses[i].className, &class))
bActivated = ActivateActCtx(hActCtx5, &ulCookie);
ret = GetClassInfoExW (NULL, subclasses[i].className, &class);
if (bActivated)
DeactivateActCtx(0, ulCookie);
if (!ret)
{
ERR("Could not retrieve information for class %s\n",
debugstr_w (subclasses[i].className));
@ -134,7 +135,9 @@ void THEMING_Initialize (void)
}
originalProcs[i] = class.lpfnWndProc;
class.lpfnWndProc = subclassProcs[i];
class.style |= CS_GLOBALCLASS;
class.hInstance = COMCTL32_hModule;
if (!class.lpfnWndProc)
{
ERR("Missing proc for class %s\n",
@ -142,9 +145,11 @@ void THEMING_Initialize (void)
continue;
}
bActivated = ActivateActCtx(hActCtx6, &ulCookie);
if (!RegisterClassExW (&class))
{
ERR("Could not re-register class %s: %x\n",
WARN("Could not re-register class %s: %x\n",
debugstr_w (subclasses[i].className), GetLastError ());
}
else
@ -152,6 +157,9 @@ void THEMING_Initialize (void)
TRACE("Re-registered class %s\n",
debugstr_w (subclasses[i].className));
}
if (bActivated)
DeactivateActCtx(0, ulCookie);
}
}