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

This commit is contained in:
Nikolay Sivov 2011-10-01 23:29:10 +04:00 committed by Alexandre Julliard
parent 93d54b1759
commit 1bc331f31f
2 changed files with 42 additions and 14 deletions

View file

@ -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;

View file

@ -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 */