uxtheme: loading & validating

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Load, validate and retrieve a few properties from an msstyles theme
Index: dlls/uxtheme/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/uxtheme/Makefile.in,v
retrieving revision 1.3
diff -u -r1.3 Makefile.in
--- dlls/uxtheme/Makefile.in	4 Dec 2003 20:55:30 -0000	1.3
+++ dlls/uxtheme/Makefile.in	6 Dec 2003 20:21:21 -0000
@@ -3,7 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = uxtheme.dll
-IMPORTS   = gdi32 user32 advapi32 kernel32 ntdll
+IMPORTS   = gdi32 shlwapi user32 advapi32 kernel32 ntdll
 EXTRALIBS = $(LIBUNICODE)

 C_SRCS = \
@@ -11,7 +11,8 @@
 	main.c \
 	metric.c \
 	property.c \
-	system.c
+	system.c \
+	msstyles.c

 RC_SRCS = version.rc

Index: dlls/uxtheme/system.c
===================================================================
RCS file: /home/wine/wine/dlls/uxtheme/system.c,v
retrieving revision 1.1
diff -u -r1.1 system.c
--- dlls/uxtheme/system.c	4 Dec 2003 20:55:30 -0000	1.1
+++ dlls/uxtheme/system.c	6 Dec 2003 20:21:22 -0000
@@ -26,9 +26,12 @@
 #include "winbase.h"
 #include "winuser.h"
 #include "wingdi.h"
+#include "winreg.h"
+#include "shlwapi.h"
 #include "uxtheme.h"

 #include "uxthemedll.h"
+#include "msstyles.h"

 #include "wine/debug.h"

@@ -38,11 +41,28 @@
  * Defines and global variables
  */

+static const WCHAR szThemeManager[] = {
+    'S','o','f','t','w','a','r','e','\\',
+    'M','i','c','r','o','s','o','f','t','\\',
+    'W','i','n','d','o','w','s','\\',
+    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+    'T','h','e','m','e','M','a','n','a','g','e','r','\0'
+};
+static const WCHAR szThemeActive[] = {'T','h','e','m','e','A','c','t','i','v','e','\0'};
+static const WCHAR szSizeName[] = {'S','i','z','e','N','a','m','e','\0'};
+static const WCHAR szColorName[] = {'C','o','l','o','r','N','a','m','e','\0'};
+static const WCHAR szDllName[] = {'D','l','l','N','a','m','e','\0'};
+
 DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
 ATOM atWindowTheme;
 ATOM atSubAppName;
 ATOM atSubIdList;

+BOOL bThemeActive = FALSE;
+WCHAR szCurrentTheme[MAX_PATH];
+WCHAR szCurrentColor[64];
+WCHAR szCurrentSize[64];
+
 /***********************************************************************/

 /***********************************************************************
@@ -59,10 +79,65 @@
     const WCHAR szSubIdList[] = {
         'u','x','_','s','u','b','i','d','l','s','t','\0'
     };
+    HKEY hKey;
+    LONG buffsize;
+    HRESULT hr;
+    WCHAR tmp[10];
+    PTHEME_FILE pt;

     atWindowTheme = GlobalAddAtomW(szWindowTheme);
     atSubAppName  = GlobalAddAtomW(szSubAppName);
     atSubIdList   = GlobalAddAtomW(szSubIdList);
+
+    /* 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: %ld\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(SHRegGetPathW(hKey, NULL, szDllName, szCurrentTheme, 0))
+            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_CloseThemeFile(pt);
+        }
+    }
+
+    if(!bThemeActive)
+        TRACE("Themeing not active\n");
+    else
+        TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme),
+              debugstr_w(szCurrentColor), debugstr_w(szCurrentSize));
 }

 /***********************************************************************
@@ -70,8 +145,7 @@
  */
 BOOL WINAPI IsAppThemed(void)
 {
-    FIXME("stub\n");
-    return FALSE;
+    return IsThemeActive();
 }

 /***********************************************************************
@@ -79,8 +153,8 @@
  */
 BOOL WINAPI IsThemeActive(void)
 {
-    FIXME("stub\n");
-    return FALSE;
+    TRACE("\n");
+    return bThemeActive;
 }

 /***********************************************************************
@@ -91,8 +165,21 @@
  */
 HRESULT WINAPI EnableTheming(BOOL fEnable)
 {
-    FIXME("%d: stub\n", fEnable);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    HKEY hKey;
+    WCHAR szEnabled[] = {'0','\0'};
+
+    TRACE("(%d)\n", fEnable);
+
+    if(fEnable != bThemeActive) {
+        bThemeActive = fEnable;
+        if(bThemeActive) szEnabled[0] = '1';
+        if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
+            RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (LPBYTE)szEnabled, sizeof(WCHAR));
+            RegCloseKey(hKey);
+        }
+        PostMessageW(HWND_BROADCAST, WM_THEMECHANGED, 0, 0);
+    }
+    return S_OK;
  }

 /***********************************************************************
@@ -151,7 +238,9 @@
           debugstr_w(pszSubIdList));
     hr = UXTHEME_SetWindowProperty(hwnd, atSubAppName, pszSubAppName);
     if(SUCCEEDED(hr))
-      hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
+        hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
+    if(SUCCEEDED(hr))
+        PostMessageW(hwnd, WM_THEMECHANGED, 0, 0);
     return hr;
 }

@@ -162,8 +251,12 @@
                                    LPWSTR pszColorBuff, int cchMaxColorChars,
                                    LPWSTR pszSizeBuff, int cchMaxSizeChars)
 {
-    FIXME("stub\n");
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    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);
+    return S_OK;
 }
 
 /***********************************************************************
@@ -249,10 +342,10 @@
                              LPCWSTR pszSizeName, HTHEMEFILE *hThemeFile,
                              DWORD unknown)
 {
-    FIXME("%s,%s,%s,%ld: stub\n", debugstr_w(pszThemeFileName),
-          debugstr_w(pszColorName),
-          debugstr_w(pszSizeName), unknown);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    TRACE("(%s,%s,%s,%p,%ld)\n", debugstr_w(pszThemeFileName),
+          debugstr_w(pszColorName), debugstr_w(pszSizeName),
+          hThemeFile, unknown);
+    return MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, pszSizeName, (PTHEME_FILE*)hThemeFile);
 }
 
 /**********************************************************************
@@ -265,7 +358,8 @@
  */
 HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile)
 {
-    FIXME("stub\n");
+    TRACE("(%p)\n", hThemeFile);
+    MSSTYLES_CloseThemeFile(hThemeFile);
     return S_OK;
 }
 
