[PATCH 2/2] uxtheme: Search parts of any state in IsThemePartDefined().

Zhiyi Zhang zzhang at codeweavers.com
Tue Mar 1 01:06:38 CST 2022


Tests show that IsThemePartDefined() doesn't use state ID to search parts. If a part of any state is
present, the part is considered as defined. For example, disabled state of part EditText of class
Edit is present in theme files but there is no default state for part EditText. So
IsThemePartDefined(theme, EP_EDITTEXT, 0) failed previously and it should succeed.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52581
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/uxtheme/msstyles.c     | 30 ++++++++++++++++++++++++++++++
 dlls/uxtheme/msstyles.h     |  1 +
 dlls/uxtheme/system.c       |  6 +++---
 dlls/uxtheme/tests/system.c | 13 +++----------
 4 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c
index 7d3ee72efe8..9e5a79a1c69 100644
--- a/dlls/uxtheme/msstyles.c
+++ b/dlls/uxtheme/msstyles.c
@@ -452,6 +452,36 @@ static PTHEME_CLASS MSSTYLES_AddClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWST
     return cur;
 }
 
+/***********************************************************************
+ *      MSSTYLES_FindPart
+ *
+ * Find a part
+ *
+ * PARAMS
+ *     tc                  Class to search
+ *     iPartId             Part ID to find
+ *
+ * RETURNS
+ *  The part found, or NULL
+ */
+PTHEME_PARTSTATE MSSTYLES_FindPart(PTHEME_CLASS tc, int iPartId)
+{
+    PTHEME_PARTSTATE cur = tc->partstate;
+
+    while (cur)
+    {
+        if (cur->iPartId == iPartId)
+            return cur;
+
+        cur = cur->next;
+    }
+
+    if (tc->overrides)
+        return MSSTYLES_FindPart(tc->overrides, iPartId);
+
+    return NULL;
+}
+
 /***********************************************************************
  *      MSSTYLES_FindPartState
  *
diff --git a/dlls/uxtheme/msstyles.h b/dlls/uxtheme/msstyles.h
index 12292cefae4..67f81315d7a 100644
--- a/dlls/uxtheme/msstyles.h
+++ b/dlls/uxtheme/msstyles.h
@@ -95,6 +95,7 @@ BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue) DECLSPE
 BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId) DECLSPEC_HIDDEN;
 PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf) DECLSPEC_HIDDEN;
 UINT MSSTYLES_GetThemeDPI(PTHEME_CLASS tc) DECLSPEC_HIDDEN;
+PTHEME_PARTSTATE MSSTYLES_FindPart(PTHEME_CLASS tc, int iPartId) DECLSPEC_HIDDEN;
 PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId, PTHEME_CLASS *tcNext) DECLSPEC_HIDDEN;
 PTHEME_PROPERTY MSSTYLES_FindProperty(PTHEME_CLASS tc, int iPartId, int iStateId, int iPropertyPrimitive, int iPropertyId) DECLSPEC_HIDDEN;
 PTHEME_PROPERTY MSSTYLES_FindMetric(int iPropertyPrimitive, int iPropertyId) DECLSPEC_HIDDEN;
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index 8333d6b99ce..908451f0fe8 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -809,9 +809,9 @@ BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId)
         SetLastError(E_HANDLE);
         return FALSE;
     }
-    if(MSSTYLES_FindPartState(hTheme, iPartId, iStateId, NULL))
-        return TRUE;
-    return FALSE;
+
+    SetLastError(NO_ERROR);
+    return !iStateId && MSSTYLES_FindPart(hTheme, iPartId);
 }
 
 /***********************************************************************
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c
index 59631f01fe9..dd118f5ab37 100644
--- a/dlls/uxtheme/tests/system.c
+++ b/dlls/uxtheme/tests/system.c
@@ -300,7 +300,6 @@ static void test_IsThemePartDefined(void)
         int state;
         BOOL defined;
         DWORD error;
-        BOOL todo;
     }
     tests[] =
     {
@@ -311,7 +310,7 @@ static void test_IsThemePartDefined(void)
         {L"Button", BP_PUSHBUTTON, PBS_NORMAL, FALSE, NO_ERROR},
         {L"Button", BP_PUSHBUTTON, PBS_DEFAULTED_ANIMATING, FALSE, NO_ERROR},
         {L"Button", BP_PUSHBUTTON, PBS_DEFAULTED_ANIMATING + 1, FALSE, NO_ERROR},
-        {L"Edit", EP_EDITTEXT, 0, TRUE, NO_ERROR, TRUE},
+        {L"Edit", EP_EDITTEXT, 0, TRUE, NO_ERROR},
         {L"Edit", EP_EDITTEXT, ETS_NORMAL, FALSE, NO_ERROR},
         {L"Edit", EP_EDITTEXT, ETS_FOCUSED, FALSE, NO_ERROR},
     };
@@ -337,9 +336,7 @@ static void test_IsThemePartDefined(void)
         SetLastError(0xdeadbeef);
         ret = IsThemePartDefined(theme, tests[i].part, tests[i].state);
         error = GetLastError();
-        todo_wine_if(tests[i].todo)
         ok(ret == tests[i].defined, "Expected %d.\n", tests[i].defined);
-        todo_wine_if(error == 0xdeadbeef && tests[i].error == NO_ERROR)
         ok(error == tests[i].error, "Expected %#x, got %#x.\n", tests[i].error, error);
 
         if (theme)
@@ -589,12 +586,8 @@ static void test_OpenThemeData(void)
     SetLastError(0xdeadbeef);
     bTPDefined = IsThemePartDefined(hTheme, 0 , 0);
     todo_wine
-    {
-        ok( bTPDefined == FALSE, "Expected FALSE\n");
-        ok( GetLastError() == ERROR_SUCCESS,
-            "Expected ERROR_SUCCESS, got 0x%08x\n",
-            GetLastError());
-    }
+    ok( bTPDefined == FALSE, "Expected FALSE\n" );
+    ok( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%08x\n", GetLastError() );
 
     DestroyWindow(hWnd);
 }
-- 
2.32.0



More information about the wine-devel mailing list