#include "windef.h"
#include "winbase.h"
+#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
-#include "wingdi.h"
+#include "vfwmsgs.h"
#include "uxtheme.h"
#include "tmschema.h"
-#include "uxthemedll.h"
#include "msstyles.h"
#include "wine/unicode.h"
* Defines and global variables
*/
-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);
+static BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value);
+static BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize);
+static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics);
+static HRESULT MSSTYLES_GetFont (LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LOGFONTW* logfont);
extern HINSTANCE hDllInst;
extern int alphaBlendMode;
't','h','e','m','e','s','_','i','n','i','\0'
};
-PTHEME_FILE tfActiveTheme = NULL;
+static PTHEME_FILE tfActiveTheme;
/***********************************************************************/
}
if((versize = SizeofResource(hTheme, hrsc)) != 2)
{
- TRACE("Version resource found, but wrong size: %ld\n", versize);
+ TRACE("Version resource found, but wrong size: %d\n", versize);
hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
goto invalid_theme;
}
hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
goto invalid_theme;
}
- pszColors = (LPWSTR)LoadResource(hTheme, hrsc);
+ pszColors = LoadResource(hTheme, hrsc);
if(!(hrsc = FindResourceW(hTheme, MAKEINTRESOURCEW(1), szSizeNamesResource))) {
TRACE("Size names resource not found\n");
hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
goto invalid_theme;
}
- pszSizes = (LPWSTR)LoadResource(hTheme, hrsc);
+ pszSizes = LoadResource(hTheme, hrsc);
- /* Validate requested color against whats available from the theme */
+ /* Validate requested color against what's available from the theme */
if(pszColorName) {
tmp = pszColors;
while(*tmp) {
else
pszSelectedColor = pszColors; /* Use the default color */
- /* Validate requested size against whats available from the theme */
+ /* Validate requested size against what's available from the theme */
if(pszSizeName) {
tmp = pszSizes;
while(*tmp) {
TRACE("FILERESNAMES map not found\n");
return NULL;
}
- tmp = (LPWSTR)LoadResource(tf->hTheme, hrsc);
+ tmp = LoadResource(tf->hTheme, hrsc);
dwResourceIndex = (dwSizeCount * dwColorNum) + dwSizeNum;
for(i=0; i < dwResourceIndex; i++) {
tmp += lstrlenW(tmp)+1;
* RETURNS
* The class found, or NULL
*/
-PTHEME_CLASS MSSTYLES_FindClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszClassName)
+static PTHEME_CLASS MSSTYLES_FindClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszClassName)
{
PTHEME_CLASS cur = tf->classes;
while(cur) {
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;
+};
+
+static 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;
+ if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &r) &&
+ MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &g) &&
+ 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;
+};
+
+static 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:
+ state->metrics.lfCaptionFont = font;
+ state->metricsDirty = TRUE;
+ break;
+ case TMT_SMALLCAPTIONFONT:
+ state->metrics.lfSmCaptionFont = font;
+ state->metricsDirty = TRUE;
+ break;
+ case TMT_MENUFONT:
+ state->metrics.lfMenuFont = font;
+ state->metricsDirty = TRUE;
+ break;
+ case TMT_STATUSFONT:
+ state->metrics.lfStatusFont = font;
+ state->metricsDirty = TRUE;
+ break;
+ case TMT_MSGBOXFONT:
+ state->metrics.lfMessageFont = font;
+ state->metricsDirty = TRUE;
+ break;
+ case TMT_ICONTITLEFONT:
+ state->iconTitleFont = font;
+ 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
*
* PARAMS
* tf Theme to parse
*/
-void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
+static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
{
static const WCHAR szSysMetrics[] = {'S','y','s','M','e','t','r','i','c','s','\0'};
static const WCHAR szGlobals[] = {'g','l','o','b','a','l','s','\0'};
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;
- int captionColors = 0;
+ 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);
- switch (iPropertyId)
- {
- case TMT_ACTIVECAPTION:
- captionColors |= 0x1;
- break;
- case TMT_INACTIVECAPTION:
- captionColors |= 0x2;
- break;
- case TMT_GRADIENTACTIVECAPTION:
- captionColors |= 0x4;
- break;
- case TMT_GRADIENTINACTIVECAPTION:
- captionColors |= 0x8;
- break;
- }
- }
- 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);
}
TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName));
}
}
- if (setMetrics && (colorCount > 0))
- SetSysColors(colorCount, colorElements, colorRgb);
- if (setMetrics && (captionColors == 0xf))
- SystemParametersInfoW (SPI_SETGRADIENTCAPTIONS, 0, (PVOID)TRUE, 0);
+ if (setMetrics)
+ {
+ parse_apply_color (&colorState);
+ parse_apply_nonclient (&nonClientState);
+ }
continue;
}
if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) {
return img->image;
}
-BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value)
+static BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value)
{
LPCWSTR cur = lpStringStart;
int total = 0;
return TRUE;
}
-BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize) {
+static BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize) {
LPCWSTR cur = lpStringStart;
LPCWSTR start;
LPCWSTR end;
lpCur = tp->lpValue;
lpEnd = tp->lpValue + tp->dwValueLen;
- MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &red);
- MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &green);
+ if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &red)) {
+ TRACE("Could not parse color property\n");
+ return E_PROP_ID_UNSUPPORTED;
+ }
+ if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &green)) {
+ TRACE("Could not parse color property\n");
+ return E_PROP_ID_UNSUPPORTED;
+ }
if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &blue)) {
TRACE("Could not parse color property\n");
return E_PROP_ID_UNSUPPORTED;
*
* Retrieve a color value for a property
*/
-HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont)
+static 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'};
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]))) {
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
*
LPCWSTR lpCur = tp->lpValue;
LPCWSTR lpEnd = tp->lpValue + tp->dwValueLen;
- MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &x);
+ if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &x)) {
+ TRACE("Could not parse position property\n");
+ return E_PROP_ID_UNSUPPORTED;
+ }
if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &y)) {
TRACE("Could not parse position property\n");
return E_PROP_ID_UNSUPPORTED;
LPCWSTR lpCur = tp->lpValue;
LPCWSTR lpEnd = tp->lpValue + tp->dwValueLen;
- MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->left);
- MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->top);
- MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->right);
- if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->bottom)) {
+ MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pRect->left);
+ MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pRect->top);
+ MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pRect->right);
+ if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pRect->bottom)) {
TRACE("Could not parse rect property\n");
return E_PROP_ID_UNSUPPORTED;
}