[PATCH v4 0/2] MR4140: uxtheme/tests: Add some tests for OpenThemeData() with various app/class names.
Themed Delphi applications use "explorer::listview" and "explorer::treeview": https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/lcl/interfaces... -- v4: uxtheme: Parse app/class name in OpenThemeData(). uxtheme/tests: Add a test for OpenThemeData("explorer::treeview"). https://gitlab.winehq.org/wine/wine/-/merge_requests/4140
From: Dmitry Timoshkov <dmitry(a)baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru> --- dlls/uxtheme/tests/system.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index c5fc19dd86a..f6b009f57ca 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -558,6 +558,11 @@ static void test_OpenThemeData(void) /* Only do the next checks if we have an active theme */ + hTheme = OpenThemeData(hWnd, L"dead:beef;explorer::treeview"); + todo_wine + ok(hTheme != NULL, "OpenThemeData() failed\n"); + CloseThemeData(hTheme); + SetLastError(0xdeadbeef); hTheme = OpenThemeData(hWnd, szButtonClassList); ok( hTheme != NULL, "got NULL, expected a HTHEME handle\n"); @@ -2591,7 +2596,7 @@ static void test_theme(void) /* > XP use opaque scrollbar arrow parts, but TMT_TRANSPARENT is TRUE */ else { - ok(hr == S_OK, "Got unexpected hr %#lx,\n", hr); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(transparent, "Expected transparent.\n"); transparent = IsThemeBackgroundPartiallyTransparent(htheme, SBP_ARROWBTN, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4140
From: Dmitry Timoshkov <dmitry(a)baikal.ru> Themed Delphi applications use "explorer::listview" and "explorer::treeview": https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/lcl/interfaces... Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru> --- dlls/uxtheme/msstyles.c | 45 +++++++++++++++++++++++++++++++++---- dlls/uxtheme/tests/system.c | 1 - 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c index cfd21a48989..c2e68508088 100644 --- a/dlls/uxtheme/msstyles.c +++ b/dlls/uxtheme/msstyles.c @@ -1022,6 +1022,23 @@ static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) } } +static void parse_app_class_name(LPCWSTR name, LPWSTR szAppName, LPWSTR szClassName) +{ + LPCWSTR p; + + szAppName[0] = szClassName[0] = 0; + + p = wcsstr(name, L"::"); + if (p) + { + lstrcpynW(szAppName, name, min(p - name + 1, MAX_THEME_APP_NAME)); + p += 2; + lstrcpynW(szClassName, p, min(wcslen(p) + 1, MAX_THEME_CLASS_NAME)); + } + else + lstrcpynW(szClassName, name, MAX_THEME_CLASS_NAME); +} + /*********************************************************************** * MSSTYLES_OpenThemeClass * @@ -1036,6 +1053,8 @@ static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList, UINT dpi) { PTHEME_CLASS cls = NULL; + WCHAR buf[MAX_THEME_APP_NAME + MAX_THEME_CLASS_NAME]; + WCHAR szAppName[MAX_THEME_APP_NAME]; WCHAR szClassName[MAX_THEME_CLASS_NAME]; LPCWSTR start; LPCWSTR end; @@ -1052,14 +1071,32 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList, U start = pszClassList; while((end = wcschr(start, ';'))) { len = end-start; - lstrcpynW(szClassName, start, min(len+1, ARRAY_SIZE(szClassName))); + lstrcpynW(buf, start, min(len+1, ARRAY_SIZE(buf))); start = end+1; - cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); + + parse_app_class_name(buf, szAppName, szClassName); + if (szAppName[0]) + { + /* If the application class is already set then fail */ + if (pszAppName) return NULL; + + cls = MSSTYLES_FindClass(tfActiveTheme, szAppName, szClassName); + } + else + cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); if(cls) break; } if(!cls && *start) { - lstrcpynW(szClassName, start, ARRAY_SIZE(szClassName)); - cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); + parse_app_class_name(start, szAppName, szClassName); + if (szAppName[0]) + { + /* If the application class is already set then fail */ + if (pszAppName) return NULL; + + cls = MSSTYLES_FindClass(tfActiveTheme, szAppName, szClassName); + } + else + cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); } if(cls) { TRACE("Opened app %s, class %s from list %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName), debugstr_w(pszClassList)); diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index f6b009f57ca..55dd97f81e1 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -559,7 +559,6 @@ static void test_OpenThemeData(void) /* Only do the next checks if we have an active theme */ hTheme = OpenThemeData(hWnd, L"dead:beef;explorer::treeview"); - todo_wine ok(hTheme != NULL, "OpenThemeData() failed\n"); CloseThemeData(hTheme); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4140
Zhiyi Zhang (@zhiyi) commented about dlls/uxtheme/tests/system.c:
/* Only do the next checks if we have an active theme */
+ hTheme = OpenThemeData(hWnd, L"dead:beef;explorer::treeview");
Sorry if I gave you the wrong suggestion. But we should use :: between dead and beef. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4140#note_50472
Zhiyi Zhang (@zhiyi) commented about dlls/uxtheme/msstyles.c:
start = pszClassList; while((end = wcschr(start, ';'))) { len = end-start; - lstrcpynW(szClassName, start, min(len+1, ARRAY_SIZE(szClassName))); + lstrcpynW(buf, start, min(len+1, ARRAY_SIZE(buf))); start = end+1; - cls = MSSTYLES_FindClass(tfActiveTheme, pszAppName, szClassName); + + parse_app_class_name(buf, szAppName, szClassName); + if (szAppName[0]) + { + /* If the application class is already set then fail */
Please keep the tests for this case. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4140#note_50473
Zhiyi Zhang (@zhiyi) commented about dlls/uxtheme/msstyles.c:
} }
+static void parse_app_class_name(LPCWSTR name, LPWSTR szAppName, LPWSTR szClassName)
It's a bit inconsistent that the function name uses underscores while its parameters use camelcase. Let's use the snake case here. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4140#note_50474
On Wed Nov 1 09:44:47 2023 +0000, Zhiyi Zhang wrote:
Sorry if I gave you the wrong suggestion. But we should use :: between dead and beef. Please add checks for the last error code as well.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/4140#note_50492
participants (3)
-
Dmitry Timoshkov -
Dmitry Timoshkov (@dmitry) -
Zhiyi Zhang (@zhiyi)