uxtheme: Set non-client metrics from theme.

This commit is contained in:
Frank Richter 2006-08-14 19:22:18 +02:00 committed by Alexandre Julliard
parent 3e4bdad4a3
commit 11211bf940
2 changed files with 232 additions and 10 deletions

View File

@ -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;
@ -719,6 +720,130 @@ static void parse_apply_color (struct PARSECOLORSTATE* state)
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
*
@ -752,8 +877,10 @@ 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) {
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])));
@ -768,6 +895,22 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
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);
}
@ -775,7 +918,11 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
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;
}
if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) {
@ -1078,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'};
@ -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'};
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]))) {
@ -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(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
*

View File

@ -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"
@ -251,6 +251,10 @@ static const WCHAR strColorKey[] =
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
{
@ -301,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;
@ -313,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);
}
@ -378,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);
@ -401,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);
}
/***********************************************************************