Load properties from the theme ini.

Implemented most of the GetTheme* functions.
This commit is contained in:
Kevin Koltzau 2004-01-23 04:34:02 +00:00 committed by Alexandre Julliard
parent 0c7f449343
commit c31cae0f7e
8 changed files with 379 additions and 58 deletions

View File

@ -27,7 +27,9 @@
#include "winuser.h" #include "winuser.h"
#include "wingdi.h" #include "wingdi.h"
#include "uxtheme.h" #include "uxtheme.h"
#include "tmschema.h"
#include "msstyles.h"
#include "uxthemedll.h" #include "uxthemedll.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -133,10 +135,26 @@ HRESULT WINAPI GetThemeBackgroundContentRect(HTHEME hTheme, HDC hdc, int iPartId
const RECT *pBoundingRect, const RECT *pBoundingRect,
RECT *pContentRect) RECT *pContentRect)
{ {
FIXME("%d %d: stub\n", iPartId, iStateId); MARGINS margin;
HRESULT hr;
TRACE("(%d,%d)\n", iPartId, iStateId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
hr = GetThemeMargins(hTheme, hdc, iPartId, iStateId, TMT_CONTENTMARGINS, NULL, &margin);
if(FAILED(hr)) {
TRACE("Margins not found\n");
return hr;
}
pContentRect->left = pBoundingRect->left + margin.cxLeftWidth;
pContentRect->top = pBoundingRect->top + margin.cyTopHeight;
pContentRect->right = pBoundingRect->right - margin.cxRightWidth;
pContentRect->bottom = pBoundingRect->bottom - margin.cyBottomHeight;
TRACE("left:%ld,top:%ld,right:%ld,bottom:%ld\n", pContentRect->left, pContentRect->top, pContentRect->right, pContentRect->bottom);
return S_OK;
} }
/*********************************************************************** /***********************************************************************

View File

@ -28,6 +28,7 @@
#include "wingdi.h" #include "wingdi.h"
#include "uxtheme.h" #include "uxtheme.h"
#include "msstyles.h"
#include "uxthemedll.h" #include "uxthemedll.h"
#include "wine/debug.h" #include "wine/debug.h"

View File

@ -30,6 +30,7 @@
#include "winnls.h" #include "winnls.h"
#include "wingdi.h" #include "wingdi.h"
#include "uxtheme.h" #include "uxtheme.h"
#include "tmschema.h"
#include "uxthemedll.h" #include "uxthemedll.h"
#include "msstyles.h" #include "msstyles.h"
@ -215,7 +216,6 @@ HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf)
MSSTYLES_CloseThemeFile(tfActiveTheme); MSSTYLES_CloseThemeFile(tfActiveTheme);
tfActiveTheme = tf; tfActiveTheme = tf;
tfActiveTheme->dwRefCount++; tfActiveTheme->dwRefCount++;
FIXME("Process theme resources\n");
return S_OK; return S_OK;
} }
@ -226,7 +226,7 @@ HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf)
*/ */
PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf) PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf)
{ {
return UXINI_LoadINI(tf, szThemesIniResource); return UXINI_LoadINI(tf->hTheme, szThemesIniResource);
} }
/*********************************************************************** /***********************************************************************
@ -275,7 +275,7 @@ PUXINI_FILE MSSTYLES_GetActiveThemeIni(PTHEME_FILE tf)
for(i=0; i < dwResourceIndex; i++) { for(i=0; i < dwResourceIndex; i++) {
tmp += lstrlenW(tmp)+1; tmp += lstrlenW(tmp)+1;
} }
return UXINI_LoadINI(tf, tmp); return UXINI_LoadINI(tf->hTheme, tmp);
} }
@ -378,8 +378,14 @@ PTHEME_CLASS MSSTYLES_FindClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszC
{ {
PTHEME_CLASS cur = tf->classes; PTHEME_CLASS cur = tf->classes;
while(cur) { while(cur) {
if(!lstrcmpiW(pszAppName, cur->szAppName) && !lstrcmpiW(pszClassName, cur->szClassName)) if(!pszAppName) {
return cur; if(!*cur->szAppName && !lstrcmpiW(pszClassName, cur->szClassName))
return cur;
}
else {
if(!lstrcmpiW(pszAppName, cur->szAppName) && !lstrcmpiW(pszClassName, cur->szClassName))
return cur;
}
cur = cur->next; cur = cur->next;
} }
return NULL; return NULL;
@ -404,6 +410,7 @@ PTHEME_CLASS MSSTYLES_AddClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszCl
if(cur) return cur; if(cur) return cur;
cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_CLASS)); cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_CLASS));
cur->hTheme = tf->hTheme;
lstrcpyW(cur->szAppName, pszAppName); lstrcpyW(cur->szAppName, pszAppName);
lstrcpyW(cur->szClassName, pszClassName); lstrcpyW(cur->szClassName, pszClassName);
cur->next = tf->classes; cur->next = tf->classes;
@ -422,19 +429,22 @@ PTHEME_CLASS MSSTYLES_AddClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszCl
* tc Class to search * tc Class to search
* iPartId Part ID to find * iPartId Part ID to find
* iStateId State ID to find * iStateId State ID to find
* tcNext Receives the next class in the override chain
* *
* RETURNS * RETURNS
* The part/state found, or NULL * The part/state found, or NULL
*/ */
PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId) PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId, PTHEME_CLASS *tcNext)
{ {
PTHEME_PARTSTATE cur = tc->partstate; PTHEME_PARTSTATE cur = tc->partstate;
while(cur) { while(cur) {
if(cur->iPartId == iPartId && cur->iStateId == iStateId) if(cur->iPartId == iPartId && cur->iStateId == iStateId) {
if(tcNext) *tcNext = tc->overrides;
return cur; return cur;
}
cur = cur->next; cur = cur->next;
} }
if(tc->overrides) return MSSTYLES_FindPartState(tc->overrides, iPartId, iStateId); if(tc->overrides) return MSSTYLES_FindPartState(tc->overrides, iPartId, iStateId, tcNext);
return NULL; return NULL;
} }
@ -453,17 +463,91 @@ PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iState
*/ */
PTHEME_PARTSTATE MSSTYLES_AddPartState(PTHEME_CLASS tc, int iPartId, int iStateId) PTHEME_PARTSTATE MSSTYLES_AddPartState(PTHEME_CLASS tc, int iPartId, int iStateId)
{ {
PTHEME_PARTSTATE cur = MSSTYLES_FindPartState(tc, iPartId, iStateId); PTHEME_PARTSTATE cur = MSSTYLES_FindPartState(tc, iPartId, iStateId, NULL);
if(cur) return cur; if(cur) return cur;
cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PARTSTATE)); cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PARTSTATE));
cur->iPartId = iPartId; cur->iPartId = iPartId;
cur->iStateId = iStateId; cur->iStateId = iStateId;
cur->properties = NULL;
cur->next = tc->partstate; cur->next = tc->partstate;
tc->partstate = cur; tc->partstate = cur;
return cur; return cur;
} }
/***********************************************************************
* MSSTYLES_PSFindProperty
*
* Find a value within a part/state
*
* PARAMS
* ps Part/state to search
* iPropertyPrimitive Type of value expected
* iPropertyId ID of the required value
*
* RETURNS
* The property found, or NULL
*/
PTHEME_PROPERTY MSSTYLES_PSFindProperty(PTHEME_PARTSTATE ps, int iPropertyPrimitive, int iPropertyId)
{
PTHEME_PROPERTY cur = ps->properties;
while(cur) {
if(cur->iPropertyId == iPropertyId) {
if(cur->iPrimitiveType == iPropertyPrimitive) {
return cur;
}
else {
if(!iPropertyPrimitive)
return cur;
return NULL;
}
}
cur = cur->next;
}
return NULL;
}
/***********************************************************************
* MSSTYLES_AddProperty
*
* Add a property to a part/state
*
* PARAMS
* ps Part/state
* iPropertyPrimitive Primitive type of the property
* iPropertyId ID of the property
* lpValue Raw value (non-NULL terminated)
* dwValueLen Length of the value
*
* RETURNS
* The property added, or a property previously added with the same IDs
*/
PTHEME_PROPERTY MSSTYLES_AddProperty(PTHEME_PARTSTATE ps, int iPropertyPrimitive, int iPropertyId, LPCWSTR lpValue, DWORD dwValueLen, BOOL isGlobal)
{
PTHEME_PROPERTY cur = MSSTYLES_PSFindProperty(ps, iPropertyPrimitive, iPropertyId);
/* Should duplicate properties overwrite the original, or be ignored? */
if(cur) return cur;
cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PROPERTY));
cur->iPrimitiveType = iPropertyPrimitive;
cur->iPropertyId = iPropertyId;
cur->lpValue = lpValue;
cur->dwValueLen = dwValueLen;
if(ps->iStateId)
cur->origin = PO_STATE;
else if(ps->iPartId)
cur->origin = PO_PART;
else if(isGlobal)
cur->origin = PO_GLOBAL;
else
cur->origin = PO_CLASS;
cur->next = ps->properties;
ps->properties = cur;
return cur;
}
/*********************************************************************** /***********************************************************************
* MSSTYLES_ParseThemeIni * MSSTYLES_ParseThemeIni
* *
@ -475,15 +559,22 @@ PTHEME_PARTSTATE MSSTYLES_AddPartState(PTHEME_CLASS tc, int iPartId, int iStateI
void MSSTYLES_ParseThemeIni(PTHEME_FILE tf) void MSSTYLES_ParseThemeIni(PTHEME_FILE tf)
{ {
WCHAR szSysMetrics[] = {'S','y','s','M','e','t','r','i','c','s','\0'}; WCHAR szSysMetrics[] = {'S','y','s','M','e','t','r','i','c','s','\0'};
WCHAR szGlobals[] = {'g','l','o','b','a','l','s','\0'};
PTHEME_CLASS cls; PTHEME_CLASS cls;
PTHEME_CLASS globals;
PTHEME_PARTSTATE ps; PTHEME_PARTSTATE ps;
PUXINI_FILE ini; PUXINI_FILE ini;
WCHAR szAppName[MAX_THEME_APP_NAME]; WCHAR szAppName[MAX_THEME_APP_NAME];
WCHAR szClassName[MAX_THEME_CLASS_NAME]; WCHAR szClassName[MAX_THEME_CLASS_NAME];
WCHAR szPropertyName[MAX_THEME_VALUE_NAME];
int iPartId; int iPartId;
int iStateId; int iStateId;
int iPropertyPrimitive;
int iPropertyId;
DWORD dwLen; DWORD dwLen;
LPCWSTR lpName; LPCWSTR lpName;
DWORD dwValueLen;
LPCWSTR lpValue;
ini = MSSTYLES_GetActiveThemeIni(tf); ini = MSSTYLES_GetActiveThemeIni(tf);
@ -493,13 +584,27 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf)
continue; 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)) {
isGlobal = TRUE;
}
cls = MSSTYLES_AddClass(tf, szAppName, szClassName); cls = MSSTYLES_AddClass(tf, szAppName, szClassName);
ps = MSSTYLES_AddPartState(cls, iPartId, iStateId); ps = MSSTYLES_AddPartState(cls, iPartId, iStateId);
FIXME("Parse properties\n");
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)) {
MSSTYLES_AddProperty(ps, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen, isGlobal);
}
else {
TRACE("Unknown property %s\n", debugstr_w(szPropertyName));
}
}
} }
} }
/* App/Class combos override values defined by the base class, map these overrides */ /* App/Class combos override values defined by the base class, map these overrides */
globals = MSSTYLES_FindClass(tf, NULL, szGlobals);
cls = tf->classes; cls = tf->classes;
while(cls) { while(cls) {
if(*cls->szAppName) { if(*cls->szAppName) {
@ -507,6 +612,13 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf)
if(!cls->overrides) { if(!cls->overrides) {
TRACE("No overrides found for app %s class %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName)); TRACE("No overrides found for app %s class %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName));
} }
else {
cls->overrides = globals;
}
}
else {
/* Everything overrides globals..except globals */
if(cls != globals) cls->overrides = globals;
} }
cls = cls->next; cls = cls->next;
} }
@ -534,6 +646,7 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList)
LPCWSTR start; LPCWSTR start;
LPCWSTR end; LPCWSTR end;
DWORD len; DWORD len;
if(!tfActiveTheme) { if(!tfActiveTheme) {
TRACE("there is no active theme\n"); TRACE("there is no active theme\n");
return NULL; return NULL;
@ -557,7 +670,7 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList)
cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName);
} }
if(cls) { if(cls) {
TRACE("Opened class %s from list %s\n", debugstr_w(cls->szClassName), debugstr_w(pszClassList)); TRACE("Opened app %s, class %s from list %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName), debugstr_w(pszClassList));
} }
return cls; return cls;
} }
@ -578,3 +691,37 @@ HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc)
{ {
return S_OK; return S_OK;
} }
/***********************************************************************
* MSSTYLES_FindProperty
*
* Locate a property in a class. Part and state IDs will be used as a
* preference, but may be ignored in the attempt to locate the property.
* Will scan the entire chain of overrides for this class.
*/
PTHEME_PROPERTY MSSTYLES_FindProperty(PTHEME_CLASS tc, int iPartId, int iStateId, int iPropertyPrimitive, int iPropertyId)
{
PTHEME_CLASS next = tc;
PTHEME_PARTSTATE ps;
PTHEME_PROPERTY tp;
TRACE("(%p, %d, %d, %d)\n", tc, iPartId, iStateId, iPropertyId);
/* Try and find an exact match on part & state */
while(next && (ps = MSSTYLES_FindPartState(next, iPartId, iStateId, &next))) {
if((tp = MSSTYLES_PSFindProperty(ps, iPropertyPrimitive, iPropertyId))) {
return tp;
}
}
/* If that fails, and we didn't already try it, search for just part */
if(iStateId != 0)
iStateId = 0;
/* As a last ditch attempt..go for just class */
else if(iPartId != 0)
iPartId = 0;
else
return NULL;
if((tp = MSSTYLES_FindProperty(tc, iPartId, iStateId, iPropertyPrimitive, iPropertyId)))
return tp;
return NULL;
}

