/* * Win32 5.1 msstyles theme format * * Copyright (C) 2003 Kevin Koltzau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include "windef.h" #include "winbase.h" #include "winuser.h" #include "wingdi.h" #include "uxtheme.h" #include "uxthemedll.h" #include "msstyles.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); #define MSSTYLES_VERSION 0x0003 /********************************************************************** * MSSTYLES_OpenThemeFile * * Load and validate a theme * * PARAMS * lpThemeFile Path to theme file to load * pszColorName Color name wanted, can be NULL * pszSizeName Size name wanted, can be NULL * * NOTES * If pszColorName or pszSizeName are NULL, the default color/size will be used. * If one/both are provided, they are validated against valid color/sizes and if * a match is not found, the function fails. */ HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf) { HMODULE hTheme; HRSRC hrsc; HRESULT hr = S_OK; WCHAR szPackThemVersionResource[] = { 'P','A','C','K','T','H','E','M','_','V','E','R','S','I','O','N', '\0' }; WCHAR szColorNamesResource[] = { 'C','O','L','O','R','N','A','M','E','S','\0' }; WCHAR szSizeNamesResource[] = { 'S','I','Z','E','N','A','M','E','S','\0' }; WORD version; DWORD versize; LPWSTR pszColors; LPWSTR pszSelectedColor = NULL; LPWSTR pszSizes; LPWSTR pszSelectedSize = NULL; LPWSTR tmp; TRACE("Opening %s\n", debugstr_w(lpThemeFile)); hTheme = LoadLibraryExW(lpThemeFile, NULL, LOAD_LIBRARY_AS_DATAFILE); /* Validate that this is really a theme */ if(!hTheme) goto invalid_theme; if(!(hrsc = FindResourceW(hTheme, MAKEINTRESOURCEW(1), szPackThemVersionResource))) { TRACE("No version resource found\n"); goto invalid_theme; } if((versize = SizeofResource(hTheme, hrsc)) != 2) { TRACE("Version resource found, but wrong size: %ld\n", versize); goto invalid_theme; } version = *(WORD*)LoadResource(hTheme, hrsc); if(version != MSSTYLES_VERSION) { TRACE("Version of theme file is unsupported: 0x%04x\n", version); goto invalid_theme; } if(!(hrsc = FindResourceW(hTheme, MAKEINTRESOURCEW(1), szColorNamesResource))) { TRACE("Color names resource not found\n"); goto invalid_theme; } pszColors = (LPWSTR)LoadResource(hTheme, hrsc); if(!(hrsc = FindResourceW(hTheme, MAKEINTRESOURCEW(1), szSizeNamesResource))) { TRACE("Size names resource not found\n"); goto invalid_theme; } pszSizes = (LPWSTR)LoadResource(hTheme, hrsc); /* Validate requested color against whats available from the theme */ if(pszColorName) { tmp = pszColors; while(*tmp) { if(!lstrcmpiW(pszColorName, tmp)) { pszSelectedColor = tmp; break; } tmp += lstrlenW(tmp)+1; } } else pszSelectedColor = pszColors; /* Use the default color */ /* Validate requested size against whats available from the theme */ if(pszSizeName) { tmp = pszSizes; while(*tmp) { if(!lstrcmpiW(pszSizeName, tmp)) { pszSelectedSize = tmp; break; } tmp += lstrlenW(tmp)+1; } } else pszSelectedSize = pszSizes; /* Use the default size */ if(!pszSelectedColor || !pszSelectedSize) { TRACE("Requested color/size (%s/%s) not found in theme\n", debugstr_w(pszColorName), debugstr_w(pszSizeName)); hr = E_PROP_ID_UNSUPPORTED; goto invalid_theme; } *tf = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_FILE)); (*tf)->hTheme = hTheme; (*tf)->pszAvailColors = pszColors; (*tf)->pszAvailSizes = pszSizes; (*tf)->pszSelectedColor = pszSelectedColor; (*tf)->pszSelectedSize = pszSelectedSize; return S_OK; invalid_theme: if(hTheme) FreeLibrary(hTheme); if(!hr) hr = HRESULT_FROM_WIN32(GetLastError()); return hr; } /*********************************************************************** * MSSTYLES_CloseThemeFile * * Close theme file and free resources */ void MSSTYLES_CloseThemeFile(PTHEME_FILE tf) { if(tf) { if(tf->hTheme) FreeLibrary(tf->hTheme); HeapFree(GetProcessHeap(), 0, tf); } }