Commit 11211bf9 authored by Frank Richter's avatar Frank Richter Committed by Alexandre Julliard

uxtheme: Set non-client metrics from theme.

parent 3e4bdad4
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h" #include "winnls.h"
#include "wingdi.h"
#include "uxtheme.h" #include "uxtheme.h"
#include "tmschema.h" #include "tmschema.h"
...@@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); ...@@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value); BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value);
BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize); BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize);
void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics); void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics);
HRESULT MSSTYLES_GetFont (LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LOGFONTW* logfont);
extern HINSTANCE hDllInst; extern HINSTANCE hDllInst;
extern int alphaBlendMode; extern int alphaBlendMode;
...@@ -719,6 +720,130 @@ static void parse_apply_color (struct PARSECOLORSTATE* state) ...@@ -719,6 +720,130 @@ static void parse_apply_color (struct PARSECOLORSTATE* state)
SystemParametersInfoW (SPI_SETGRADIENTCAPTIONS, 0, (PVOID)TRUE, 0); 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 * MSSTYLES_ParseThemeIni
* *
...@@ -752,8 +877,10 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) ...@@ -752,8 +877,10 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
while((lpName=UXINI_GetNextSection(ini, &dwLen))) { while((lpName=UXINI_GetNextSection(ini, &dwLen))) {
if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpName, dwLen, szSysMetrics, -1) == CSTR_EQUAL) { if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpName, dwLen, szSysMetrics, -1) == CSTR_EQUAL) {
struct PARSECOLORSTATE colorState; struct PARSECOLORSTATE colorState;
struct PARSENONCLIENTSTATE nonClientState;
parse_init_color (&colorState); parse_init_color (&colorState);
parse_init_nonclient (&nonClientState);
while((lpName=UXINI_GetNextValue(ini, &dwLen, &lpValue, &dwValueLen))) { while((lpName=UXINI_GetNextValue(ini, &dwLen, &lpValue, &dwValueLen))) {
lstrcpynW(szPropertyName, lpName, min(dwLen+1, sizeof(szPropertyName)/sizeof(szPropertyName[0]))); lstrcpynW(szPropertyName, lpName, min(dwLen+1, sizeof(szPropertyName)/sizeof(szPropertyName[0])));
...@@ -768,6 +895,22 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) ...@@ -768,6 +895,22 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
BOOL flatMenus = (*lpValue == 'T') || (*lpValue == 't'); BOOL flatMenus = (*lpValue == 'T') || (*lpValue == 't');
SystemParametersInfoW (SPI_SETFLATMENU, 0, (PVOID)(INT_PTR)flatMenus, 0); 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 */ /* Catch all metrics, including colors */
MSSTYLES_AddMetric(tf, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen); MSSTYLES_AddMetric(tf, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen);
} }
...@@ -775,7 +918,11 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) ...@@ -775,7 +918,11 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName)); TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName));
} }
} }
if (setMetrics) parse_apply_color (&colorState); if (setMetrics)
{
parse_apply_color (&colorState);
parse_apply_nonclient (&nonClientState);
}
continue; continue;
} }
if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) { if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) {
...@@ -1078,7 +1225,8 @@ HRESULT MSSTYLES_GetPropertyColor(PTHEME_PROPERTY tp, COLORREF *pColor) ...@@ -1078,7 +1225,8 @@ HRESULT MSSTYLES_GetPropertyColor(PTHEME_PROPERTY tp, COLORREF *pColor)
* *
* Retrieve a color value for a property * 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 szBold[] = {'b','o','l','d','\0'};
static const WCHAR szItalic[] = {'i','t','a','l','i','c','\0'}; static const WCHAR szItalic[] = {'i','t','a','l','i','c','\0'};
...@@ -1086,20 +1234,18 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) ...@@ -1086,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'}; static const WCHAR szStrikeOut[] = {'s','t','r','i','k','e','o','u','t','\0'};
int pointSize; int pointSize;
WCHAR attr[32]; 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)) { if(!MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, pFont->lfFaceName, LF_FACESIZE)) {
TRACE("Property is there, but failed to get face name\n"); TRACE("Property is there, but failed to get face name\n");
*lpValEnd = lpCur;
return E_PROP_ID_UNSUPPORTED; return E_PROP_ID_UNSUPPORTED;
} }
if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pointSize)) { if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pointSize)) {
TRACE("Property is there, but failed to get point size\n"); TRACE("Property is there, but failed to get point size\n");
*lpValEnd = lpCur;
return E_PROP_ID_UNSUPPORTED; return E_PROP_ID_UNSUPPORTED;
} }
pFont->lfHeight = -MulDiv(pointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); pFont->lfHeight = pointSize;
pFont->lfWeight = FW_REGULAR; pFont->lfWeight = FW_REGULAR;
pFont->lfCharSet = DEFAULT_CHARSET; pFont->lfCharSet = DEFAULT_CHARSET;
while(MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, attr, sizeof(attr)/sizeof(attr[0]))) { while(MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, attr, sizeof(attr)/sizeof(attr[0]))) {
...@@ -1108,9 +1254,24 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) ...@@ -1108,9 +1254,24 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont)
else if(!!lstrcmpiW(szUnderline, attr)) pFont->lfUnderline = TRUE; else if(!!lstrcmpiW(szUnderline, attr)) pFont->lfUnderline = TRUE;
else if(!!lstrcmpiW(szStrikeOut, attr)) pFont->lfStrikeOut = TRUE; else if(!!lstrcmpiW(szStrikeOut, attr)) pFont->lfStrikeOut = TRUE;
} }
*lpValEnd = lpCur;
return S_OK; 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 * MSSTYLES_GetPropertyInt
* *
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winuser.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h"
#include "winreg.h" #include "winreg.h"
#include "uxtheme.h" #include "uxtheme.h"
#include "tmschema.h" #include "tmschema.h"
...@@ -251,6 +251,10 @@ static const WCHAR strColorKey[] = ...@@ -251,6 +251,10 @@ static const WCHAR strColorKey[] =
static const WCHAR keyFlatMenus[] = { 'F','l','a','t','M','e','n','u', 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', static const WCHAR keyGradientCaption[] = { 'G','r','a','d','i','e','n','t',
'C','a','p','t','i','o','n', 0 }; '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 static const struct BackupSysParam
{ {
...@@ -301,8 +305,13 @@ static void UXTHEME_BackupSystemMetrics(void) ...@@ -301,8 +305,13 @@ static void UXTHEME_BackupSystemMetrics(void)
0, 0, 0, KEY_ALL_ACCESS, 0, 0, 0, KEY_ALL_ACCESS,
0, &hKey, 0) == ERROR_SUCCESS) 0, &hKey, 0) == ERROR_SUCCESS)
{ {
NONCLIENTMETRICSW ncm;
LOGFONTW iconTitleFont;
/* back up colors */
save_sys_colors (hKey); save_sys_colors (hKey);
/* back up "other" settings */
while (bsp->spiGet >= 0) while (bsp->spiGet >= 0)
{ {
DWORD value; DWORD value;
...@@ -313,6 +322,18 @@ static void UXTHEME_BackupSystemMetrics(void) ...@@ -313,6 +322,18 @@ static void UXTHEME_BackupSystemMetrics(void)
bsp++; 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); RegCloseKey (hKey);
} }
...@@ -378,16 +399,43 @@ static void UXTHEME_RestoreSystemMetrics(void) ...@@ -378,16 +399,43 @@ static void UXTHEME_RestoreSystemMetrics(void)
bsp++; 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); RegCloseKey (hKey);
} }
} }
/* Make system settings persistent, so they're in effect even w/o uxtheme /* 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) static void UXTHEME_SaveSystemMetrics(void)
{ {
const struct BackupSysParam* bsp = backupSysParams; const struct BackupSysParam* bsp = backupSysParams;
NONCLIENTMETRICSW ncm;
LOGFONTW iconTitleFont;
save_sys_colors (HKEY_CURRENT_USER); save_sys_colors (HKEY_CURRENT_USER);
...@@ -401,7 +449,20 @@ static void UXTHEME_SaveSystemMetrics(void) ...@@ -401,7 +449,20 @@ static void UXTHEME_SaveSystemMetrics(void)
bsp++; 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);
} }
/*********************************************************************** /***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment