[PATCH 1/4] comctl32/treeview: Fix tooltip window leak
Nikolay Sivov
nsivov at codeweavers.com
Thu Feb 1 01:09:03 CST 2018
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/comctl32/tests/treeview.c | 114 +++++++++++++++++++++++++++++++++++++----
dlls/comctl32/treeview.c | 1 +
2 files changed, 106 insertions(+), 9 deletions(-)
diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c
index 64fb1ebcd5..45bcb740a0 100644
--- a/dlls/comctl32/tests/treeview.c
+++ b/dlls/comctl32/tests/treeview.c
@@ -1069,9 +1069,101 @@ static void test_get_set_textcolor(void)
static void test_get_set_tooltips(void)
{
- HWND hwndLastToolTip = NULL;
- HWND hPopupTreeView;
- HWND hTree;
+ HWND hTree, tooltips, hwnd;
+ DWORD style;
+ int i;
+
+ /* TVS_NOTOOLTIPS */
+ hTree = create_treeview_control(TVS_NOTOOLTIPS);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(tooltips == NULL, "Unexpected tooltip window %p.\n", tooltips);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_SETTOOLTIPS, 0, 0);
+ ok(tooltips == NULL, "Unexpected ret value %p.\n", tooltips);
+
+ /* Toggle style */
+ style = GetWindowLongA(hTree, GWL_STYLE);
+ SetWindowLongA(hTree, GWL_STYLE, style & ~TVS_NOTOOLTIPS);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(IsWindow(tooltips), "Unexpected tooltip window %p.\n", tooltips);
+
+ style = GetWindowLongA(hTree, GWL_STYLE);
+ SetWindowLongA(hTree, GWL_STYLE, style | TVS_NOTOOLTIPS);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(tooltips == NULL, "Unexpected tooltip window %p.\n", tooltips);
+
+ DestroyWindow(hTree);
+
+ /* Set some valid window, does not have to be tooltips class. */
+ hTree = create_treeview_control(TVS_NOTOOLTIPS);
+
+ hwnd = CreateWindowA(WC_STATICA, "Test", WS_VISIBLE|WS_CHILD, 5, 5, 100, 100, hMainWnd, NULL, NULL, 0);
+ ok(hwnd != NULL, "Failed to create child window.\n");
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_SETTOOLTIPS, (WPARAM)hwnd, 0);
+ ok(tooltips == NULL, "Unexpected ret value %p.\n", tooltips);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(tooltips == hwnd, "Unexpected tooltip window %p.\n", tooltips);
+
+ /* Externally set tooltips window, disable style. */
+ style = GetWindowLongA(hTree, GWL_STYLE);
+ SetWindowLongA(hTree, GWL_STYLE, style & ~TVS_NOTOOLTIPS);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(IsWindow(tooltips) && tooltips != hwnd, "Unexpected tooltip window %p.\n", tooltips);
+ ok(IsWindow(hwnd), "Expected valid window.\n");
+
+ style = GetWindowLongA(hTree, GWL_STYLE);
+ SetWindowLongA(hTree, GWL_STYLE, style | TVS_NOTOOLTIPS);
+ ok(!IsWindow(tooltips), "Unexpected tooltip window %p.\n", tooltips);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(tooltips == NULL, "Unexpected tooltip window %p.\n", tooltips);
+ ok(IsWindow(hwnd), "Expected valid window.\n");
+
+ DestroyWindow(hTree);
+ ok(IsWindow(hwnd), "Expected valid window.\n");
+
+ /* Set window, disable tooltips. */
+ hTree = create_treeview_control(0);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_SETTOOLTIPS, (WPARAM)hwnd, 0);
+ ok(IsWindow(tooltips), "Unexpected ret value %p.\n", tooltips);
+
+ style = GetWindowLongA(hTree, GWL_STYLE);
+ SetWindowLongA(hTree, GWL_STYLE, style | TVS_NOTOOLTIPS);
+ ok(!IsWindow(hwnd), "Unexpected tooltip window %p.\n", tooltips);
+ ok(IsWindow(tooltips), "Expected valid window %p.\n", tooltips);
+
+ DestroyWindow(hTree);
+ ok(IsWindow(tooltips), "Expected valid window %p.\n", tooltips);
+ DestroyWindow(tooltips);
+ DestroyWindow(hwnd);
+
+ for (i = 0; i < 2; i++)
+ {
+ DWORD style = i == 0 ? 0 : TVS_NOTOOLTIPS;
+
+ hwnd = CreateWindowA(WC_STATICA, "Test", WS_VISIBLE|WS_CHILD, 5, 5, 100, 100, hMainWnd, NULL, NULL, 0);
+ ok(hwnd != NULL, "Failed to create child window.\n");
+
+ hTree = create_treeview_control(style);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_SETTOOLTIPS, (WPARAM)hwnd, 0);
+ ok(style & TVS_NOTOOLTIPS ? tooltips == NULL : IsWindow(tooltips), "Unexpected ret value %p.\n", tooltips);
+ DestroyWindow(tooltips);
+
+ tooltips = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(tooltips == hwnd, "Unexpected tooltip window %p.\n", tooltips);
+
+ /* TreeView is destroyed, check if set window is still around. */
+ DestroyWindow(hTree);
+ ok(!IsWindow(hwnd), "Unexpected window.\n");
+ }
hTree = create_treeview_control(0);
fill_tree(hTree);
@@ -1079,20 +1171,23 @@ static void test_get_set_tooltips(void)
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */
- hPopupTreeView = CreateWindowA(WC_TREEVIEWA, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100,
+ hwnd = CreateWindowA(WC_TREEVIEWA, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100,
hMainWnd, NULL, NULL, NULL);
- DestroyWindow(hPopupTreeView);
+ DestroyWindow(hwnd);
/* Testing setting a NULL ToolTip */
- SendMessageA(hTree, TVM_SETTOOLTIPS, 0, 0);
- hwndLastToolTip = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
- ok(hwndLastToolTip == NULL, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip);
+ tooltips = (HWND)SendMessageA(hTree, TVM_SETTOOLTIPS, 0, 0);
+ ok(IsWindow(tooltips), "Unexpected ret value %p.\n", tooltips);
+
+ hwnd = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0);
+ ok(hwnd == NULL, "Unexpected tooltip window %p.\n", hwnd);
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_tooltips_seq,
"test get set tooltips", TRUE);
- /* TODO: Add a test of an actual tooltip */
DestroyWindow(hTree);
+ ok(IsWindow(tooltips), "Expected valid window.\n");
+ DestroyWindow(tooltips);
}
static void test_get_set_unicodeformat(void)
@@ -2754,6 +2849,7 @@ START_TEST(treeview)
test_expandedimage();
test_htreeitem_layout();
test_WM_GETDLGCODE();
+ test_get_set_tooltips();
unload_v6_module(ctx_cookie, hCtx);
}
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index 9a37cf331b..2295022320 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -5204,6 +5204,7 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr)
DeleteObject(infoPtr->hBoldFont);
DeleteObject(infoPtr->hUnderlineFont);
DeleteObject(infoPtr->hBoldUnderlineFont);
+ DestroyWindow(infoPtr->hwndToolTip);
Free(infoPtr);
return 0;
--
2.15.1
More information about the wine-devel
mailing list