/********************************************************************** * EnumThemeSizes (UXTHEME.10) * * Enumerate theme colors available with a particular size * * PARAMS * pszThemeFileName Path to a msstyles theme file * pszColorName Theme color to enumerate available sizes * If NULL the default theme color is used * dwSizeNum Size index to retrieve, increment from 0 * pszSizeNames Output size names * * RETURNS * S_OK on success * E_PROP_ID_UNSUPPORTED when dwSizeName does not refer to a size * or when pszColorName does not refer to a valid color * * NOTES * XP fails with E_POINTER when pszSizeNames points to a buffer smaller than * sizeof(THEMENAMES). * * Not very efficient that I'm opening & validating the theme every call, but * this is undocumented and almost never called.. * (and this is how windows works too) */ HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName, DWORD dwSizeNum, PTHEMENAMES pszSizeNames) { PTHEME_FILE pt; HRESULT hr; LPWSTR tmp; UINT resourceId = dwSizeNum + 3000; TRACE("(%s,%s,%d)\n", debugstr_w(pszThemeFileName), debugstr_w(pszColorName), dwSizeNum); hr = MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, NULL, &pt); if(FAILED(hr)) return hr; tmp = pt->pszAvailSizes; while(dwSizeNum && *tmp) { dwSizeNum--; tmp += lstrlenW(tmp)+1; } if(!dwSizeNum && *tmp) { TRACE("%s\n", debugstr_w(tmp)); lstrcpyW(pszSizeNames->szName, tmp); LoadStringW (pt->hTheme, resourceId, pszSizeNames->szDisplayName, sizeof (pszSizeNames->szDisplayName) / sizeof (WCHAR)); LoadStringW (pt->hTheme, resourceId+1000, pszSizeNames->szTooltip, sizeof (pszSizeNames->szTooltip) / sizeof (WCHAR)); } else hr = E_PROP_ID_UNSUPPORTED; MSSTYLES_CloseThemeFile(pt); return hr; }
/*********************************************************************** * UXTHEME_LoadTheme * * Set the current active theme from the registry */ static void UXTHEME_LoadTheme(void) { HKEY hKey; DWORD buffsize; HRESULT hr; WCHAR tmp[10]; PTHEME_FILE pt; /* Get current theme configuration */ if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) { TRACE("Loading theme config\n"); buffsize = sizeof(tmp)/sizeof(tmp[0]); if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize)) { bThemeActive = (tmp[0] != '0'); } else { bThemeActive = FALSE; TRACE("Failed to get ThemeActive: %d\n", GetLastError()); } buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]); if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor, &buffsize)) szCurrentColor[0] = '\0'; buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]); if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize, &buffsize)) szCurrentSize[0] = '\0'; if (query_reg_path (hKey, szDllName, szCurrentTheme)) szCurrentTheme[0] = '\0'; RegCloseKey(hKey); } else TRACE("Failed to open theme registry key\n"); if(bThemeActive) { /* Make sure the theme requested is actually valid */ hr = MSSTYLES_OpenThemeFile(szCurrentTheme, szCurrentColor[0]?szCurrentColor:NULL, szCurrentSize[0]?szCurrentSize:NULL, &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)); MSSTYLES_CloseThemeFile(pt); } } if(!bThemeActive) { MSSTYLES_SetActiveTheme(NULL, FALSE); TRACE("Theming not active\n"); } }
/********************************************************************** * OpenThemeFile (UXTHEME.2) * * Opens a theme file, which can be used to change the current theme, etc * * PARAMS * pszThemeFileName Path to a msstyles theme file * pszColorName Color defined in the theme, eg. NormalColor * pszSizeName Size defined in the theme, eg. NormalSize * hThemeFile Handle to theme file * * RETURNS * Success: S_OK * Failure: HRESULT error-code */ HRESULT WINAPI OpenThemeFile(LPCWSTR pszThemeFileName, LPCWSTR pszColorName, LPCWSTR pszSizeName, HTHEMEFILE *hThemeFile, DWORD unknown) { TRACE("(%s,%s,%s,%p,%d)\n", debugstr_w(pszThemeFileName), debugstr_w(pszColorName), debugstr_w(pszSizeName), hThemeFile, unknown); return MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, pszSizeName, (PTHEME_FILE*)hThemeFile); }
/*********************************************************************** * GetThemeDocumentationProperty (UXTHEME.@) * * Try and retrieve the documentation property from string resources * if that fails, get it from the [documentation] section of themes.ini */ HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, LPWSTR pszValueBuff, int cchMaxValChars) { const WORD wDocToRes[] = { TMT_DISPLAYNAME,5000, TMT_TOOLTIP,5001, TMT_COMPANY,5002, TMT_AUTHOR,5003, TMT_COPYRIGHT,5004, TMT_URL,5005, TMT_VERSION,5006, TMT_DESCRIPTION,5007 }; PTHEME_FILE pt; HRESULT hr; unsigned int i; int iDocId; TRACE("(%s,%s,%p,%d)\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName), pszValueBuff, cchMaxValChars); hr = MSSTYLES_OpenThemeFile(pszThemeName, NULL, NULL, &pt); if(FAILED(hr)) return hr; /* Try to load from string resources */ hr = E_PROP_ID_UNSUPPORTED; if(MSSTYLES_LookupProperty(pszPropertyName, NULL, &iDocId)) { for(i=0; i<sizeof(wDocToRes)/sizeof(wDocToRes[0]); i+=2) { if(wDocToRes[i] == iDocId) { if(LoadStringW(pt->hTheme, wDocToRes[i+1], pszValueBuff, cchMaxValChars)) { hr = S_OK; break; } } } } /* If loading from string resource failed, try getting it from the theme.ini */ if(FAILED(hr)) { PUXINI_FILE uf = MSSTYLES_GetThemeIni(pt); if(UXINI_FindSection(uf, szIniDocumentation)) { LPCWSTR lpValue; DWORD dwLen; if(UXINI_FindValue(uf, pszPropertyName, &lpValue, &dwLen)) { lstrcpynW(pszValueBuff, lpValue, min(dwLen+1,cchMaxValChars)); hr = S_OK; } } UXINI_CloseINI(uf); } MSSTYLES_CloseThemeFile(pt); return hr; }
/********************************************************************** * CheckThemeSignature (UXTHEME.29) * * Validates the signature of a theme file * * PARAMS * pszIniFileName Path to a theme file * * RETURNS * Success: S_OK * Failure: HRESULT error-code */ HRESULT WINAPI CheckThemeSignature(LPCWSTR pszThemeFileName) { PTHEME_FILE pt; HRESULT hr; TRACE("(%s)\n", debugstr_w(pszThemeFileName)); hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, NULL, &pt); if(FAILED(hr)) return hr; MSSTYLES_CloseThemeFile(pt); return S_OK; }
/********************************************************************** * GetThemeDefaults (UXTHEME.7) * * Get the default color & size for a theme * * PARAMS * pszThemeFileName Path to a msstyles theme file * pszColorName Buffer to receive the default color name * dwColorNameLen Length, in characters, of color name buffer * pszSizeName Buffer to receive the default size name * dwSizeNameLen Length, in characters, of size name buffer * * RETURNS * Success: S_OK * Failure: HRESULT error-code */ HRESULT WINAPI GetThemeDefaults(LPCWSTR pszThemeFileName, LPWSTR pszColorName, DWORD dwColorNameLen, LPWSTR pszSizeName, DWORD dwSizeNameLen) { PTHEME_FILE pt; HRESULT hr; TRACE("(%s,%p,%d,%p,%d)\n", debugstr_w(pszThemeFileName), pszColorName, dwColorNameLen, pszSizeName, dwSizeNameLen); hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, NULL, &pt); if(FAILED(hr)) return hr; lstrcpynW(pszColorName, pt->pszSelectedColor, dwColorNameLen); lstrcpynW(pszSizeName, pt->pszSelectedSize, dwSizeNameLen); MSSTYLES_CloseThemeFile(pt); return S_OK; }
/*********************************************************************** * UXTHEME_LoadTheme * * Set the current active theme from the registry */ void UXTHEME_LoadTheme(BOOL bLoad) { HKEY hKey; DWORD buffsize; HRESULT hr; WCHAR tmp[10]; PTHEME_FILE pt; WCHAR szCurrentTheme[MAX_PATH]; WCHAR szCurrentColor[64]; WCHAR szCurrentSize[64]; BOOL bThemeActive = FALSE; if(bLoad == TRUE) { /* Get current theme configuration */ if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) { TRACE("Loading theme config\n"); buffsize = sizeof(tmp)/sizeof(tmp[0]); if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize)) { bThemeActive = (tmp[0] != '0'); } else { bThemeActive = FALSE; TRACE("Failed to get ThemeActive: %d\n", GetLastError()); } buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]); if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor, &buffsize)) szCurrentColor[0] = '\0'; buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]); if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize, &buffsize)) szCurrentSize[0] = '\0'; if (query_reg_path (hKey, szDllName, szCurrentTheme)) szCurrentTheme[0] = '\0'; RegCloseKey(hKey); } else TRACE("Failed to open theme registry key\n"); } else { bThemeActive = FALSE; } if(bThemeActive) { if( bIsThemeActive(szCurrentTheme, szCurrentColor, szCurrentSize) ) { TRACE("Tried to load active theme again\n"); return; } /* Make sure the theme requested is actually valid */ hr = MSSTYLES_OpenThemeFile(szCurrentTheme, szCurrentColor[0]?szCurrentColor:NULL, szCurrentSize[0]?szCurrentSize:NULL, &pt); if(FAILED(hr)) { bThemeActive = FALSE; } else { TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme), debugstr_w(szCurrentColor), debugstr_w(szCurrentSize)); UXTHEME_SetActiveTheme(pt); MSSTYLES_CloseThemeFile(pt); } } if(!bThemeActive) { UXTHEME_SetActiveTheme(NULL); TRACE("Theming not active\n"); } }