View File

@ -25,16 +25,29 @@
#define MAX_THEME_APP_NAME 60 #define MAX_THEME_APP_NAME 60
#define MAX_THEME_CLASS_NAME 60 #define MAX_THEME_CLASS_NAME 60
#define MAX_THEME_VALUE_NAME 60
typedef struct _THEME_PROPERTY {
int iPrimitiveType;
int iPropertyId;
PROPERTYORIGIN origin;
LPCWSTR lpValue;
DWORD dwValueLen;
struct _THEME_PROPERTY *next;
} THEME_PROPERTY, *PTHEME_PROPERTY;
typedef struct _THEME_PARTSTATE { typedef struct _THEME_PARTSTATE {
int iPartId; int iPartId;
int iStateId; int iStateId;
/* TODO: define part/state properties */ PTHEME_PROPERTY properties;
struct _THEME_PARTSTATE *next; struct _THEME_PARTSTATE *next;
} THEME_PARTSTATE, *PTHEME_PARTSTATE; } THEME_PARTSTATE, *PTHEME_PARTSTATE;
typedef struct _THEME_CLASS { typedef struct _THEME_CLASS {
HMODULE hTheme;
WCHAR szAppName[MAX_THEME_APP_NAME]; WCHAR szAppName[MAX_THEME_APP_NAME];
WCHAR szClassName[MAX_THEME_CLASS_NAME]; WCHAR szClassName[MAX_THEME_CLASS_NAME];
PTHEME_PARTSTATE partstate; PTHEME_PARTSTATE partstate;
@ -55,25 +68,22 @@ typedef struct _THEME_FILE {
PTHEME_CLASS classes; PTHEME_CLASS classes;
} THEME_FILE, *PTHEME_FILE; } THEME_FILE, *PTHEME_FILE;
typedef struct _UXINI_FILE { typedef void* PUXINI_FILE;
LPCWSTR lpIni;
LPCWSTR lpCurLoc;
LPCWSTR lpEnd;
} UXINI_FILE, *PUXINI_FILE;
HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf); HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf);
void MSSTYLES_CloseThemeFile(PTHEME_FILE tf); void MSSTYLES_CloseThemeFile(PTHEME_FILE tf);
HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf); HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf);
PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList); PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList);
HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc); HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc);
BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, DWORD *dwPrimitive, DWORD *dwId); BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwId);
BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, DWORD dwEnum, DWORD *dwValue); BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue);
BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId); BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId);
PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf); PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf);
PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId); PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId, PTHEME_CLASS *tcNext);
PTHEME_CLASS MSSTYLES_FindClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszClassName); PTHEME_CLASS MSSTYLES_FindClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR pszClassName);
PTHEME_PROPERTY MSSTYLES_FindProperty(PTHEME_CLASS tc, int iPartId, int iStateId, int iPropertyPrimitive, int iPropertyId);
PUXINI_FILE UXINI_LoadINI(PTHEME_FILE tf, LPCWSTR lpName); PUXINI_FILE UXINI_LoadINI(HMODULE hTheme, LPCWSTR lpName);
void UXINI_CloseINI(PUXINI_FILE uf); void UXINI_CloseINI(PUXINI_FILE uf);
void UXINI_ResetINI(PUXINI_FILE uf); void UXINI_ResetINI(PUXINI_FILE uf);
LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen); LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen);

