Nikolay Sivov : comctl32/treeview: Free checkbox imagelist when control is about to be killed.

Alexandre Julliard julliard at winehq.org
Mon Oct 3 17:21:25 CDT 2011


Module: wine
Branch: master
Commit: 1bc331f31f44a382a7f909d79da794d28c233fd7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1bc331f31f44a382a7f909d79da794d28c233fd7

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sat Oct  1 23:29:10 2011 +0400

comctl32/treeview: Free checkbox imagelist when control is about to be killed.

---

 dlls/comctl32/tests/treeview.c |   22 ++++++++++++++++++----
 dlls/comctl32/treeview.c       |   34 ++++++++++++++++++++++++----------
 2 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c
index fd4a6ce..c99d480 100644
--- a/dlls/comctl32/tests/treeview.c
+++ b/dlls/comctl32/tests/treeview.c
@@ -658,7 +658,7 @@ static void test_get_set_bkcolor(void)
 
 static void test_get_set_imagelist(void)
 {
-    HIMAGELIST hImageList = NULL;
+    HIMAGELIST himl;
     HWND hTree;
 
     hTree = create_treeview_control(0);
@@ -667,9 +667,9 @@ static void test_get_set_imagelist(void)
     flush_sequences(sequences, NUM_MSG_SEQUENCES);
 
     /* Test a NULL HIMAGELIST */
-    SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList );
-    hImageList = (HIMAGELIST)SendMessage( hTree, TVM_GETIMAGELIST, TVSIL_NORMAL, 0 );
-    ok(hImageList == NULL, "NULL image list, reported as 0x%p, expected 0.\n", hImageList);
+    SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, 0 );
+    himl = (HIMAGELIST)SendMessage( hTree, TVM_GETIMAGELIST, TVSIL_NORMAL, 0 );
+    ok(himl == NULL, "NULL image list, reported as %p, expected 0.\n", himl);
 
     /* TODO: Test an actual image list */
 
@@ -1607,6 +1607,7 @@ static void test_htreeitem_layout(void)
 
 static void test_TVS_CHECKBOXES(void)
 {
+    HIMAGELIST himl;
     TVITEMA item;
     HWND hTree;
     DWORD ret;
@@ -1614,6 +1615,9 @@ static void test_TVS_CHECKBOXES(void)
     hTree = create_treeview_control(0);
     fill_tree(hTree);
 
+    himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0);
+    ok(himl == NULL, "got %p\n", himl);
+
     item.hItem = hRoot;
     item.mask = TVIF_STATE;
     item.state = INDEXTOSTATEIMAGEMASK(1);
@@ -1632,6 +1636,8 @@ static void test_TVS_CHECKBOXES(void)
 
     /* enabling check boxes set all items to 1 state image index */
     SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES);
+    himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0);
+    ok(himl != NULL, "got %p\n", himl);
 
     item.hItem = hRoot;
     item.mask = TVIF_STATE;
@@ -1652,8 +1658,16 @@ static void test_TVS_CHECKBOXES(void)
     DestroyWindow(hTree);
 
     /* the same, but initially created with TVS_CHECKBOXES */
+    hTree = create_treeview_control(0);
+    fill_tree(hTree);
+    himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0);
+    ok(himl == NULL, "got %p\n", himl);
+    DestroyWindow(hTree);
+
     hTree = create_treeview_control(TVS_CHECKBOXES);
     fill_tree(hTree);
+    himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0);
+    todo_wine ok(himl == NULL, "got %p\n", himl);
 
     item.hItem = hRoot;
     item.mask = TVIF_STATE;
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index 02b5a7f..c5f3bb3 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -66,6 +66,12 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(treeview);
 
+enum StateListType
+{
+  OriginInternal,
+  OriginUser
+};
+
 /* internal structures */
 
 typedef struct _TREEITEM    /* HTREEITEM is a _TREEINFO *. */
