From 1bc331f31f44a382a7f909d79da794d28c233fd7 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sat, 1 Oct 2011 23:29:10 +0400 Subject: [PATCH] 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 fd4a6ce2df..c99d480d33 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 02b5a7f0ba..c5f3bb35cf 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 */ -- 2.32.0.93.g670b81a890