View File

@ -27,23 +27,57 @@
#include "winuser.h" #include "winuser.h"
#include "wingdi.h" #include "wingdi.h"
#include "uxtheme.h" #include "uxtheme.h"
#include "tmschema.h"
#include "msstyles.h"
#include "uxthemedll.h" #include "uxthemedll.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
BOOL UXTHEME_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value)
{
LPCWSTR cur = lpStringStart;
int total = 0;
BOOL gotNeg = FALSE;
while(cur < lpStringEnd && (*cur < '0' || *cur > '9' || *cur == '-')) cur++;
if(cur >= lpStringEnd) {
return FALSE;
}
if(*cur == '-') {
cur++;
gotNeg = TRUE;
}
while(cur < lpStringEnd && (*cur >= '0' && *cur <= '9')) {
total = total * 10 + (*cur - '0');
cur++;
}
if(gotNeg) total = -total;
*value = total;
if(lpValEnd) *lpValEnd = cur;
return TRUE;
}
/*********************************************************************** /***********************************************************************
* GetThemeBool (UXTHEME.@) * GetThemeBool (UXTHEME.@)
*/ */
HRESULT WINAPI GetThemeBool(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemeBool(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, BOOL *pfVal) int iPropId, BOOL *pfVal)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_BOOL, iPropId)))
return E_PROP_ID_UNSUPPORTED;
*pfVal = FALSE;
if(*tp->lpValue == 't' || *tp->lpValue == 'T')
*pfVal = TRUE;
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -52,10 +86,28 @@ HRESULT WINAPI GetThemeBool(HTHEME hTheme, int iPartId, int iStateId,
HRESULT WINAPI GetThemeColor(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemeColor(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, COLORREF *pColor) int iPropId, COLORREF *pColor)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); LPCWSTR lpEnd;
LPCWSTR lpCur;
int red, green, blue;
PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_COLOR, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lpCur = tp->lpValue;
lpEnd = tp->lpValue + tp->dwValueLen;
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &red);
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &green);
if(!UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &blue)) {
TRACE("Could not parse color property\n");
return E_PROP_ID_UNSUPPORTED;
}
*pColor = RGB(red,green,blue);
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -64,10 +116,19 @@ HRESULT WINAPI GetThemeColor(HTHEME hTheme, int iPartId, int iStateId,
HRESULT WINAPI GetThemeEnumValue(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemeEnumValue(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, int *piVal) int iPropId, int *piVal)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); WCHAR val[60];
PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_ENUM, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lstrcpynW(val, tp->lpValue, min(tp->dwValueLen+1, sizeof(val)/sizeof(val[0])));
if(!MSSTYLES_LookupEnum(val, iPropId, piVal))
return E_PROP_ID_UNSUPPORTED;
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -77,10 +138,16 @@ HRESULT WINAPI GetThemeFilename(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, LPWSTR pszThemeFilename, int iPropId, LPWSTR pszThemeFilename,
int cchMaxBuffChars) int cchMaxBuffChars)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_FILENAME, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lstrcpynW(pszThemeFilename, tp->lpValue, min(tp->dwValueLen+1, cchMaxBuffChars));
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -101,10 +168,19 @@ HRESULT WINAPI GetThemeFont(HTHEME hTheme, HDC hdc, int iPartId,
HRESULT WINAPI GetThemeInt(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemeInt(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, int *piVal) int iPropId, int *piVal)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_INT, iPropId)))
return E_PROP_ID_UNSUPPORTED;
if(!UXTHEME_GetNextInteger(tp->lpValue, (tp->lpValue + tp->dwValueLen), NULL, piVal)) {
TRACE("Could not parse int property\n");
return E_PROP_ID_UNSUPPORTED;
}
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -125,10 +201,28 @@ HRESULT WINAPI GetThemeIntList(HTHEME hTheme, int iPartId, int iStateId,
HRESULT WINAPI GetThemePosition(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemePosition(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, POINT *pPoint) int iPropId, POINT *pPoint)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); LPCWSTR lpEnd;
LPCWSTR lpCur;
PTHEME_PROPERTY tp;
int x,y;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_POSITION, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lpCur = tp->lpValue;
lpEnd = tp->lpValue + tp->dwValueLen;
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &x);
if(!UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &y)) {
TRACE("Could not parse position property\n");
return E_PROP_ID_UNSUPPORTED;
}
pPoint->x = x;
pPoint->y = y;
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -137,10 +231,27 @@ HRESULT WINAPI GetThemePosition(HTHEME hTheme, int iPartId, int iStateId,
HRESULT WINAPI GetThemeRect(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemeRect(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, RECT *pRect) int iPropId, RECT *pRect)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); LPCWSTR lpEnd;
LPCWSTR lpCur;
PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_RECT, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lpCur = tp->lpValue;
lpEnd = tp->lpValue + tp->dwValueLen;
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->left);
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->top);
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->right);
if(!UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, (int*)&pRect->bottom)) {
TRACE("Could not parse rect property\n");
return E_PROP_ID_UNSUPPORTED;
}
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -149,10 +260,16 @@ HRESULT WINAPI GetThemeRect(HTHEME hTheme, int iPartId, int iStateId,
HRESULT WINAPI GetThemeString(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemeString(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, LPWSTR pszBuff, int cchMaxBuffChars) int iPropId, LPWSTR pszBuff, int cchMaxBuffChars)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_FILENAME, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lstrcpynW(pszBuff, tp->lpValue, min(tp->dwValueLen+1, cchMaxBuffChars));
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -162,10 +279,27 @@ HRESULT WINAPI GetThemeMargins(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, int iPropId, RECT *prc, int iStateId, int iPropId, RECT *prc,
MARGINS *pMargins) MARGINS *pMargins)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); LPCWSTR lpEnd;
LPCWSTR lpCur;
PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_MARGINS, iPropId)))
return E_PROP_ID_UNSUPPORTED;
lpCur = tp->lpValue;
lpEnd = tp->lpValue + tp->dwValueLen;
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &pMargins->cxLeftWidth);
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &pMargins->cxRightWidth);
UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &pMargins->cyTopHeight);
if(!UXTHEME_GetNextInteger(lpCur, lpEnd, &lpCur, &pMargins->cyBottomHeight)) {
TRACE("Could not parse margins property\n");
return E_PROP_ID_UNSUPPORTED;
}
return S_OK;
} }
/*********************************************************************** /***********************************************************************
@ -186,8 +320,16 @@ HRESULT WINAPI GetThemeMetric(HTHEME hTheme, HDC hdc, int iPartId,
HRESULT WINAPI GetThemePropertyOrigin(HTHEME hTheme, int iPartId, int iStateId, HRESULT WINAPI GetThemePropertyOrigin(HTHEME hTheme, int iPartId, int iStateId,
int iPropId, PROPERTYORIGIN *pOrigin) int iPropId, PROPERTYORIGIN *pOrigin)
{ {
FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); PTHEME_PROPERTY tp;
TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId);
if(!hTheme) if(!hTheme)
return E_HANDLE; return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
if(!(tp = MSSTYLES_FindProperty(hTheme, iPartId, iStateId, 0, iPropId))) {
*pOrigin = PO_NOTFOUND;
return S_OK;
}
*pOrigin = tp->origin;
return S_OK;
} }

View File

@ -27,7 +27,7 @@
#include "winuser.h" #include "winuser.h"
#include "tmschema.h" #include "tmschema.h"
#include "msstyles.h" #define TMT_ENUM 200
#include "wine/debug.h" #include "wine/debug.h"
@ -1111,7 +1111,7 @@ BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszStat
* RETURNS * RETURNS
* FALSE if value is not found, TRUE otherwise * FALSE if value is not found, TRUE otherwise
*/ */
BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, DWORD *dwPrimitive, DWORD *dwId) BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwId)
{ {
DWORD item = 0; DWORD item = 0;
do { do {
@ -1137,7 +1137,7 @@ BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, DWORD *dwPrimitive, DWORD
* RETURNS * RETURNS
* FALSE if value is not found, TRUE otherwise * FALSE if value is not found, TRUE otherwise
*/ */
BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, DWORD dwEnum, DWORD *dwValue) BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue)
{ {
DWORD item = 0; DWORD item = 0;
/* Locate the enum block */ /* Locate the enum block */

View File

@ -398,7 +398,7 @@ HRESULT WINAPI HitTestThemeBackground(HTHEME hTheme, HDC hdc, int iPartId,
BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId) BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId)
{ {
TRACE("(%p,%d,%d)\n", hTheme, iPartId, iStateId); TRACE("(%p,%d,%d)\n", hTheme, iPartId, iStateId);
if(MSSTYLES_FindPartState(hTheme, iPartId, iStateId)) if(MSSTYLES_FindPartState(hTheme, iPartId, iStateId, NULL))
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -428,7 +428,7 @@ HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName,
PTHEME_FILE pt; PTHEME_FILE pt;
HRESULT hr; HRESULT hr;
int i; int i;
DWORD dwDocId; int iDocId;
TRACE("(%s,%s,%p,%d)\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName), TRACE("(%s,%s,%p,%d)\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName),
pszValueBuff, cchMaxValChars); pszValueBuff, cchMaxValChars);
@ -437,9 +437,9 @@ HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName,
/* Try to load from string resources */ /* Try to load from string resources */
hr = E_PROP_ID_UNSUPPORTED; hr = E_PROP_ID_UNSUPPORTED;
if(MSSTYLES_LookupProperty(pszPropertyName, NULL, &dwDocId)) { if(MSSTYLES_LookupProperty(pszPropertyName, NULL, &iDocId)) {
for(i=0; i<sizeof(wDocToRes)/sizeof(wDocToRes[0]); i+=2) { for(i=0; i<sizeof(wDocToRes)/sizeof(wDocToRes[0]); i+=2) {
if(wDocToRes[i] == dwDocId) { if(wDocToRes[i] == iDocId) {
if(LoadStringW(pt->hTheme, wDocToRes[i+1], pszValueBuff, cchMaxValChars)) { if(LoadStringW(pt->hTheme, wDocToRes[i+1], pszValueBuff, cchMaxValChars)) {
hr = S_OK; hr = S_OK;
break; break;

View File

@ -26,8 +26,6 @@
#include "winbase.h" #include "winbase.h"
#include "winnls.h" #include "winnls.h"
#include "msstyles.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
@ -40,6 +38,12 @@ static const WCHAR szTextFileResource[] = {
'T','E','X','T','F','I','L','E','\0' 'T','E','X','T','F','I','L','E','\0'
}; };
typedef struct _UXINI_FILE {
LPCWSTR lpIni;
LPCWSTR lpCurLoc;
LPCWSTR lpEnd;
} UXINI_FILE, *PUXINI_FILE;
/***********************************************************************/ /***********************************************************************/
/********************************************************************** /**********************************************************************
@ -55,7 +59,7 @@ static const WCHAR szTextFileResource[] = {
* RETURNS * RETURNS
* INI file, or NULL if not found * INI file, or NULL if not found
*/ */
PUXINI_FILE UXINI_LoadINI(PTHEME_FILE tf, LPCWSTR lpName) { PUXINI_FILE UXINI_LoadINI(HMODULE hTheme, LPCWSTR lpName) {
HRSRC hrsc; HRSRC hrsc;
LPCWSTR lpThemesIni = NULL; LPCWSTR lpThemesIni = NULL;
PUXINI_FILE uf; PUXINI_FILE uf;
@ -63,14 +67,14 @@ PUXINI_FILE UXINI_LoadINI(PTHEME_FILE tf, LPCWSTR lpName) {
TRACE("Loading resource INI %s\n", debugstr_w(lpName)); TRACE("Loading resource INI %s\n", debugstr_w(lpName));
if((hrsc = FindResourceW(tf->hTheme, lpName, szTextFileResource))) { if((hrsc = FindResourceW(hTheme, lpName, szTextFileResource))) {
if(!(lpThemesIni = (LPCWSTR)LoadResource(tf->hTheme, hrsc))) { if(!(lpThemesIni = (LPCWSTR)LoadResource(hTheme, hrsc))) {
TRACE("%s resource not found\n", debugstr_w(lpName)); TRACE("%s resource not found\n", debugstr_w(lpName));
return NULL; return NULL;
} }
} }
dwIniSize = SizeofResource(tf->hTheme, hrsc) / sizeof(WCHAR); dwIniSize = SizeofResource(hTheme, hrsc) / sizeof(WCHAR);
uf = HeapAlloc(GetProcessHeap(), 0, sizeof(UXINI_FILE)); uf = HeapAlloc(GetProcessHeap(), 0, sizeof(UXINI_FILE));
uf->lpIni = lpThemesIni; uf->lpIni = lpThemesIni;
uf->lpCurLoc = lpThemesIni; uf->lpCurLoc = lpThemesIni;
@ -156,8 +160,7 @@ LPCWSTR UXINI_GetNextLine(PUXINI_FILE uf, DWORD *dwLen)
while(!UXINI_eof(uf) && (UXINI_isspace(*uf->lpCurLoc) || *uf->lpCurLoc == '\n')) uf->lpCurLoc++; while(!UXINI_eof(uf) && (UXINI_isspace(*uf->lpCurLoc) || *uf->lpCurLoc == '\n')) uf->lpCurLoc++;
lpLineStart = uf->lpCurLoc; lpLineStart = uf->lpCurLoc;
lpLineEnd = uf->lpCurLoc; lpLineEnd = uf->lpCurLoc;
while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n' && *uf->lpCurLoc != ';') lpLineEnd = uf->lpCurLoc++; while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n' && *uf->lpCurLoc != ';') lpLineEnd = ++uf->lpCurLoc;
if(*uf->lpCurLoc == ';') lpLineEnd = uf->lpCurLoc++;
/* If comment was found, skip the rest of the line */ /* If comment was found, skip the rest of the line */
if(*uf->lpCurLoc == ';') if(*uf->lpCurLoc == ';')
while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n') uf->lpCurLoc++; while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n') uf->lpCurLoc++;