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++;