[PATCH v5 0/2] MR10340: comctl32/tooltips: suppress icon and title when title is NULL or empty.
Per MSDN, TTM_SETTITLE with a NULL or empty title string should suppress both the title row and any associated icon. Previously an empty string was treated the same as a non-empty title, causing the icon to still be displayed and the tooltip to be incorrectly sized. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58236 Signed-off-by: Larry Starr <Larry_A_Starr@yahoo.com> -- v5: comctl32/tooltips: suppress icon and title when title is NULL or empty. comctl32/tooltips/tests: add regression test for TTM_SETTITLE with NULL or empty title. https://gitlab.winehq.org/wine/wine/-/merge_requests/10340
From: Larry Starr <Larry_A_Starr@yahoo.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58236 Signed-off-by: Larry Starr <Larry_A_Starr@yahoo.com> --- dlls/comctl32/tests/tooltips.c | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c index d34f83806b5..30d3a6d89da 100644 --- a/dlls/comctl32/tests/tooltips.c +++ b/dlls/comctl32/tests/tooltips.c @@ -1179,6 +1179,78 @@ static const struct message ttn_show_parent_seq[] = { 0 } }; +/* Helper: activate a tracked tooltip and measure its window size. */ +static void get_tracked_size(HWND tt, TTTOOLINFOW *info, SIZE *sz) +{ + RECT rc; + SendMessageW(tt, TTM_TRACKACTIVATE, TRUE, (LPARAM)info); + SendMessageW(tt, TTM_TRACKPOSITION, 0, MAKELPARAM(10, 10)); + flush_events(100); + GetWindowRect(tt, &rc); + sz->cx = rc.right - rc.left; + sz->cy = rc.bottom - rc.top; + SendMessageW(tt, TTM_TRACKACTIVATE, FALSE, (LPARAM)info); + flush_events(50); +} + +static void test_TTM_SETTITLE(void) +{ + HWND parent, tt; + TTTOOLINFOW info = { 0 }; + SIZE sz_no_title, sz_null_icon, sz_empty_icon; + LRESULT res; + + parent = CreateWindowExW(0, WC_STATICW, NULL, WS_CAPTION | WS_VISIBLE, + 50, 50, 400, 400, NULL, NULL, GetModuleHandleW(NULL), 0); + ok(parent != NULL, "failed to create parent window\n"); + ShowWindow(parent, SW_SHOWNORMAL); + flush_events(100); + + tt = CreateWindowExW(WS_EX_TOPMOST, TOOLTIPS_CLASSW, NULL, + TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + parent, NULL, GetModuleHandleW(NULL), 0); + ok(tt != NULL, "failed to create tooltip window\n"); + + info.cbSize = TTTOOLINFOW_V1_SIZE; + info.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE; + info.hwnd = parent; + info.hinst = GetModuleHandleW(NULL); + info.lpszText = (WCHAR *)L"x"; + info.uId = (UINT_PTR)parent; + GetClientRect(parent, &info.rect); + + res = SendMessageW(tt, TTM_ADDTOOLW, 0, (LPARAM)&info); + ok(res, "TTM_ADDTOOLW failed\n"); + + /* Baseline: no title, no icon */ + SendMessageW(tt, TTM_SETTITLEW, TTI_NONE, (LPARAM)NULL); + get_tracked_size(tt, &info, &sz_no_title); + + /* Icon requested with NULL title — must be suppressed */ + SendMessageW(tt, TTM_SETTITLEW, TTI_WARNING, (LPARAM)NULL); + get_tracked_size(tt, &info, &sz_null_icon); + todo_wine ok(sz_null_icon.cy == sz_no_title.cy, + "NULL title + icon: height %ld, expected %ld (same as no-title)\n", + sz_null_icon.cy, sz_no_title.cy); + todo_wine ok(sz_null_icon.cx == sz_no_title.cx, + "NULL title + icon: width %ld, expected %ld (same as no-title)\n", + sz_null_icon.cx, sz_no_title.cx); + + /* Icon requested with empty string title — must also be suppressed */ + SendMessageW(tt, TTM_SETTITLEW, TTI_WARNING, (LPARAM)L""); + get_tracked_size(tt, &info, &sz_empty_icon); + todo_wine ok(sz_empty_icon.cy == sz_no_title.cy, + "empty title + icon: height %ld, expected %ld (same as no-title)\n", + sz_empty_icon.cy, sz_no_title.cy); + todo_wine ok(sz_empty_icon.cx == sz_no_title.cx, + "empty title + icon: width %ld, expected %ld (same as no-title)\n", + sz_empty_icon.cx, sz_no_title.cx); + + DestroyWindow(tt); + DestroyWindow(parent); +} + static void test_TTN_SHOW(void) { HWND hwndTip, hwnd; @@ -1255,6 +1327,7 @@ START_TEST(tooltips) test_margin(); test_TTM_ADDTOOL(FALSE); test_TTN_SHOW(); + test_TTM_SETTITLE(); if (!load_v6_module(&ctx_cookie, &hCtx)) return; @@ -1267,6 +1340,7 @@ START_TEST(tooltips) test_margin(); test_TTM_ADDTOOL(TRUE); test_TTN_SHOW(); + test_TTM_SETTITLE(); unload_v6_module(ctx_cookie, hCtx); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10340
From: Larry Starr <Larry_A_Starr@yahoo.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58236 Signed-off-by: Larry Starr <Larry_A_Starr@yahoo.com> --- dlls/comctl32/tests/tooltips.c | 8 ++++---- dlls/comctl32/tooltips.c | 14 ++++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c index 30d3a6d89da..36904aac3ad 100644 --- a/dlls/comctl32/tests/tooltips.c +++ b/dlls/comctl32/tests/tooltips.c @@ -1230,20 +1230,20 @@ static void test_TTM_SETTITLE(void) /* Icon requested with NULL title — must be suppressed */ SendMessageW(tt, TTM_SETTITLEW, TTI_WARNING, (LPARAM)NULL); get_tracked_size(tt, &info, &sz_null_icon); - todo_wine ok(sz_null_icon.cy == sz_no_title.cy, + ok(sz_null_icon.cy == sz_no_title.cy, "NULL title + icon: height %ld, expected %ld (same as no-title)\n", sz_null_icon.cy, sz_no_title.cy); - todo_wine ok(sz_null_icon.cx == sz_no_title.cx, + ok(sz_null_icon.cx == sz_no_title.cx, "NULL title + icon: width %ld, expected %ld (same as no-title)\n", sz_null_icon.cx, sz_no_title.cx); /* Icon requested with empty string title — must also be suppressed */ SendMessageW(tt, TTM_SETTITLEW, TTI_WARNING, (LPARAM)L""); get_tracked_size(tt, &info, &sz_empty_icon); - todo_wine ok(sz_empty_icon.cy == sz_no_title.cy, + ok(sz_empty_icon.cy == sz_no_title.cy, "empty title + icon: height %ld, expected %ld (same as no-title)\n", sz_empty_icon.cy, sz_no_title.cy); - todo_wine ok(sz_empty_icon.cx == sz_no_title.cx, + ok(sz_empty_icon.cx == sz_no_title.cx, "empty title + icon: width %ld, expected %ld (same as no-title)\n", sz_empty_icon.cx, sz_no_title.cx); diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index 876736b11e4..f150efeabc1 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c @@ -1638,7 +1638,8 @@ TOOLTIPS_SetTitleT (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitl Free(infoPtr->pszTitle); - if (pszTitle) + /* Suppress title and icon if title is NULL or empty (MSDN, bug 58236). */ + if (pszTitle && (isW ? ((LPCWSTR)pszTitle)[0] : ((LPCSTR)pszTitle)[0])) { if (isW) { @@ -1671,10 +1672,15 @@ TOOLTIPS_SetTitleT (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitl infoPtr->iconHeight = GetSystemMetrics(SM_CYSMICON); } - if (uTitleIcon <= TTI_ERROR_LARGE) - infoPtr->hTitleIcon = hTooltipIcons[uTitleIcon]; + if (infoPtr->pszTitle) + { + if (uTitleIcon <= TTI_ERROR_LARGE) + infoPtr->hTitleIcon = hTooltipIcons[uTitleIcon]; + else + infoPtr->hTitleIcon = CopyIcon((HICON)uTitleIcon); + } else - infoPtr->hTitleIcon = CopyIcon((HICON)uTitleIcon); + infoPtr->hTitleIcon = NULL; TRACE("icon = %p\n", infoPtr->hTitleIcon); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10340
On Sat Apr 18 22:16:04 2026 +0000, Larry Starr wrote:
changed this line in [version 5 of the diff](/wine/wine/-/merge_requests/10340/diffs?diff_id=261561&start_sha=7f2a007c9c658789d672127a58f623b1bed72ca0#af8e9605cf3b646b82337493000c7398ad51e12e_1196_1196) Ok, updates have been made please check the latest and let me know if anything else is needed. Also, thanks for your help with all this.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10340#note_137036
participants (2)
-
Larry Starr -
Larry Starr (@starrl)