Add INI file processing.
Full implementation of GetThemeDocumentationProperty. Define string maps for parsing INI files into useable form. Implemented (undocumented) ApplyTheme to select current theme.
This commit is contained in:
parent
1614f91767
commit
e04ff33417
|
@ -12,7 +12,9 @@ C_SRCS = \
|
|||
metric.c \
|
||||
msstyles.c \
|
||||
property.c \
|
||||
system.c
|
||||
stylemap.c \
|
||||
system.c \
|
||||
uxini.c
|
||||
|
||||
RC_SRCS = version.rc
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
UXTHEME_InitSystem();
|
||||
UXTHEME_InitSystem(hInstDLL);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
|
|
|
@ -35,8 +35,22 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
|
||||
|
||||
/***********************************************************************
|
||||
* Defines and global variables
|
||||
*/
|
||||
|
||||
extern HINSTANCE hDllInst;
|
||||
|
||||
#define MSSTYLES_VERSION 0x0003
|
||||
|
||||
static const WCHAR szThemesIniResource[] = {
|
||||
't','h','e','m','e','s','_','i','n','i','\0'
|
||||
};
|
||||
|
||||
PTHEME_FILE tfActiveTheme = NULL;
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/**********************************************************************
|
||||
* MSSTYLES_OpenThemeFile
|
||||
*
|
||||
|
@ -144,12 +158,13 @@ HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWST
|
|||
goto invalid_theme;
|
||||
}
|
||||
|
||||
*tf = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_FILE));
|
||||
*tf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THEME_FILE));
|
||||
(*tf)->hTheme = hTheme;
|
||||
(*tf)->pszAvailColors = pszColors;
|
||||
(*tf)->pszAvailSizes = pszSizes;
|
||||
(*tf)->pszSelectedColor = pszSelectedColor;
|
||||
(*tf)->pszSelectedSize = pszSelectedSize;
|
||||
(*tf)->dwRefCount = 1;
|
||||
return S_OK;
|
||||
|
||||
invalid_theme:
|
||||
|
@ -166,7 +181,56 @@ invalid_theme:
|
|||
void MSSTYLES_CloseThemeFile(PTHEME_FILE tf)
|
||||
{
|
||||
if(tf) {
|
||||
if(tf->hTheme) FreeLibrary(tf->hTheme);
|
||||
HeapFree(GetProcessHeap(), 0, tf);
|
||||
tf->dwRefCount--;
|
||||
if(!tf->dwRefCount) {
|
||||
if(tf->hTheme) FreeLibrary(tf->hTheme);
|
||||
HeapFree(GetProcessHeap(), 0, tf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSSTYLES_SetActiveTheme
|
||||
*
|
||||
* Set the current active theme
|
||||
*/
|
||||
HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf)
|
||||
{
|
||||
if(tfActiveTheme)
|
||||
MSSTYLES_CloseThemeFile(tfActiveTheme);
|
||||
tfActiveTheme = tf;
|
||||
tfActiveTheme->dwRefCount++;
|
||||
FIXME("Process theme resources\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSSTYLES_GetThemeIni
|
||||
*
|
||||
* Retrieves themes.ini from a theme
|
||||
*/
|
||||
PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf)
|
||||
{
|
||||
return UXINI_LoadINI(tf, szThemesIniResource);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSSTYLES_OpenThemeClass
|
||||
*
|
||||
* Open a theme class
|
||||
*
|
||||
* PARAMS
|
||||
* tf Previously opened theme file
|
||||
* pszClassList List of requested classes, semicolon delimited
|
||||
*/
|
||||
PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszClassList)
|
||||
{
|
||||
FIXME("%s\n", debugstr_w(pszClassList));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc)
|
||||
{
|
||||
FIXME("%p\n", tc);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@
|
|||
#ifndef __WINE_MSSTYLES_H
|
||||
#define __WINE_MSSTYLES_H
|
||||
|
||||
#define TMT_ENUM 200
|
||||
|
||||
typedef struct _THEME_FILE {
|
||||
DWORD dwRefCount;
|
||||
HMODULE hTheme;
|
||||
LPWSTR pszAvailColors;
|
||||
LPWSTR pszAvailSizes;
|
||||
|
@ -30,8 +33,30 @@ typedef struct _THEME_FILE {
|
|||
LPWSTR pszSelectedSize;
|
||||
} THEME_FILE, *PTHEME_FILE;
|
||||
|
||||
typedef struct _THEME_CLASS {
|
||||
/* TODO */
|
||||
} THEME_CLASS, *PTHEME_CLASS;
|
||||
|
||||
typedef struct _UXINI_FILE {
|
||||
LPCWSTR lpIni;
|
||||
LPCWSTR lpCurLoc;
|
||||
LPCWSTR lpEnd;
|
||||
} 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);
|
||||
PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszClassList);
|
||||
HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc);
|
||||
BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, DWORD *dwPrimitive, DWORD *dwId);
|
||||
PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf);
|
||||
|
||||
PUXINI_FILE UXINI_LoadINI(PTHEME_FILE tf, LPCWSTR lpName);
|
||||
void UXINI_CloseINI(PUXINI_FILE uf);
|
||||
void UXINI_ResetINI(PUXINI_FILE uf);
|
||||
LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen);
|
||||
BOOL UXINI_FindSection(PUXINI_FILE uf, LPCWSTR lpName);
|
||||
LPCWSTR UXINI_GetNextValue(PUXINI_FILE uf, DWORD *dwNameLen, LPCWSTR *lpValue, DWORD *dwValueLen);
|
||||
BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,18 +34,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
|
||||
|
||||
/***********************************************************************
|
||||
* GetThemeDocumentationProperty (UXTHEME.@)
|
||||
*/
|
||||
HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName,
|
||||
LPCWSTR pszPropertyName,
|
||||
LPWSTR pszValueBuff,
|
||||
int cchMaxValChars)
|
||||
{
|
||||
FIXME("%s %s: stub\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName));
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetThemeBool (UXTHEME.@)
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,7 @@
|
|||
#include "winreg.h"
|
||||
#include "shlwapi.h"
|
||||
#include "uxtheme.h"
|
||||
#include "tmschema.h"
|
||||
|
||||
#include "uxthemedll.h"
|
||||
#include "msstyles.h"
|
||||
|
@ -53,6 +54,10 @@ 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'};
|
||||
|
||||
static const WCHAR szIniDocumentation[] = {'d','o','c','u','m','e','n','t','a','t','i','o','n','\0'};
|
||||
|
||||
HINSTANCE hDllInst;
|
||||
|
||||
DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
|
||||
ATOM atWindowTheme;
|
||||
ATOM atSubAppName;
|
||||
|
@ -66,29 +71,18 @@ WCHAR szCurrentSize[64];
|
|||
/***********************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
* UXTHEME_InitSystem
|
||||
* UXTHEME_LoadTheme
|
||||
*
|
||||
* Set the current active theme from the registry
|
||||
*/
|
||||
void UXTHEME_InitSystem()
|
||||
void UXTHEME_LoadTheme()
|
||||
{
|
||||
const WCHAR szWindowTheme[] = {
|
||||
'u','x','_','t','h','e','m','e','\0'
|
||||
};
|
||||
const WCHAR szSubAppName[] = {
|
||||
'u','x','_','s','u','b','a','p','p','\0'
|
||||
};
|
||||
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");
|
||||
|
@ -129,15 +123,84 @@ void UXTHEME_InitSystem()
|
|||
/* 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);
|
||||
TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme),
|
||||
debugstr_w(szCurrentColor), debugstr_w(szCurrentSize));
|
||||
MSSTYLES_CloseThemeFile(pt);
|
||||
}
|
||||
}
|
||||
|
||||
if(!bThemeActive)
|
||||
if(!bThemeActive) {
|
||||
MSSTYLES_SetActiveTheme(NULL);
|
||||
TRACE("Themeing not active\n");
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UXTHEME_SetActiveTheme
|
||||
*
|
||||
* Change the current active theme
|
||||
*/
|
||||
HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf)
|
||||
{
|
||||
HKEY hKey;
|
||||
WCHAR tmp[2];
|
||||
HRESULT hr;
|
||||
|
||||
hr = MSSTYLES_SetActiveTheme(tf);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
if(tf) {
|
||||
bThemeActive = TRUE;
|
||||
GetModuleFileNameW(tf->hTheme, szCurrentTheme, sizeof(szCurrentTheme)/sizeof(szCurrentTheme[0]));
|
||||
lstrcpynW(szCurrentColor, tf->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0]));
|
||||
lstrcpynW(szCurrentSize, tf->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0]));
|
||||
}
|
||||
else {
|
||||
bThemeActive = FALSE;
|
||||
szCurrentTheme[0] = '\0';
|
||||
szCurrentColor[0] = '\0';
|
||||
szCurrentSize[0] = '\0';
|
||||
return MSSTYLES_SetActiveTheme(NULL);
|
||||
}
|
||||
|
||||
TRACE("Writing theme config to registry\n");
|
||||
if(!RegCreateKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
|
||||
tmp[0] = bThemeActive?'1':'0';
|
||||
tmp[1] = '\0';
|
||||
RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (const BYTE*)tmp, sizeof(WCHAR)*2);
|
||||
RegSetValueExW(hKey, szColorName, 0, REG_SZ, (const BYTE*)szCurrentColor, lstrlenW(szCurrentColor)+1);
|
||||
RegSetValueExW(hKey, szSizeName, 0, REG_SZ, (const BYTE*)szCurrentSize, lstrlenW(szCurrentSize)+1);
|
||||
RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*)szCurrentTheme, lstrlenW(szCurrentTheme)+1);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
else
|
||||
TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme),
|
||||
debugstr_w(szCurrentColor), debugstr_w(szCurrentSize));
|
||||
TRACE("Failed to open theme registry key\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UXTHEME_InitSystem
|
||||
*/
|
||||
void UXTHEME_InitSystem(HINSTANCE hInst)
|
||||
{
|
||||
const WCHAR szWindowTheme[] = {
|
||||
'u','x','_','t','h','e','m','e','\0'
|
||||
};
|
||||
const WCHAR szSubAppName[] = {
|
||||
'u','x','_','s','u','b','a','p','p','\0'
|
||||
};
|
||||
const WCHAR szSubIdList[] = {
|
||||
'u','x','_','s','u','b','i','d','l','s','t','\0'
|
||||
};
|
||||
|
||||
hDllInst = hInst;
|
||||
|
||||
atWindowTheme = GlobalAddAtomW(szWindowTheme);
|
||||
atSubAppName = GlobalAddAtomW(szSubAppName);
|
||||
atSubIdList = GlobalAddAtomW(szSubIdList);
|
||||
|
||||
UXTHEME_LoadTheme();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -180,15 +243,21 @@ HRESULT WINAPI EnableTheming(BOOL fEnable)
|
|||
PostMessageW(HWND_BROADCAST, WM_THEMECHANGED, 0, 0);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OpenThemeData (UXTHEME.@)
|
||||
*/
|
||||
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR pszClassList)
|
||||
{
|
||||
FIXME("%p %s: stub\n", hwnd, debugstr_w(pszClassList));
|
||||
return NULL;
|
||||
HTHEME hTheme;
|
||||
TRACE("(%p,%s)\n", hwnd, debugstr_w(pszClassList));
|
||||
if(!bThemeActive)
|
||||
return NULL;
|
||||
hTheme = MSSTYLES_OpenThemeClass(pszClassList);
|
||||
if(IsWindow(hwnd))
|
||||
SetPropW(hwnd, MAKEINTATOMW(atWindowTheme), hTheme);
|
||||
return hTheme;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -281,10 +350,10 @@ void WINAPI SetThemeAppProperties(DWORD dwFlags)
|
|||
*/
|
||||
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
TRACE("(%p)\n", hTheme);
|
||||
if(!hTheme)
|
||||
return E_HANDLE;
|
||||
return S_OK;
|
||||
return MSSTYLES_CloseThemeClass(hTheme);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -310,6 +379,68 @@ BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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;
|
||||
int i;
|
||||
DWORD dwDocId;
|
||||
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, &dwDocId)) {
|
||||
for(i=0; i<sizeof(wDocToRes)/sizeof(wDocToRes[0]); i+=2) {
|
||||
if(wDocToRes[i] == dwDocId) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Undocumented functions
|
||||
*/
|
||||
|
@ -385,8 +516,11 @@ HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile)
|
|||
*/
|
||||
HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, char *unknown, HWND hWnd)
|
||||
{
|
||||
FIXME("%s: stub\n", unknown);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
HRESULT hr;
|
||||
TRACE("(%p,%s,%p)\n", hThemeFile, unknown, hWnd);
|
||||
hr = UXTHEME_SetActiveTheme(hThemeFile);
|
||||
PostMessageW(HWND_BROADCAST, WM_THEMECHANGED, 0, 0);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* Win32 5.1 uxtheme ini file processing
|
||||
*
|
||||
* Copyright (C) 2004 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 "winnls.h"
|
||||
|
||||
#include "msstyles.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
|
||||
|
||||
/***********************************************************************
|
||||
* Defines and global variables
|
||||
*/
|
||||
|
||||
static const WCHAR szTextFileResource[] = {
|
||||
'T','E','X','T','F','I','L','E','\0'
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_LoadINI
|
||||
*
|
||||
* Load a theme INI file out of resources from the specified
|
||||
* theme
|
||||
*
|
||||
* PARAMS
|
||||
* tf Theme to load INI file out of resources
|
||||
* lpName Resource name of the INI file
|
||||
*
|
||||
* RETURNS
|
||||
* INI file, or NULL if not found
|
||||
*/
|
||||
PUXINI_FILE UXINI_LoadINI(PTHEME_FILE tf, LPCWSTR lpName) {
|
||||
HRSRC hrsc;
|
||||
LPCWSTR lpThemesIni = NULL;
|
||||
PUXINI_FILE uf;
|
||||
DWORD dwIniSize;
|
||||
|
||||
if((hrsc = FindResourceW(tf->hTheme, lpName, szTextFileResource))) {
|
||||
if(!(lpThemesIni = (LPCWSTR)LoadResource(tf->hTheme, hrsc))) {
|
||||
TRACE("%s resource not found\n", debugstr_w(lpName));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dwIniSize = SizeofResource(tf->hTheme, hrsc) / sizeof(WCHAR);
|
||||
uf = HeapAlloc(GetProcessHeap(), 0, sizeof(UXINI_FILE));
|
||||
uf->lpIni = lpThemesIni;
|
||||
uf->lpCurLoc = lpThemesIni;
|
||||
uf->lpEnd = lpThemesIni + dwIniSize;
|
||||
return uf;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_CloseINI
|
||||
*
|
||||
* Close an open theme INI file
|
||||
*
|
||||
* PARAMS
|
||||
* uf Theme INI file to close
|
||||
*/
|
||||
void UXINI_CloseINI(PUXINI_FILE uf)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, uf);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_ResetINI
|
||||
*
|
||||
* Reset the current pointer into INI file to the beginning of the file
|
||||
*
|
||||
* PARAMS
|
||||
* uf Theme INI file to reset
|
||||
*/
|
||||
void UXINI_ResetINI(PUXINI_FILE uf)
|
||||
{
|
||||
uf->lpCurLoc = uf->lpIni;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_eof
|
||||
*
|
||||
* Determines if we are at the end of the INI file
|
||||
*
|
||||
* PARAMS
|
||||
* uf Theme INI file to test
|
||||
*/
|
||||
static inline BOOL UXINI_eof(PUXINI_FILE uf)
|
||||
{
|
||||
return uf->lpCurLoc >= uf->lpEnd;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_isspace
|
||||
*
|
||||
* Check if a character is a space character
|
||||
*
|
||||
* PARAMS
|
||||
* c Character to test
|
||||
*/
|
||||
static inline BOOL UXINI_isspace(WCHAR c)
|
||||
{
|
||||
if (isspace(c)) return TRUE;
|
||||
if (c=='\r') return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_GetNextLine
|
||||
*
|
||||
* Get the next line in the INI file, non NULL terminated
|
||||
* removes whitespace at beginning and end of line, and removes comments
|
||||
*
|
||||
* PARAMS
|
||||
* uf INI file to retrieve next line
|
||||
* dwLen Location to store pointer to line length
|
||||
*
|
||||
* RETURNS
|
||||
* The section name, non NULL terminated
|
||||
*/
|
||||
LPCWSTR UXINI_GetNextLine(PUXINI_FILE uf, DWORD *dwLen)
|
||||
{
|
||||
LPCWSTR lpLineEnd;
|
||||
LPCWSTR lpLineStart;
|
||||
DWORD len;
|
||||
do {
|
||||
if(UXINI_eof(uf)) return NULL;
|
||||
/* Skip whitespace and empty lines */
|
||||
while(!UXINI_eof(uf) && (UXINI_isspace(*uf->lpCurLoc) || *uf->lpCurLoc == '\n')) uf->lpCurLoc++;
|
||||
lpLineStart = uf->lpCurLoc;
|
||||
lpLineEnd = uf->lpCurLoc;
|
||||
while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n' && *uf->lpCurLoc != ';') lpLineEnd = uf->lpCurLoc++;
|
||||
/* If comment was found, skip the rest of the line */
|
||||
if(*uf->lpCurLoc == ';')
|
||||
while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n') uf->lpCurLoc++;
|
||||
len = (lpLineEnd - lpLineStart);
|
||||
if(len == 0)
|
||||
return NULL;
|
||||
} while(*lpLineStart == ';');
|
||||
/* Remove whitespace from end of line */
|
||||
while(UXINI_isspace(lpLineStart[len-1])) len--;
|
||||
*dwLen = len;
|
||||
|
||||
return lpLineStart;
|
||||
}
|
||||
|
||||
void UXINI_UnGetToLine(PUXINI_FILE uf, LPCWSTR lpLine)
|
||||
{
|
||||
uf->lpCurLoc = lpLine;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_GetNextSection
|
||||
*
|
||||
* Locate the next section in the ini file, and return pointer to
|
||||
* section name, non NULL terminated. Use dwLen to determine length
|
||||
*
|
||||
* PARAMS
|
||||
* uf INI file to search, search starts at current location
|
||||
* dwLen Location to store pointer to section name length
|
||||
*
|
||||
* RETURNS
|
||||
* The section name, non NULL terminated
|
||||
*/
|
||||
LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen)
|
||||
{
|
||||
LPCWSTR lpLine;
|
||||
while((lpLine = UXINI_GetNextLine(uf, dwLen))) {
|
||||
/* Assuming a ']' ending to the section name */
|
||||
if(lpLine[0] == '[') {
|
||||
lpLine++;
|
||||
*dwLen -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return lpLine;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_FindSection
|
||||
*
|
||||
* Locate a section with the specified name, search starts
|
||||
* at current location in ini file
|
||||
* to start search from start, call UXINI_ResetINI
|
||||
*
|
||||
* PARAMS
|
||||
* uf INI file to search, search starts at current location
|
||||
* lpName Name of the section to locate
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE if section was found, FALSE otherwise
|
||||
*/
|
||||
BOOL UXINI_FindSection(PUXINI_FILE uf, LPCWSTR lpName)
|
||||
{
|
||||
LPCWSTR lpSection;
|
||||
DWORD dwLen;
|
||||
while((lpSection = UXINI_GetNextSection(uf, &dwLen))) {
|
||||
if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpSection, dwLen, lpName, -1) == CSTR_EQUAL) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_GetNextValue
|
||||
*
|
||||
* Locate the next value in the current section
|
||||
*
|
||||
* PARAMS
|
||||
* uf INI file to search, search starts at current location
|
||||
* dwNameLen Location to store pointer to value name length
|
||||
* lpValue Location to store pointer to the value
|
||||
* dwValueLen Location to store pointer to value length
|
||||
*
|
||||
* RETURNS
|
||||
* The value name, non NULL terminated
|
||||
*/
|
||||
LPCWSTR UXINI_GetNextValue(PUXINI_FILE uf, DWORD *dwNameLen, LPCWSTR *lpValue, DWORD *dwValueLen)
|
||||
{
|
||||
LPCWSTR lpLine;
|
||||
LPCWSTR lpLineEnd;
|
||||
LPCWSTR name = NULL;
|
||||
LPCWSTR value = NULL;
|
||||
DWORD vallen = 0;
|
||||
DWORD namelen = 0;
|
||||
DWORD dwLen;
|
||||
lpLine = UXINI_GetNextLine(uf, &dwLen);
|
||||
if(!lpLine)
|
||||
return NULL;
|
||||
if(lpLine[0] == '[') {
|
||||
UXINI_UnGetToLine(uf, lpLine);
|
||||
return NULL;
|
||||
}
|
||||
lpLineEnd = lpLine + dwLen;
|
||||
|
||||
name = lpLine;
|
||||
while(namelen < dwLen && *lpLine != '=') {
|
||||
lpLine++;
|
||||
namelen++;
|
||||
}
|
||||
if(*lpLine != '=') return NULL;
|
||||
lpLine++;
|
||||
|
||||
/* Remove whitespace from end of name */
|
||||
while(UXINI_isspace(name[namelen-1])) namelen--;
|
||||
/* Remove whitespace from beginning of value */
|
||||
while(UXINI_isspace(*lpLine) && lpLine < lpLineEnd) lpLine++;
|
||||
value = lpLine;
|
||||
vallen = dwLen-(value-name);
|
||||
|
||||
*dwNameLen = namelen;
|
||||
*dwValueLen = vallen;
|
||||
*lpValue = value;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* UXINI_FindValue
|
||||
*
|
||||
* Locate a value by name
|
||||
*
|
||||
* PARAMS
|
||||
* uf INI file to search, search starts at current location
|
||||
* lpName Value name to locate
|
||||
* lpValue Location to store pointer to the value
|
||||
* dwValueLen Location to store pointer to value length
|
||||
*
|
||||
* RETURNS
|
||||
* The value name, non NULL terminated
|
||||
*/
|
||||
BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen)
|
||||
{
|
||||
LPCWSTR name;
|
||||
DWORD namelen;
|
||||
|
||||
while((name = UXINI_GetNextValue(uf, &namelen, lpValue, dwValueLen))) {
|
||||
if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, name, namelen, lpName, -1) == CSTR_EQUAL) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
|
@ -85,6 +85,6 @@ HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
|
|||
HRESULT WINAPI ParseThemeIniFile(LPCWSTR pszIniFileName, LPWSTR pszUnknown,
|
||||
ParseThemeIniFileProc callback, LPVOID lpData);
|
||||
|
||||
extern void UXTHEME_InitSystem(void);
|
||||
extern void UXTHEME_InitSystem(HINSTANCE hInst);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue