Может ли изменение ImageList, используемого TVS_CHECKBOXES, вызвать утечку ресурсов?
Да.Из Стили окна управления древовидным представлением :
Уничтожение управления древовидным представлением не разрушает список изображений состояния флажка.Вы должны уничтожить это явно.Получите дескриптор списка изображений состояния, отправив элементу управления древовидного представления сообщение TVM_GETIMAGELIST
.Затем уничтожьте список изображений с помощью ImageList_Destroy
.
Бонусная ссылка «Старое новое»: Остерегайтесь списка пропущенных изображений при использовании стиля TVS_CHECKBOXES
Решение Win32
Мы можем воспользоваться тем, что TVM_SETIMAGELIST
(обернутый TreeView_SetImageList()
) возвращает дескриптор к предыдущему списку изображений.
HIMAGELIST hNewImageList = ImageList_Create(/* insert arguments */);
HIMAGELIST hOldImageList = TreeView_SetImageList( hwndTreeView, hNewImageList, TVSIL_STATE );
if( hOldImageList ) // a good habit, to check if handle is not NULL
{
ImageList_Destroy( hOldImageList );
hOldImageList = NULL;
}
После того, как древовидный элемент управления был уничтожен, вам также необходимо ImageList_Destroy
новый список изображений.
Решение MFC
MFC не так уж отличается, то есть он не очищает автоматическисписок изображений, созданный в стиле TVS_CHECKBOXES
.
Создайте переменную-член CImageList m_newImageList;
в объявлении класса, в котором находится древовидный элемент управления (например, производный класс CDialog
).Это гарантирует, что время жизни новых списков изображений не заканчивается раньше, чем у окна управления деревом, и автоматически уничтожает список изображений через деструктор.
m_newImageList.Create(/* insert arguments */);
CImageList* pOldImageList = m_treeCtrl.SetImageList( &m_newImageList, TVSIL_STATE );
if( pOldImageList )
{
pOldImageList->DeleteImageList();
pOldImageList = nullptr;
}
CTreeCtrl::SetImageList()
возвращает указатель на временный объект (черезCImageList::FromHandle()
), которому не принадлежит ручка, которую он оборачивает.Вам нужно DeleteImageList()
, чтобы избежать утечки ресурсов, но никогда delete
на указателе, возвращаемом SetImageList
.MFC автоматически очищает временные объекты во время обработки в режиме ожидания (CWinApp::OnIdle()
).
Дополнительные сведения: