diff --git a/reactos/dll/win32/uxtheme/metric.c b/reactos/dll/win32/uxtheme/metric.c index 05a5e932de9..b8eb77a1b38 100644 --- a/reactos/dll/win32/uxtheme/metric.c +++ b/reactos/dll/win32/uxtheme/metric.c @@ -35,7 +35,9 @@ BOOL WINAPI GetThemeSysBool(HTHEME hTheme, int iBoolID) TRACE("(%p, %d)\n", hTheme, iBoolID); SetLastError(0); if(hTheme) { - if((tp = MSSTYLES_FindMetric(TMT_BOOL, iBoolID))) { + PTHEME_CLASS ptc = (PTHEME_CLASS) hTheme; + + if((tp = MSSTYLES_FindMetric(ptc->tf, TMT_BOOL, iBoolID))) { hr = MSSTYLES_GetPropertyBool(tp, &ret); if(SUCCEEDED(hr)) return ret; @@ -62,10 +64,15 @@ COLORREF WINAPI GetThemeSysColor(HTHEME hTheme, int iColorID) HRESULT hr; PTHEME_PROPERTY tp; + // TODO: Check if this is correct + if ( iColorID >= 0 && iColorID < 32) + iColorID += TMT_SCROLLBAR; + TRACE("(%p, %d)\n", hTheme, iColorID); SetLastError(0); if(hTheme) { - if((tp = MSSTYLES_FindMetric(TMT_COLOR, iColorID))) { + PTHEME_CLASS ptc = (PTHEME_CLASS) hTheme; + if((tp = MSSTYLES_FindMetric(ptc->tf, TMT_COLOR, iColorID))) { COLORREF color; hr = MSSTYLES_GetPropertyColor(tp, &color); if(SUCCEEDED(hr)) @@ -96,7 +103,8 @@ HRESULT WINAPI GetThemeSysFont(HTHEME hTheme, int iFontID, LOGFONTW *plf) TRACE("(%p, %d)\n", hTheme, iFontID); if(hTheme) { - if((tp = MSSTYLES_FindMetric(TMT_FONT, iFontID))) { + PTHEME_CLASS ptc = (PTHEME_CLASS) hTheme; + if((tp = MSSTYLES_FindMetric(ptc->tf, TMT_FONT, iFontID))) { HDC hdc = GetDC(NULL); hr = MSSTYLES_GetPropertyFont(tp, hdc, plf); ReleaseDC(NULL, hdc); @@ -134,6 +142,7 @@ HRESULT WINAPI GetThemeSysFont(HTHEME hTheme, int iFontID, LOGFONTW *plf) HRESULT WINAPI GetThemeSysInt(HTHEME hTheme, int iIntID, int *piValue) { PTHEME_PROPERTY tp; + PTHEME_CLASS ptc = (PTHEME_CLASS) hTheme; TRACE("(%p, %d)\n", hTheme, iIntID); if(!hTheme) @@ -142,7 +151,7 @@ HRESULT WINAPI GetThemeSysInt(HTHEME hTheme, int iIntID, int *piValue) WARN("Unknown IntID: %d\n", iIntID); return STG_E_INVALIDPARAMETER; } - if((tp = MSSTYLES_FindMetric(TMT_INT, iIntID))) + if((tp = MSSTYLES_FindMetric(ptc->tf , TMT_INT, iIntID))) return MSSTYLES_GetPropertyInt(tp, piValue); return E_PROP_ID_UNSUPPORTED; } @@ -168,6 +177,8 @@ int WINAPI GetThemeSysSize(HTHEME hTheme, int iSizeID) }; if(hTheme) { + PTHEME_CLASS ptc = (PTHEME_CLASS) hTheme; + for(i=0; itf, TMT_SIZE, id))) { if(SUCCEEDED(MSSTYLES_GetPropertyInt(tp, &i))) { return i; } @@ -188,6 +199,12 @@ int WINAPI GetThemeSysSize(HTHEME hTheme, int iSizeID) return 0; } } + + + // TODO: Check if this is correct + // In windows for SM_CXFRAME this function returns what seems to be the non client metric iBorderWidth + if (iSizeID == SM_CXFRAME) + return GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME); return GetSystemMetrics(iSizeID); } @@ -198,6 +215,7 @@ HRESULT WINAPI GetThemeSysString(HTHEME hTheme, int iStringID, LPWSTR pszStringBuff, int cchMaxStringChars) { PTHEME_PROPERTY tp; + PTHEME_CLASS ptc = (PTHEME_CLASS) hTheme; TRACE("(%p, %d)\n", hTheme, iStringID); if(!hTheme) @@ -206,7 +224,7 @@ HRESULT WINAPI GetThemeSysString(HTHEME hTheme, int iStringID, WARN("Unknown StringID: %d\n", iStringID); return STG_E_INVALIDPARAMETER; } - if((tp = MSSTYLES_FindMetric(TMT_STRING, iStringID))) + if((tp = MSSTYLES_FindMetric(ptc->tf, TMT_STRING, iStringID))) return MSSTYLES_GetPropertyString(tp, pszStringBuff, cchMaxStringChars); return E_PROP_ID_UNSUPPORTED; } diff --git a/reactos/dll/win32/uxtheme/msstyles.c b/reactos/dll/win32/uxtheme/msstyles.c index a312149c3fe..23b329993e1 100644 --- a/reactos/dll/win32/uxtheme/msstyles.c +++ b/reactos/dll/win32/uxtheme/msstyles.c @@ -30,7 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); 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; @@ -42,8 +41,6 @@ static const WCHAR szThemesIniResource[] = { 't','h','e','m','e','s','_','i','n','i','\0' }; -static PTHEME_FILE tfActiveTheme; - /***********************************************************************/ /********************************************************************** @@ -214,21 +211,13 @@ void MSSTYLES_CloseThemeFile(PTHEME_FILE tf) } /*********************************************************************** - * MSSTYLES_SetActiveTheme + * MSSTYLES_ReferenceTheme * - * Set the current active theme + * Increase the reference count of the theme file */ -HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf, BOOL setMetrics) +HRESULT MSSTYLES_ReferenceTheme(PTHEME_FILE tf) { - if(tfActiveTheme) - MSSTYLES_CloseThemeFile(tfActiveTheme); - tfActiveTheme = tf; - if (tfActiveTheme) - { - tfActiveTheme->dwRefCount++; - if(!tfActiveTheme->classes) - MSSTYLES_ParseThemeIni(tfActiveTheme, setMetrics); - } + tf->dwRefCount++; return S_OK; } @@ -545,7 +534,7 @@ static inline PTHEME_PROPERTY MSSTYLES_PSFindProperty(PTHEME_PARTSTATE ps, int i } /*********************************************************************** - * MSSTYLES_FFindMetric + * MSSTYLES_FindMetric * * Find a metric property for a theme file * @@ -557,30 +546,11 @@ static inline PTHEME_PROPERTY MSSTYLES_PSFindProperty(PTHEME_PARTSTATE ps, int i * RETURNS * The property found, or NULL */ -static inline PTHEME_PROPERTY MSSTYLES_FFindMetric(PTHEME_FILE tf, int iPropertyPrimitive, int iPropertyId) +PTHEME_PROPERTY MSSTYLES_FindMetric(PTHEME_FILE tf, int iPropertyPrimitive, int iPropertyId) { return MSSTYLES_LFindProperty(tf->metrics, iPropertyPrimitive, iPropertyId); } -/*********************************************************************** - * MSSTYLES_FindMetric - * - * Find a metric property for the current installed theme - * - * PARAMS - * tf Theme file - * iPropertyPrimitive Type of value expected - * iPropertyId ID of the required value - * - * RETURNS - * The property found, or NULL - */ -PTHEME_PROPERTY MSSTYLES_FindMetric(int iPropertyPrimitive, int iPropertyId) -{ - if(!tfActiveTheme) return NULL; - return MSSTYLES_FFindMetric(tfActiveTheme, iPropertyPrimitive, iPropertyId); -} - /*********************************************************************** * MSSTYLES_AddProperty * @@ -639,7 +609,7 @@ static PTHEME_PROPERTY MSSTYLES_AddProperty(PTHEME_PARTSTATE ps, int iPropertyPr */ static PTHEME_PROPERTY MSSTYLES_AddMetric(PTHEME_FILE tf, int iPropertyPrimitive, int iPropertyId, LPCWSTR lpValue, DWORD dwValueLen) { - PTHEME_PROPERTY cur = MSSTYLES_FFindMetric(tf, iPropertyPrimitive, iPropertyId); + PTHEME_PROPERTY cur = MSSTYLES_FindMetric(tf, iPropertyPrimitive, iPropertyId); /* Should duplicate properties overwrite the original, or be ignored? */ if(cur) return cur; @@ -656,185 +626,6 @@ 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; -}; - -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), - &state->metrics, 0); - SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (LOGFONTW), - &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), - &state->metrics, 0); - SystemParametersInfoW (SPI_SETICONTITLELOGFONT, sizeof (state->iconTitleFont), - &state->iconTitleFont, 0); - } -} - /*********************************************************************** * MSSTYLES_ParseThemeIni * @@ -843,7 +634,7 @@ static void parse_apply_nonclient (struct PARSENONCLIENTSTATE* state) * PARAMS * tf Theme to parse */ -static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) +void MSSTYLES_ParseThemeIni(PTHEME_FILE tf) { 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'}; @@ -863,73 +654,50 @@ static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) DWORD dwValueLen; LPCWSTR lpValue; + if(tf->classes) + return; + ini = MSSTYLES_GetActiveThemeIni(tf); - 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))) { + while((lpName=UXINI_GetNextSection(ini, &dwLen))) + { + if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpName, dwLen, szSysMetrics, -1) == CSTR_EQUAL) + { + 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) { - 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); + if(MSSTYLES_LookupProperty(szPropertyName, &iPropertyPrimitive, &iPropertyId)) + { + /* Catch all metrics, including colors */ + MSSTYLES_AddMetric(tf, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen); } - else { + else + { TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName)); } } - if (setMetrics) - { - parse_apply_color (&colorState); - parse_apply_nonclient (&nonClientState); - } continue; } - if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) { + + if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) + { BOOL isGlobal = FALSE; - if(!lstrcmpiW(szClassName, szGlobals)) { + if(!lstrcmpiW(szClassName, szGlobals)) + { isGlobal = TRUE; } cls = MSSTYLES_AddClass(tf, szAppName, szClassName); ps = MSSTYLES_AddPartState(cls, iPartId, iStateId); - 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]))); - if(MSSTYLES_LookupProperty(szPropertyName, &iPropertyPrimitive, &iPropertyId)) { + if(MSSTYLES_LookupProperty(szPropertyName, &iPropertyPrimitive, &iPropertyId)) + { MSSTYLES_AddProperty(ps, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen, isGlobal); } - else { + else + { TRACE("Unknown property %s\n", debugstr_w(szPropertyName)); } } @@ -939,19 +707,25 @@ static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) /* App/Class combos override values defined by the base class, map these overrides */ globals = MSSTYLES_FindClass(tf, NULL, szGlobals); cls = tf->classes; - while(cls) { - if(*cls->szAppName) { + while(cls) + { + if(*cls->szAppName) + { cls->overrides = MSSTYLES_FindClass(tf, NULL, cls->szClassName); - if(!cls->overrides) { + if(!cls->overrides) + { TRACE("No overrides found for app %s class %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName)); } - else { + else + { cls->overrides = globals; } } - else { + else + { /* Everything overrides globals..except globals */ - if(cls != globals) cls->overrides = globals; + if(cls != globals) + cls->overrides = globals; } cls = cls->next; } @@ -972,7 +746,7 @@ static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) * to a particular application * pszClassList List of requested classes, semicolon delimited */ -PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList) +PTHEME_CLASS MSSTYLES_OpenThemeClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszClassList) { PTHEME_CLASS cls = NULL; WCHAR szClassName[MAX_THEME_CLASS_NAME]; @@ -980,29 +754,25 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList) LPCWSTR end; DWORD len; - if(!tfActiveTheme) { - TRACE("there is no active theme\n"); + if(!tf->classes) { return NULL; } - if(!tfActiveTheme->classes) { - return NULL; - } start = pszClassList; while((end = strchrW(start, ';'))) { len = end-start; lstrcpynW(szClassName, start, min(len+1, sizeof(szClassName)/sizeof(szClassName[0]))); start = end+1; - cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); + cls = MSSTYLES_FindClass(tf, pszAppName, szClassName); if(cls) break; } if(!cls && *start) { lstrcpynW(szClassName, start, sizeof(szClassName)/sizeof(szClassName[0])); - cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); + cls = MSSTYLES_FindClass(tf, pszAppName, szClassName); } if(cls) { TRACE("Opened app %s, class %s from list %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName), debugstr_w(pszClassList)); - cls->tf = tfActiveTheme; + cls->tf = tf; cls->tf->dwRefCount++; } return cls; diff --git a/reactos/dll/win32/uxtheme/system.c b/reactos/dll/win32/uxtheme/system.c index ae42df73ec8..40747f6646f 100644 --- a/reactos/dll/win32/uxtheme/system.c +++ b/reactos/dll/win32/uxtheme/system.c @@ -51,9 +51,8 @@ static ATOM atSubIdList; ATOM atWndContrext; static BOOL bThemeActive = FALSE; -static WCHAR szCurrentTheme[MAX_PATH]; -static WCHAR szCurrentColor[64]; -static WCHAR szCurrentSize[64]; + +static PTHEME_FILE ActiveThemeFile; /***********************************************************************/ @@ -128,6 +127,19 @@ static DWORD query_reg_path (HKEY hKey, LPCWSTR lpszValue, return dwRet; } +static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf) +{ + if(ActiveThemeFile) + MSSTYLES_CloseThemeFile(ActiveThemeFile); + ActiveThemeFile = tf; + if (ActiveThemeFile) + { + MSSTYLES_ReferenceTheme(ActiveThemeFile); + MSSTYLES_ParseThemeIni(ActiveThemeFile); + } + return S_OK; +} + /*********************************************************************** * UXTHEME_LoadTheme * @@ -140,6 +152,9 @@ void UXTHEME_LoadTheme(BOOL bLoad) HRESULT hr; WCHAR tmp[10]; PTHEME_FILE pt; + WCHAR szCurrentTheme[MAX_PATH]; + WCHAR szCurrentColor[64]; + WCHAR szCurrentSize[64]; if(bLoad == TRUE) { @@ -180,23 +195,17 @@ void UXTHEME_LoadTheme(BOOL bLoad) &pt); if(FAILED(hr)) { bThemeActive = FALSE; - szCurrentTheme[0] = '\0'; - szCurrentColor[0] = '\0'; - szCurrentSize[0] = '\0'; } else { - /* Make sure the global color & size match the theme */ - lstrcpynW(szCurrentColor, pt->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0])); - lstrcpynW(szCurrentSize, pt->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0])); - - MSSTYLES_SetActiveTheme(pt, FALSE); TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme), debugstr_w(szCurrentColor), debugstr_w(szCurrentSize)); + + UXTHEME_SetActiveTheme(pt); MSSTYLES_CloseThemeFile(pt); } } if(!bThemeActive) { - MSSTYLES_SetActiveTheme(NULL, FALSE); + UXTHEME_SetActiveTheme(NULL); TRACE("Theming not active\n"); } } @@ -453,32 +462,26 @@ static void UXTHEME_SaveSystemMetrics(void) } /*********************************************************************** - * UXTHEME_SetActiveTheme + * UXTHEME_ApplyTheme * * Change the current active theme */ -static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf) +static HRESULT UXTHEME_ApplyTheme(PTHEME_FILE tf) { HKEY hKey; WCHAR tmp[2]; HRESULT hr; if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics(); - hr = MSSTYLES_SetActiveTheme(tf, TRUE); + hr = UXTHEME_SetActiveTheme(tf); if(FAILED(hr)) return hr; if(tf) { bThemeActive = TRUE; - lstrcpynW(szCurrentTheme, tf->szThemeFile, sizeof(szCurrentTheme)/sizeof(szCurrentTheme[0])); - lstrcpynW(szCurrentColor, tf->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0])); - lstrcpynW(szCurrentSize, tf->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0])); } else { UXTHEME_RestoreSystemMetrics(); bThemeActive = FALSE; - szCurrentTheme[0] = '\0'; - szCurrentColor[0] = '\0'; - szCurrentSize[0] = '\0'; } TRACE("Writing theme config to registry\n"); @@ -487,12 +490,12 @@ static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf) tmp[1] = '\0'; RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (const BYTE*)tmp, sizeof(WCHAR)*2); if(bThemeActive) { - RegSetValueExW(hKey, szColorName, 0, REG_SZ, (const BYTE*)szCurrentColor, - (lstrlenW(szCurrentColor)+1)*sizeof(WCHAR)); - RegSetValueExW(hKey, szSizeName, 0, REG_SZ, (const BYTE*)szCurrentSize, - (lstrlenW(szCurrentSize)+1)*sizeof(WCHAR)); - RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*)szCurrentTheme, - (lstrlenW(szCurrentTheme)+1)*sizeof(WCHAR)); + RegSetValueExW(hKey, szColorName, 0, REG_SZ, (const BYTE*)tf->pszSelectedColor, + (lstrlenW(tf->pszSelectedColor)+1)*sizeof(WCHAR)); + RegSetValueExW(hKey, szSizeName, 0, REG_SZ, (const BYTE*)tf->pszSelectedSize, + (lstrlenW(tf->pszSelectedSize)+1)*sizeof(WCHAR)); + RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*)tf->szThemeFile, + (lstrlenW(tf->szThemeFile)+1)*sizeof(WCHAR)); } else { RegDeleteValueW(hKey, szColorName); @@ -619,10 +622,8 @@ static LPWSTR UXTHEME_GetWindowProperty(HWND hwnd, ATOM aProp, LPWSTR pszBuffer, return NULL; } -/*********************************************************************** - * OpenThemeDataEx (UXTHEME.61) - */ -HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) +static HTHEME WINAPI +OpenThemeDataInternal(PTHEME_FILE ThemeFile, HWND hwnd, LPCWSTR pszClassList, DWORD flags) { WCHAR szAppBuff[256]; WCHAR szClassBuff[256]; @@ -649,7 +650,7 @@ HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) pszUseClassList = pszClassList; if (pszUseClassList) - hTheme = MSSTYLES_OpenThemeClass(pszAppName, pszUseClassList); + hTheme = MSSTYLES_OpenThemeClass(ThemeFile, pszAppName, pszUseClassList); } if(IsWindow(hwnd)) SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme); @@ -657,9 +658,24 @@ HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) return hTheme; } +/*********************************************************************** + * OpenThemeDataEx (UXTHEME.61) + */ +HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) +{ + return OpenThemeDataInternal(ActiveThemeFile, hwnd, pszClassList, flags); +} + +/*********************************************************************** + * OpenThemeDataEx (UXTHEME.16) + */ HTHEME WINAPI OpenThemeDataFromFile(HTHEMEFILE hThemeFile, HWND hwnd, LPCWSTR pszClassList, DWORD flags) { - return S_OK; + PTHEME_FILE ThemeFile = (PTHEME_FILE)hThemeFile; + + MSSTYLES_ParseThemeIni(ThemeFile); + + return OpenThemeDataInternal(ThemeFile, hwnd, pszClassList, flags); } /*********************************************************************** @@ -667,7 +683,7 @@ HTHEME WINAPI OpenThemeDataFromFile(HTHEMEFILE hThemeFile, HWND hwnd, LPCWSTR ps */ HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist) { - return OpenThemeDataEx(hwnd, classlist, 0); + return OpenThemeDataInternal(ActiveThemeFile, hwnd, classlist, 0); } /*********************************************************************** @@ -720,11 +736,35 @@ HRESULT WINAPI GetCurrentThemeName(LPWSTR pszThemeFileName, int dwMaxNameChars, LPWSTR pszColorBuff, int cchMaxColorChars, LPWSTR pszSizeBuff, int cchMaxSizeChars) { - if(!bThemeActive) - return E_PROP_ID_UNSUPPORTED; - if(pszThemeFileName) lstrcpynW(pszThemeFileName, szCurrentTheme, dwMaxNameChars); - if(pszColorBuff) lstrcpynW(pszColorBuff, szCurrentColor, cchMaxColorChars); - if(pszSizeBuff) lstrcpynW(pszSizeBuff, szCurrentSize, cchMaxSizeChars); + int cchar; + + if(ActiveThemeFile == NULL) + return E_PROP_ID_UNSUPPORTED; + + if(pszThemeFileName) + { + cchar = lstrlenW(ActiveThemeFile->szThemeFile) + 1; + if(cchar > dwMaxNameChars) + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + lstrcpynW(pszThemeFileName, ActiveThemeFile->szThemeFile, cchar); + } + + if(pszColorBuff) + { + cchar = lstrlenW(ActiveThemeFile->pszSelectedColor) + 1; + if(cchar > cchMaxColorChars) + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + lstrcpynW(pszColorBuff, ActiveThemeFile->pszSelectedColor, cchar); + } + + if(pszSizeBuff) + { + cchar = lstrlenW(ActiveThemeFile->pszSelectedSize) + 1; + if(cchar > cchMaxSizeChars) + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + lstrcpynW(pszSizeBuff, ActiveThemeFile->pszSelectedSize, cchar); + } + return S_OK; } @@ -936,7 +976,7 @@ HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, char *unknown, HWND hWnd) { HRESULT hr; TRACE("(%p,%s,%p)\n", hThemeFile, unknown, hWnd); - hr = UXTHEME_SetActiveTheme(hThemeFile); + hr = UXTHEME_ApplyTheme(hThemeFile); UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED); return hr; } @@ -1229,6 +1269,6 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, PNONCLIENTMETRICSW pncMetrics, COLORREF* lpaRgbValues) { - return S_OK; + return E_NOTIMPL; } diff --git a/reactos/dll/win32/uxtheme/uxthemep.h b/reactos/dll/win32/uxtheme/uxthemep.h index 83915c49505..72627ffb602 100644 --- a/reactos/dll/win32/uxtheme/uxthemep.h +++ b/reactos/dll/win32/uxtheme/uxthemep.h @@ -79,18 +79,20 @@ typedef struct _THEME_FILE { typedef struct _UXINI_FILE *PUXINI_FILE; -HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf); -void MSSTYLES_CloseThemeFile(PTHEME_FILE tf); -HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf, BOOL setMetrics); -PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList); -HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc); BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwId); BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue); BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId); + +HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf); +HRESULT MSSTYLES_ReferenceTheme(PTHEME_FILE tf); +void MSSTYLES_CloseThemeFile(PTHEME_FILE tf); +void MSSTYLES_ParseThemeIni(PTHEME_FILE tf); +PTHEME_CLASS MSSTYLES_OpenThemeClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszClassList); +HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc); PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf); PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId, PTHEME_CLASS *tcNext); PTHEME_PROPERTY MSSTYLES_FindProperty(PTHEME_CLASS tc, int iPartId, int iStateId, int iPropertyPrimitive, int iPropertyId); -PTHEME_PROPERTY MSSTYLES_FindMetric(int iPropertyPrimitive, int iPropertyId); +PTHEME_PROPERTY MSSTYLES_FindMetric(PTHEME_FILE tf, int iPropertyPrimitive, int iPropertyId); HBITMAP MSSTYLES_LoadBitmap(PTHEME_CLASS tc, LPCWSTR lpFilename, BOOL* hasAlpha); HRESULT MSSTYLES_GetPropertyBool(PTHEME_PROPERTY tp, BOOL *pfVal);