@@ -311,8 +405,20 @@
                                 DWORD dwColorNameLen, LPWSTR pszSizeName,
                                 DWORD dwSizeNameLen)
 {
-    FIXME("%s: stub\n", debugstr_w(pszThemeFileName));
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    PTHEME_FILE pt;
+    HRESULT hr;
+    TRACE("(%s,%p,%ld,%p,%ld)\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;
 }
 
 /**********************************************************************
@@ -354,13 +460,37 @@
  * NOTES
  * XP fails with E_POINTER when pszColorName points to a buffer smaller then 605
  * characters
+ *
+ * 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 EnumThemeColors(LPWSTR pszThemeFileName, LPWSTR pszSizeName,
                                DWORD dwColorNum, LPWSTR pszColorName)
 {
-    FIXME("%s %s %ld: stub\n", debugstr_w(pszThemeFileName),
+    PTHEME_FILE pt;
+    HRESULT hr;
+    LPWSTR tmp;
+    TRACE("(%s,%s,%ld)\n", debugstr_w(pszThemeFileName),
           debugstr_w(pszSizeName), dwColorNum);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+
+    hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, pszSizeName, &pt);
+    if(FAILED(hr)) return hr;
+
+    tmp = pt->pszAvailColors;
+    while(dwColorNum && *tmp) {
+        dwColorNum--;
+        tmp += lstrlenW(tmp)+1;
+    }
+    if(!dwColorNum && *tmp) {
+        TRACE("%s\n", debugstr_w(tmp));
+        lstrcpyW(pszColorName, tmp);
+    }
+    else
+        hr = E_PROP_ID_UNSUPPORTED;
+
+    MSSTYLES_CloseThemeFile(pt);
+    return hr;
 }

 /**********************************************************************
@@ -383,12 +513,37 @@
  * NOTES
  * XP fails with E_POINTER when pszSizeName points to a buffer smaller then 605
  * characters
+ *
+ * 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, LPWSTR pszSizeName)
 {
-    FIXME("%s %s %ld: stub\n", debugstr_w(pszThemeFileName), debugstr_w(pszColorName), dwSizeNum);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    PTHEME_FILE pt;
+    HRESULT hr;
+    LPWSTR tmp;
+    TRACE("(%s,%s,%ld)\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(pszSizeName, tmp);
+    }
+    else
+        hr = E_PROP_ID_UNSUPPORTED;
+
+    MSSTYLES_CloseThemeFile(pt);
+    return hr;
 }

 /**********************************************************************
--- /dev/null	1969-12-31 19:00:00.000000000 -0500
+++ dlls/uxtheme/msstyles.c	2003-12-06 14:12:48.000000000 -0500
@@ -0,0 +1,172 @@
+/*
+ * 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 <stdarg.h>
+
+#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);
+    }
+}
--- /dev/null	1969-12-31 19:00:00.000000000 -0500
+++ dlls/uxtheme/msstyles.h	2003-12-05 21:31:49.000000000 -0500
@@ -0,0 +1,37 @@
+/*
+ * Internal msstyles related defines & declarations
+ *
+ * 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
+ */
+
+#ifndef __WINE_MSSTYLES_H
+#define __WINE_MSSTYLES_H
+
+typedef struct _THEME_FILE {
+    HMODULE hTheme;
+    LPWSTR pszAvailColors;
+    LPWSTR pszAvailSizes;
+
+    LPWSTR pszSelectedColor;
+    LPWSTR pszSelectedSize;
+} THEME_FILE, *PTHEME_FILE;
+
+HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf);
+void MSSTYLES_CloseThemeFile(PTHEME_FILE tf);
+
+
+#endif

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux