[PATCH] UXTHEME: Set non-client metrics from theme
Frank Richter
frank.richter at gmail.com
Mon Aug 14 12:22:18 CDT 2006
-------------- next part --------------
>From f8d4f796e734aebb430546495020f897f3518728 Mon Sep 17 00:00:00 2001
From: Frank Richter frank.richter at gmail.com <frank.richter at gmail.com>
Date: Mon, 14 Aug 2006 19:20:48 +0200
Subject: [PATCH] UXTHEME: Set non-client metrics from theme
---
dlls/uxtheme/msstyles.c | 177 +++++++++++++++++++++++++++++++++++++++++++++--
dlls/uxtheme/system.c | 67 +++++++++++++++++-
2 files changed, 233 insertions(+), 11 deletions(-)
diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c
index 4649a36..9225206 100644
--- a/dlls/uxtheme/msstyles.c
+++ b/dlls/uxtheme/msstyles.c
@@ -25,9 +25,9 @@ #include <stdlib.h>
#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 PA
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
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
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
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
*
* 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_
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_
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/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index e19f913..b115c53 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -25,8 +25,8 @@ #include <stdio.h>
#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(
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(
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
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(vo
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);
}
/***********************************************************************
--
1.4.1.1
More information about the wine-patches
mailing list