Load properties from the theme ini. Implemented most of the GetTheme* functions.
diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 57cf359..534e9ac 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c
@@ -27,7 +27,9 @@ #include "winuser.h" #include "wingdi.h" #include "uxtheme.h" +#include "tmschema.h" +#include "msstyles.h" #include "uxthemedll.h" #include "wine/debug.h" @@ -133,10 +135,26 @@ const RECT *pBoundingRect, RECT *pContentRect) { - FIXME("%d %d: stub\n", iPartId, iStateId); + MARGINS margin; + HRESULT hr; + + TRACE("(%d,%d)\n", iPartId, iStateId); if(!hTheme) 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; } /***********************************************************************
diff --git a/dlls/uxtheme/metric.c b/dlls/uxtheme/metric.c index 30e1889..661e162 100644 --- a/dlls/uxtheme/metric.c +++ b/dlls/uxtheme/metric.c
@@ -28,6 +28,7 @@ #include "wingdi.h" #include "uxtheme.h" +#include "msstyles.h" #include "uxthemedll.h" #include "wine/debug.h"
diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c index 2438f34..4b150de 100644 --- a/dlls/uxtheme/msstyles.c +++ b/dlls/uxtheme/msstyles.c
@@ -30,6 +30,7 @@ #include "winnls.h" #include "wingdi.h" #include "uxtheme.h" +#include "tmschema.h" #include "uxthemedll.h" #include "msstyles.h" @@ -215,7 +216,6 @@ MSSTYLES_CloseThemeFile(tfActiveTheme); tfActiveTheme = tf; tfActiveTheme->dwRefCount++; - FIXME("Process theme resources\n"); return S_OK; } @@ -226,7 +226,7 @@ */ PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf) { - return UXINI_LoadINI(tf, szThemesIniResource); + return UXINI_LoadINI(tf->hTheme, szThemesIniResource); } /*********************************************************************** @@ -275,7 +275,7 @@ for(i=0; i < dwResourceIndex; i++) { tmp += lstrlenW(tmp)+1; } - return UXINI_LoadINI(tf, tmp); + return UXINI_LoadINI(tf->hTheme, tmp); } @@ -378,8 +378,14 @@ { PTHEME_CLASS cur = tf->classes; while(cur) { - if(!lstrcmpiW(pszAppName, cur->szAppName) && !lstrcmpiW(pszClassName, cur->szClassName)) - return cur; + if(!pszAppName) { + if(!*cur->szAppName && !lstrcmpiW(pszClassName, cur->szClassName)) + return cur; + } + else { + if(!lstrcmpiW(pszAppName, cur->szAppName) && !lstrcmpiW(pszClassName, cur->szClassName)) + return cur; + } cur = cur->next; } return NULL; @@ -404,6 +410,7 @@ if(cur) return cur; cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_CLASS)); + cur->hTheme = tf->hTheme; lstrcpyW(cur->szAppName, pszAppName); lstrcpyW(cur->szClassName, pszClassName); cur->next = tf->classes; @@ -422,19 +429,22 @@ * tc Class to search * iPartId Part ID to find * iStateId State ID to find + * tcNext Receives the next class in the override chain * * RETURNS * 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; while(cur) { - if(cur->iPartId == iPartId && cur->iStateId == iStateId) + if(cur->iPartId == iPartId && cur->iStateId == iStateId) { + if(tcNext) *tcNext = tc->overrides; return cur; + } 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; } @@ -453,18 +463,92 @@ */ 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; cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PARTSTATE)); cur->iPartId = iPartId; cur->iStateId = iStateId; + cur->properties = NULL; cur->next = tc->partstate; tc->partstate = 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 * * Parse the theme ini for the selected color/style @@ -475,15 +559,22 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf) { 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 globals; PTHEME_PARTSTATE ps; PUXINI_FILE ini; WCHAR szAppName[MAX_THEME_APP_NAME]; WCHAR szClassName[MAX_THEME_CLASS_NAME]; + WCHAR szPropertyName[MAX_THEME_VALUE_NAME]; int iPartId; int iStateId; + int iPropertyPrimitive; + int iPropertyId; DWORD dwLen; LPCWSTR lpName; + DWORD dwValueLen; + LPCWSTR lpValue; ini = MSSTYLES_GetActiveThemeIni(tf); @@ -493,13 +584,27 @@ continue; } if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) { + BOOL isGlobal = FALSE; + if(!lstrcmpiW(szClassName, szGlobals)) { + isGlobal = TRUE; + } cls = MSSTYLES_AddClass(tf, szAppName, szClassName); 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 */ + globals = MSSTYLES_FindClass(tf, NULL, szGlobals); cls = tf->classes; while(cls) { if(*cls->szAppName) { @@ -507,6 +612,13 @@ if(!cls->overrides) { 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; } @@ -534,6 +646,7 @@ LPCWSTR start; LPCWSTR end; DWORD len; + if(!tfActiveTheme) { TRACE("there is no active theme\n"); return NULL; @@ -557,7 +670,7 @@ cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); } 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; } @@ -578,3 +691,37 @@ { 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; +}
diff --git a/dlls/uxtheme/msstyles.h b/dlls/uxtheme/msstyles.h index c57a26f..b848ba2 100644 --- a/dlls/uxtheme/msstyles.h +++ b/dlls/uxtheme/msstyles.h
@@ -25,16 +25,29 @@ #define MAX_THEME_APP_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 { int iPartId; int iStateId; - /* TODO: define part/state properties */ + PTHEME_PROPERTY properties; struct _THEME_PARTSTATE *next; } THEME_PARTSTATE, *PTHEME_PARTSTATE; typedef struct _THEME_CLASS { + HMODULE hTheme; WCHAR szAppName[MAX_THEME_APP_NAME]; WCHAR szClassName[MAX_THEME_CLASS_NAME]; PTHEME_PARTSTATE partstate; @@ -55,25 +68,22 @@ PTHEME_CLASS classes; } THEME_FILE, *PTHEME_FILE; -typedef struct _UXINI_FILE { - LPCWSTR lpIni; - LPCWSTR lpCurLoc; - LPCWSTR lpEnd; -} UXINI_FILE, *PUXINI_FILE; +typedef void* 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 pszAppName, LPCWSTR pszClassList); HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc); -BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, DWORD *dwPrimitive, DWORD *dwId); -BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, DWORD dwEnum, DWORD *dwValue); +BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwId); +BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue); BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId); 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_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_ResetINI(PUXINI_FILE uf); LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen);
diff --git a/dlls/uxtheme/property.c b/dlls/uxtheme/property.c index 87b41cc..da9a109 100644 --- a/dlls/uxtheme/property.c +++ b/dlls/uxtheme/property.c
@@ -27,23 +27,57 @@ #include "winuser.h" #include "wingdi.h" #include "uxtheme.h" +#include "tmschema.h" +#include "msstyles.h" #include "uxthemedll.h" #include "wine/debug.h" 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.@) */ HRESULT WINAPI GetThemeBool(HTHEME hTheme, int iPartId, int iStateId, 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) 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 GetThemeColor(HTHEME hTheme, int iPartId, int iStateId, 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) 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 GetThemeEnumValue(HTHEME hTheme, int iPartId, int iStateId, 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) 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 @@ int iPropId, LPWSTR pszThemeFilename, int cchMaxBuffChars) { - FIXME("%d %d %d: stub\n", iPartId, iStateId, iPropId); + PTHEME_PROPERTY tp; + + TRACE("(%d, %d, %d)\n", iPartId, iStateId, iPropId); if(!hTheme) 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 GetThemeInt(HTHEME hTheme, int iPartId, int iStateId, 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) 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 GetThemePosition(HTHEME hTheme, int iPartId, int iStateId, 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) 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 GetThemeRect(HTHEME hTheme, int iPartId, int iStateId, 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) 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 GetThemeString(HTHEME hTheme, int iPartId, int iStateId, 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) 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 @@ int iStateId, int iPropId, RECT *prc, 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) 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 GetThemePropertyOrigin(HTHEME hTheme, int iPartId, int iStateId, 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) 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; }
diff --git a/dlls/uxtheme/stylemap.c b/dlls/uxtheme/stylemap.c index 1167add..1f49e61 100644 --- a/dlls/uxtheme/stylemap.c +++ b/dlls/uxtheme/stylemap.c
@@ -27,7 +27,7 @@ #include "winuser.h" #include "tmschema.h" -#include "msstyles.h" +#define TMT_ENUM 200 #include "wine/debug.h" @@ -1111,7 +1111,7 @@ * RETURNS * 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; do { @@ -1137,7 +1137,7 @@ * RETURNS * 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; /* Locate the enum block */
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c index 43dba39..6bd3b78 100644 --- a/dlls/uxtheme/system.c +++ b/dlls/uxtheme/system.c
@@ -398,7 +398,7 @@ BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int 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 FALSE; } @@ -428,7 +428,7 @@ PTHEME_FILE pt; HRESULT hr; int i; - DWORD dwDocId; + int iDocId; TRACE("(%s,%s,%p,%d)\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName), pszValueBuff, cchMaxValChars); @@ -437,9 +437,9 @@ /* Try to load from string resources */ 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) { - if(wDocToRes[i] == dwDocId) { + if(wDocToRes[i] == iDocId) { if(LoadStringW(pt->hTheme, wDocToRes[i+1], pszValueBuff, cchMaxValChars)) { hr = S_OK; break;
diff --git a/dlls/uxtheme/uxini.c b/dlls/uxtheme/uxini.c index 265b23f..8adb085 100644 --- a/dlls/uxtheme/uxini.c +++ b/dlls/uxtheme/uxini.c
@@ -26,8 +26,6 @@ #include "winbase.h" #include "winnls.h" -#include "msstyles.h" - #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); @@ -40,6 +38,12 @@ '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 @@ * RETURNS * 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; LPCWSTR lpThemesIni = NULL; PUXINI_FILE uf; @@ -63,14 +67,14 @@ TRACE("Loading resource INI %s\n", debugstr_w(lpName)); - if((hrsc = FindResourceW(tf->hTheme, lpName, szTextFileResource))) { - if(!(lpThemesIni = (LPCWSTR)LoadResource(tf->hTheme, hrsc))) { + if((hrsc = FindResourceW(hTheme, lpName, szTextFileResource))) { + if(!(lpThemesIni = (LPCWSTR)LoadResource(hTheme, hrsc))) { TRACE("%s resource not found\n", debugstr_w(lpName)); return NULL; } } - dwIniSize = SizeofResource(tf->hTheme, hrsc) / sizeof(WCHAR); + dwIniSize = SizeofResource(hTheme, hrsc) / sizeof(WCHAR); uf = HeapAlloc(GetProcessHeap(), 0, sizeof(UXINI_FILE)); uf->lpIni = lpThemesIni; uf->lpCurLoc = lpThemesIni; @@ -156,8 +160,7 @@ 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(*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++;