From 1869f86db688fc5a0d6743bae2040b10f9da0d35 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Fri, 8 Sep 2006 20:13:51 +0000 Subject: [PATCH] Autosyncing with Wine HEAD svn path=/trunk/; revision=23979 --- reactos/dll/win32/uxtheme/msstyles.c | 255 ++++++++++++++++++++++++--- reactos/dll/win32/uxtheme/system.c | 88 +++++++-- 2 files changed, 307 insertions(+), 36 deletions(-) diff --git a/reactos/dll/win32/uxtheme/msstyles.c b/reactos/dll/win32/uxtheme/msstyles.c index 76414d90867..9225206d002 100644 --- a/reactos/dll/win32/uxtheme/msstyles.c +++ b/reactos/dll/win32/uxtheme/msstyles.c @@ -25,9 +25,9 @@ #include "windef.h" #include "winbase.h" +#include "wingdi.h" #include "winuser.h" #include "winnls.h" -#include "wingdi.h" #include "uxtheme.h" #include "tmschema.h" @@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value); BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize); void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics); +HRESULT MSSTYLES_GetFont (LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LOGFONTW* logfont); extern HINSTANCE hDllInst; extern int alphaBlendMode; @@ -664,6 +665,185 @@ static PTHEME_PROPERTY MSSTYLES_AddMetric(PTHEME_FILE tf, int iPropertyPrimitive return cur; } +/* Color-related state for theme ini parsing */ +struct PARSECOLORSTATE +{ + int colorCount; + int colorElements[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; + COLORREF colorRgb[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; + int captionColors; +}; + +inline void parse_init_color (struct PARSECOLORSTATE* state) +{ + memset (state, 0, sizeof (*state)); +} + +static BOOL parse_handle_color_property (struct PARSECOLORSTATE* state, + int iPropertyId, LPCWSTR lpValue, + DWORD dwValueLen) +{ + int r,g,b; + LPCWSTR lpValueEnd = lpValue + dwValueLen; + MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &r); + MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &g); + if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &b)) { + state->colorElements[state->colorCount] = iPropertyId - TMT_FIRSTCOLOR; + state->colorRgb[state->colorCount++] = RGB(r,g,b); + switch (iPropertyId) + { + case TMT_ACTIVECAPTION: + state->captionColors |= 0x1; + break; + case TMT_INACTIVECAPTION: + state->captionColors |= 0x2; + break; + case TMT_GRADIENTACTIVECAPTION: + state->captionColors |= 0x4; + break; + case TMT_GRADIENTINACTIVECAPTION: + state->captionColors |= 0x8; + break; + } + return TRUE; + } + else { + return FALSE; + } +} + +static void parse_apply_color (struct PARSECOLORSTATE* state) +{ + if (state->colorCount > 0) + SetSysColors(state->colorCount, state->colorElements, state->colorRgb); + if (state->captionColors == 0xf) + SystemParametersInfoW (SPI_SETGRADIENTCAPTIONS, 0, (PVOID)TRUE, 0); +} + +/* Non-client-metrics-related state for theme ini parsing */ +struct PARSENONCLIENTSTATE +{ + NONCLIENTMETRICSW metrics; + BOOL metricsDirty; + LOGFONTW iconTitleFont; +}; + +inline void parse_init_nonclient (struct PARSENONCLIENTSTATE* state) +{ + memset (state, 0, sizeof (*state)); + state->metrics.cbSize = sizeof (NONCLIENTMETRICSW); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (NONCLIENTMETRICSW), + (PVOID)&state->metrics, 0); + SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (LOGFONTW), + (PVOID)&state->iconTitleFont, 0); +} + +static BOOL parse_handle_nonclient_font (struct PARSENONCLIENTSTATE* state, + int iPropertyId, LPCWSTR lpValue, + DWORD dwValueLen) +{ + LOGFONTW font; + + memset (&font, 0, sizeof (font)); + if (SUCCEEDED (MSSTYLES_GetFont (lpValue, lpValue + dwValueLen, &lpValue, + &font))) + { + switch (iPropertyId) + { + case TMT_CAPTIONFONT: + memcpy (&state->metrics.lfCaptionFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_SMALLCAPTIONFONT: + memcpy (&state->metrics.lfSmCaptionFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_MENUFONT: + memcpy (&state->metrics.lfMenuFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_STATUSFONT: + memcpy (&state->metrics.lfStatusFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_MSGBOXFONT: + memcpy (&state->metrics.lfMessageFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_ICONTITLEFONT: + memcpy (&state->iconTitleFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + } + return TRUE; + } + else + return FALSE; +} + +static BOOL parse_handle_nonclient_size (struct PARSENONCLIENTSTATE* state, + int iPropertyId, LPCWSTR lpValue, + DWORD dwValueLen) +{ + int size; + LPCWSTR lpValueEnd = lpValue + dwValueLen; + if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &size)) { + switch (iPropertyId) + { + case TMT_SIZINGBORDERWIDTH: + state->metrics.iBorderWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_SCROLLBARWIDTH: + state->metrics.iScrollWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_SCROLLBARHEIGHT: + state->metrics.iScrollHeight = size; + state->metricsDirty = TRUE; + break; + case TMT_CAPTIONBARWIDTH: + state->metrics.iCaptionWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_CAPTIONBARHEIGHT: + state->metrics.iCaptionHeight = size; + state->metricsDirty = TRUE; + break; + case TMT_SMCAPTIONBARWIDTH: + state->metrics.iSmCaptionWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_SMCAPTIONBARHEIGHT: + state->metrics.iSmCaptionHeight = size; + state->metricsDirty = TRUE; + break; + case TMT_MENUBARWIDTH: + state->metrics.iMenuWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_MENUBARHEIGHT: + state->metrics.iMenuHeight = size; + state->metricsDirty = TRUE; + break; + } + return TRUE; + } + else + return FALSE; +} + +static void parse_apply_nonclient (struct PARSENONCLIENTSTATE* state) +{ + if (state->metricsDirty) + { + SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, sizeof (state->metrics), + (PVOID)&state->metrics, 0); + SystemParametersInfoW (SPI_SETICONTITLELOGFONT, sizeof (state->iconTitleFont), + (PVOID)&state->iconTitleFont, 0); + } +} + /*********************************************************************** * MSSTYLES_ParseThemeIni * @@ -696,31 +876,41 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) while((lpName=UXINI_GetNextSection(ini, &dwLen))) { if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpName, dwLen, szSysMetrics, -1) == CSTR_EQUAL) { - int colorCount = 0; - int colorElements[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; - COLORREF colorRgb[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; - LPCWSTR lpValueEnd; + struct PARSECOLORSTATE colorState; + struct PARSENONCLIENTSTATE nonClientState; + + parse_init_color (&colorState); + parse_init_nonclient (&nonClientState); while((lpName=UXINI_GetNextValue(ini, &dwLen, &lpValue, &dwValueLen))) { lstrcpynW(szPropertyName, lpName, min(dwLen+1, sizeof(szPropertyName)/sizeof(szPropertyName[0]))); if(MSSTYLES_LookupProperty(szPropertyName, &iPropertyPrimitive, &iPropertyId)) { if(iPropertyId >= TMT_FIRSTCOLOR && iPropertyId <= TMT_LASTCOLOR) { - int r,g,b; - lpValueEnd = lpValue + dwValueLen; - MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &r); - MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &g); - if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &b)) { - colorElements[colorCount] = iPropertyId - TMT_FIRSTCOLOR; - colorRgb[colorCount++] = RGB(r,g,b); - } - else { - FIXME("Invalid color value for %s\n", debugstr_w(szPropertyName)); - } + if (!parse_handle_color_property (&colorState, iPropertyId, + lpValue, dwValueLen)) + FIXME("Invalid color value for %s\n", + debugstr_w(szPropertyName)); } else if (setMetrics && (iPropertyId == TMT_FLATMENUS)) { BOOL flatMenus = (*lpValue == 'T') || (*lpValue == 't'); SystemParametersInfoW (SPI_SETFLATMENU, 0, (PVOID)(INT_PTR)flatMenus, 0); } + else if ((iPropertyId >= TMT_FIRSTFONT) + && (iPropertyId <= TMT_LASTFONT)) + { + if (!parse_handle_nonclient_font (&nonClientState, + iPropertyId, lpValue, dwValueLen)) + FIXME("Invalid font value for %s\n", + debugstr_w(szPropertyName)); + } + else if ((iPropertyId >= TMT_FIRSTSIZE) + && (iPropertyId <= TMT_LASTSIZE)) + { + if (!parse_handle_nonclient_size (&nonClientState, + iPropertyId, lpValue, dwValueLen)) + FIXME("Invalid size value for %s\n", + debugstr_w(szPropertyName)); + } /* Catch all metrics, including colors */ MSSTYLES_AddMetric(tf, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen); } @@ -728,8 +918,11 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName)); } } - if (setMetrics && (colorCount > 0)) - SetSysColors(colorCount, colorElements, colorRgb); + if (setMetrics) + { + parse_apply_color (&colorState); + parse_apply_nonclient (&nonClientState); + } continue; } if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) { @@ -1032,7 +1225,8 @@ HRESULT MSSTYLES_GetPropertyColor(PTHEME_PROPERTY tp, COLORREF *pColor) * * Retrieve a color value for a property */ -HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) +HRESULT MSSTYLES_GetFont (LPCWSTR lpCur, LPCWSTR lpEnd, + LPCWSTR *lpValEnd, LOGFONTW* pFont) { static const WCHAR szBold[] = {'b','o','l','d','\0'}; static const WCHAR szItalic[] = {'i','t','a','l','i','c','\0'}; @@ -1040,20 +1234,18 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) static const WCHAR szStrikeOut[] = {'s','t','r','i','k','e','o','u','t','\0'}; int pointSize; WCHAR attr[32]; - LPCWSTR lpCur = tp->lpValue; - LPCWSTR lpEnd = tp->lpValue + tp->dwValueLen; - - ZeroMemory(pFont, sizeof(LOGFONTW)); if(!MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, pFont->lfFaceName, LF_FACESIZE)) { TRACE("Property is there, but failed to get face name\n"); + *lpValEnd = lpCur; return E_PROP_ID_UNSUPPORTED; } if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pointSize)) { TRACE("Property is there, but failed to get point size\n"); + *lpValEnd = lpCur; return E_PROP_ID_UNSUPPORTED; } - pFont->lfHeight = -MulDiv(pointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); + pFont->lfHeight = pointSize; pFont->lfWeight = FW_REGULAR; pFont->lfCharSet = DEFAULT_CHARSET; while(MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, attr, sizeof(attr)/sizeof(attr[0]))) { @@ -1062,9 +1254,24 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) else if(!!lstrcmpiW(szUnderline, attr)) pFont->lfUnderline = TRUE; else if(!!lstrcmpiW(szStrikeOut, attr)) pFont->lfStrikeOut = TRUE; } + *lpValEnd = lpCur; return S_OK; } +HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) +{ + LPCWSTR lpCur = tp->lpValue; + LPCWSTR lpEnd = tp->lpValue + tp->dwValueLen; + HRESULT hr; + + ZeroMemory(pFont, sizeof(LOGFONTW)); + hr = MSSTYLES_GetFont (lpCur, lpEnd, &lpCur, pFont); + if (SUCCEEDED (hr)) + pFont->lfHeight = -MulDiv(pFont->lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72); + + return hr; +} + /*********************************************************************** * MSSTYLES_GetPropertyInt * diff --git a/reactos/dll/win32/uxtheme/system.c b/reactos/dll/win32/uxtheme/system.c index c834c52c1cb..b115c536a6e 100644 --- a/reactos/dll/win32/uxtheme/system.c +++ b/reactos/dll/win32/uxtheme/system.c @@ -25,8 +25,8 @@ #include "windef.h" #include "winbase.h" -#include "winuser.h" #include "wingdi.h" +#include "winuser.h" #include "winreg.h" #include "uxtheme.h" #include "tmschema.h" @@ -57,17 +57,17 @@ static const WCHAR szDllName[] = {'D','l','l','N','a','m','e','\0'}; static const WCHAR szIniDocumentation[] = {'d','o','c','u','m','e','n','t','a','t','i','o','n','\0'}; HINSTANCE hDllInst; - -DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS; -ATOM atWindowTheme; -ATOM atSubAppName; -ATOM atSubIdList; ATOM atDialogThemeEnabled; -BOOL bThemeActive = FALSE; -WCHAR szCurrentTheme[MAX_PATH]; -WCHAR szCurrentColor[64]; -WCHAR szCurrentSize[64]; +static DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS; +static ATOM atWindowTheme; +static ATOM atSubAppName; +static ATOM atSubIdList; + +static BOOL bThemeActive = FALSE; +static WCHAR szCurrentTheme[MAX_PATH]; +static WCHAR szCurrentColor[64]; +static WCHAR szCurrentSize[64]; /***********************************************************************/ @@ -249,6 +249,12 @@ static const WCHAR strColorKey[] = { 'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\', 'C','o','l','o','r','s',0 }; static const WCHAR keyFlatMenus[] = { 'F','l','a','t','M','e','n','u', 0}; +static const WCHAR keyGradientCaption[] = { 'G','r','a','d','i','e','n','t', + 'C','a','p','t','i','o','n', 0 }; +static const WCHAR keyNonClientMetrics[] = { 'N','o','n','C','l','i','e','n','t', + 'M','e','t','r','i','c','s',0 }; +static const WCHAR keyIconTitleFont[] = { 'I','c','o','n','T','i','t','l','e', + 'F','o','n','t',0 }; static const struct BackupSysParam { @@ -257,6 +263,7 @@ static const struct BackupSysParam } backupSysParams[] = { {SPI_GETFLATMENU, SPI_SETFLATMENU, keyFlatMenus}, + {SPI_GETGRADIENTCAPTIONS, SPI_SETGRADIENTCAPTIONS, keyGradientCaption}, {-1, -1, 0} }; @@ -298,8 +305,13 @@ static void UXTHEME_BackupSystemMetrics(void) 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0) == ERROR_SUCCESS) { + NONCLIENTMETRICSW ncm; + LOGFONTW iconTitleFont; + + /* back up colors */ save_sys_colors (hKey); + /* back up "other" settings */ while (bsp->spiGet >= 0) { DWORD value; @@ -310,6 +322,18 @@ static void UXTHEME_BackupSystemMetrics(void) bsp++; } + + /* back up non-client metrics */ + memset (&ncm, 0, sizeof (ncm)); + ncm.cbSize = sizeof (ncm); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0); + RegSetValueExW (hKey, keyNonClientMetrics, 0, REG_BINARY, (LPBYTE)&ncm, + sizeof (ncm)); + memset (&iconTitleFont, 0, sizeof (iconTitleFont)); + SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (iconTitleFont), + &iconTitleFont, 0); + RegSetValueExW (hKey, keyIconTitleFont, 0, REG_BINARY, + (LPBYTE)&iconTitleFont, sizeof (iconTitleFont)); RegCloseKey (hKey); } @@ -375,16 +399,43 @@ static void UXTHEME_RestoreSystemMetrics(void) bsp++; } + /* read backed-up non-client metrics */ + { + NONCLIENTMETRICSW ncm; + LOGFONTW iconTitleFont; + DWORD count = sizeof(ncm); + DWORD type; + + if (RegQueryValueExW (hKey, keyNonClientMetrics, 0, + &type, (LPBYTE)&ncm, &count) == ERROR_SUCCESS) + { + SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, + count, (LPVOID)&ncm, SPIF_UPDATEINIFILE); + } + + count = sizeof(iconTitleFont); + + if (RegQueryValueExW (hKey, keyIconTitleFont, 0, + &type, (LPBYTE)&iconTitleFont, &count) == ERROR_SUCCESS) + { + SystemParametersInfoW (SPI_SETICONTITLELOGFONT, + count, (LPVOID)&iconTitleFont, SPIF_UPDATEINIFILE); + } + } RegCloseKey (hKey); } } /* Make system settings persistent, so they're in effect even w/o uxtheme - * loaded */ + * loaded. + * For efficiency reasons, only the last SystemParametersInfoW sets + * SPIF_SENDWININICHANGE */ static void UXTHEME_SaveSystemMetrics(void) { const struct BackupSysParam* bsp = backupSysParams; + NONCLIENTMETRICSW ncm; + LOGFONTW iconTitleFont; save_sys_colors (HKEY_CURRENT_USER); @@ -398,7 +449,20 @@ static void UXTHEME_SaveSystemMetrics(void) bsp++; } + + memset (&ncm, 0, sizeof (ncm)); + ncm.cbSize = sizeof (ncm); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, + sizeof (ncm), (LPVOID)&ncm, 0); + SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, + sizeof (ncm), (LPVOID)&ncm, SPIF_UPDATEINIFILE); + memset (&iconTitleFont, 0, sizeof (iconTitleFont)); + SystemParametersInfoW (SPI_GETICONTITLELOGFONT, + sizeof (iconTitleFont), (LPVOID)&iconTitleFont, 0); + SystemParametersInfoW (SPI_SETICONTITLELOGFONT, + sizeof (iconTitleFont), (LPVOID)&iconTitleFont, + SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); } /*********************************************************************** @@ -412,7 +476,7 @@ HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf) WCHAR tmp[2]; HRESULT hr; - if(tf) UXTHEME_BackupSystemMetrics(); + if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics(); hr = MSSTYLES_SetActiveTheme(tf, TRUE); if(FAILED(hr)) return hr;