{"id":97475,"date":"2017-11-28T07:00:00","date_gmt":"2017-11-28T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97475"},"modified":"2019-03-13T01:20:38","modified_gmt":"2019-03-13T08:20:38","slug":"20171128-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20171128-00\/?p=97475","title":{"rendered":"Beware of the leaked image list when using the TVS_CHECKBOXES style"},"content":{"rendered":"<p>The <code>TVS_<\/code><code>CHECK&shy;BOXES<\/code> tree view style is <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20171127-00\/?p=97465\">quirky<\/a>, which is a nice way of saying that it&#8217;s crazy. <\/p>\n<p>As we noted last time, the support for check boxes was migrated in from external code, and it followed the pattern for external code. In particular, the state image list for the check boxes needs to be manually destroyed, because when you created the check boxes manually, you also needed to clean them up. <\/p>\n<p>Yes, this goes against the general principle that things which were created by the control will be destroyed by the control. Like I said, the <code>TVS_<\/code><code>CHECK&shy;BOXES<\/code> tree view style is quirky. And if you fail to accommodate this quirk, <a HREF=\"http:\/\/memprofiler.com\/articles\/treeviewresourceleak.aspx\">you end up with a resource leak<\/a>. <\/p>\n<p>MSDN suggests that you use the <code>TVM_<\/code><code>GET&shy;IMAGE&shy;LIST<\/code> message to retrieve the state image list, and then use <code>Image&shy;List_<\/code><code>Destroy<\/code> to destroy it. I prefer to exchange the image list out by setting the state image list to null, then destroying the returned image list (which is the previous image list). This avoids dangling references to a destroyed image list, and it also means that if somehow you try to clean up the image lists twice, the second one will simply not do anything since it won&#8217;t see anything to clean up. <\/p>\n<p><pre>\nImageList_Destroy(TreeView_SetImageList(hwndTV, nullptr, TVSIL_STATE));\n<\/pre>\n<p>We take advantage of the fact that the <code>HIMAGELIST<\/code> parameter to the <code>Image&shy;List_<\/code><code>Destroy<\/code> function is marked <code>_In_opt_<\/code>, which means that it is permissible to pass <code>nullptr<\/code>. <\/p>\n<p>Okay, with these two common errors out of the way, I&#8217;ll continue next time by beginning our exploration of tree view check boxes from the ground up. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;ll make one for you, but it&#8217;s still on you to destroy it.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-97475","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It&#8217;ll make one for you, but it&#8217;s still on you to destroy it.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97475","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=97475"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97475\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=97475"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97475"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97475"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}