@@ -156,6 +162,7 @@ typedef struct tagTREEVIEW_INFO
   HIMAGELIST    himlState;
   int           stateImageHeight;
   int           stateImageWidth;
+  enum StateListType statehimlType;
   HDPA          items;
 
   DWORD lastKeyPressTimestamp;
@@ -1756,22 +1763,21 @@ TREEVIEW_NaturalHeight(const TREEVIEW_INFO *infoPtr)
 }
 
 static LRESULT
-TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
+TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, UINT type, HIMAGELIST himlNew)
 {
     HIMAGELIST himlOld = 0;
     int oldWidth  = infoPtr->normalImageWidth;
     int oldHeight = infoPtr->normalImageHeight;
 
+    TRACE("%u,%p\n", type, himlNew);
 
-    TRACE("%lx,%p\n", wParam, himlNew);
-
-    switch (wParam)
+    switch (type)
     {
     case TVSIL_NORMAL:
 	himlOld = infoPtr->himlNormal;
 	infoPtr->himlNormal = himlNew;
 
-	if (himlNew != NULL)
+	if (himlNew)
 	    ImageList_GetIconSize(himlNew, &infoPtr->normalImageWidth,
 				  &infoPtr->normalImageHeight);
 	else
@@ -1786,9 +1792,12 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
 	himlOld = infoPtr->himlState;
 	infoPtr->himlState = himlNew;
 
-	if (himlNew != NULL)
+	if (himlNew)
+	{
 	    ImageList_GetIconSize(himlNew, &infoPtr->stateImageWidth,
 				  &infoPtr->stateImageHeight);
+	    infoPtr->statehimlType = OriginUser;
+	}
 	else
 	{
 	    infoPtr->stateImageWidth = 0;
@@ -1796,6 +1805,9 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
 	}
 
 	break;
+
+    default:
+        ERR("unknown imagelist type %u\n", type);
     }
 
     if (oldWidth != infoPtr->normalImageWidth ||
@@ -4950,7 +4962,7 @@ TREEVIEW_MouseWheel(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 /* Create/Destroy *******************************************************/
 
 static void
-initialize_checkboxes(TREEVIEW_INFO *infoPtr)
+TREEVIEW_InitCheckboxes(TREEVIEW_INFO *infoPtr)
 {
     RECT rc;
     HBITMAP hbm, hbmOld;
@@ -4958,6 +4970,7 @@ initialize_checkboxes(TREEVIEW_INFO *infoPtr)
     int nIndex;
 
     infoPtr->himlState = ImageList_Create(16, 16, ILC_COLOR | ILC_MASK, 3, 0);
+    infoPtr->statehimlType = OriginInternal;
 
     hdcScreen = GetDC(0);
 
@@ -5089,7 +5102,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
             hwnd, 0, 0, 0);
 
     if (infoPtr->dwStyle & TVS_CHECKBOXES)
-        initialize_checkboxes(infoPtr);
+        TREEVIEW_InitCheckboxes(infoPtr);
 
     /* Make sure actual scrollbar state is consistent with uInternalStatus */
     ShowScrollBar(hwnd, SB_VERT, FALSE);
@@ -5121,10 +5134,11 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr)
 
     CloseThemeData (GetWindowTheme (infoPtr->hwnd));
 
+    if (infoPtr->statehimlType == OriginInternal)
+        ImageList_Destroy(infoPtr->himlState);
     /* Deassociate treeview from the window before doing anything drastic. */
     SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
 
-
     DeleteObject(infoPtr->hDefaultFont);
     DeleteObject(infoPtr->hBoldFont);
     DeleteObject(infoPtr->hUnderlineFont);
@@ -5459,7 +5473,7 @@ TREEVIEW_StyleChanged(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
         {
             if (dwNewStyle & TVS_CHECKBOXES)
             {
-                initialize_checkboxes(infoPtr);
+                TREEVIEW_InitCheckboxes(infoPtr);
                 TRACE("checkboxes enabled\n");
 
                 /* set all items to state image index 1 */




More information about the wine-cvs mailing list