@@ -579,11 +579,21 @@ public bool CheckBoxes
579579 {
580580 if ( CheckBoxes )
581581 { // we want custom checkboxes
582- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , _imageListState . Handle ) ;
582+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , _imageListState . CreateUniqueHandle ( ) ) ;
583+ if ( previousHandle != IntPtr . Zero )
584+ {
585+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
586+ Debug . Assert ( result . IsTrue ( ) ) ;
587+ }
583588 }
584589 else
585590 {
586- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , IntPtr . Zero ) ;
591+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , IntPtr . Zero ) ;
592+ if ( previousHandle != IntPtr . Zero )
593+ {
594+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
595+ Debug . Assert ( result . IsTrue ( ) ) ;
596+ }
587597 }
588598 }
589599
@@ -664,7 +674,9 @@ protected override CreateParams CreateParams
664674 cp . Style |= ( currentStyle & ( int ) ( User32 . WS . HSCROLL | User32 . WS . VSCROLL ) ) ;
665675 }
666676
667- cp . Style |= ( int ) LVS . SHAREIMAGELISTS ;
677+ // disabled until ownership management of list handles is fixed
678+ // https://github.com/dotnet/winforms/issues/3531
679+ //cp.Style |= (int)LVS.SHAREIMAGELISTS;
668680
669681 switch ( alignStyle )
670682 {
@@ -966,8 +978,13 @@ public ImageList GroupImageList
966978 return ;
967979 }
968980
969- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER ,
970- value is null ? IntPtr . Zero : value . Handle ) ;
981+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER ,
982+ value is null ? IntPtr . Zero : value . CreateUniqueHandle ( ) ) ;
983+ if ( previousHandle != IntPtr . Zero )
984+ {
985+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
986+ Debug . Assert ( result . IsTrue ( ) ) ;
987+ }
971988 }
972989 }
973990
@@ -1235,7 +1252,13 @@ public ImageList LargeImageList
12351252 return ;
12361253 }
12371254
1238- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL , value is null ? IntPtr . Zero : value . Handle ) ;
1255+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL , value is null ? IntPtr . Zero : value . CreateUniqueHandle ( ) ) ;
1256+ if ( previousHandle != IntPtr . Zero )
1257+ {
1258+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
1259+ Debug . Assert ( result . IsTrue ( ) ) ;
1260+ }
1261+
12391262 if ( AutoArrange && ! listViewState1 [ LISTVIEWSTATE1_disposingImageLists ] )
12401263 {
12411264 UpdateListViewItemsLocations ( ) ;
@@ -1474,7 +1497,12 @@ public ImageList SmallImageList
14741497 return ;
14751498 }
14761499
1477- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL , value is null ? IntPtr . Zero : value . Handle ) ;
1500+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL , value is null ? IntPtr . Zero : value . CreateUniqueHandle ( ) ) ;
1501+ if ( previousHandle != IntPtr . Zero )
1502+ {
1503+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
1504+ Debug . Assert ( result . IsTrue ( ) ) ;
1505+ }
14781506
14791507 if ( View == View . SmallIcon )
14801508 {
@@ -1582,7 +1610,12 @@ public ImageList StateImageList
15821610
15831611 if ( IsHandleCreated )
15841612 {
1585- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , value is null ? IntPtr . Zero : value . Handle ) ;
1613+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , value is null ? IntPtr . Zero : value . CreateUniqueHandle ( ) ) ;
1614+ if ( previousHandle != IntPtr . Zero )
1615+ {
1616+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
1617+ Debug . Assert ( result . IsTrue ( ) ) ;
1618+ }
15861619 }
15871620 }
15881621 else
@@ -1597,7 +1630,12 @@ public ImageList StateImageList
15971630 // (Yes, it does exactly that even though our wrapper sets LVS_SHAREIMAGELISTS on the native listView.)
15981631 // So we make the native listView forget about its StateImageList just before we recreate the handle.
15991632 // Likely related to https://devblogs.microsoft.com/oldnewthing/20171128-00/?p=97475
1600- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , IntPtr . Zero ) ;
1633+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , IntPtr . Zero ) ;
1634+ if ( previousHandle != IntPtr . Zero )
1635+ {
1636+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
1637+ Debug . Assert ( result . IsTrue ( ) ) ;
1638+ }
16011639 }
16021640
16031641 _imageListState = value ;
@@ -1615,8 +1653,13 @@ public ImageList StateImageList
16151653 }
16161654 else
16171655 {
1618- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE ,
1619- ( _imageListState is null || _imageListState . Images . Count == 0 ) ? IntPtr . Zero : _imageListState . Handle ) ;
1656+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE ,
1657+ ( _imageListState is null || _imageListState . Images . Count == 0 ) ? IntPtr . Zero : _imageListState . CreateUniqueHandle ( ) ) ;
1658+ if ( previousHandle != IntPtr . Zero )
1659+ {
1660+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
1661+ Debug . Assert ( result . IsTrue ( ) ) ;
1662+ }
16201663 }
16211664
16221665 // Comctl should handle auto-arrange for us, but doesn't
@@ -3672,8 +3715,13 @@ private void GroupImageListRecreateHandle(object sender, EventArgs e)
36723715 return ;
36733716 }
36743717
3675- IntPtr handle = ( GroupImageList is null ) ? IntPtr . Zero : GroupImageList . Handle ;
3676- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER , handle ) ;
3718+ IntPtr handle = ( GroupImageList is null ) ? IntPtr . Zero : GroupImageList . CreateUniqueHandle ( ) ;
3719+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER , handle ) ;
3720+ if ( previousHandle != IntPtr . Zero )
3721+ {
3722+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
3723+ Debug . Assert ( result . IsTrue ( ) ) ;
3724+ }
36773725 }
36783726
36793727 public ListViewHitTestInfo HitTest ( Point point )
@@ -4243,8 +4291,13 @@ private void LargeImageListRecreateHandle(object sender, EventArgs e)
42434291 return ;
42444292 }
42454293
4246- IntPtr handle = ( LargeImageList is null ) ? IntPtr . Zero : LargeImageList . Handle ;
4247- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL , handle ) ;
4294+ IntPtr handle = ( LargeImageList is null ) ? IntPtr . Zero : LargeImageList . CreateUniqueHandle ( ) ;
4295+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL , handle ) ;
4296+ if ( previousHandle != IntPtr . Zero )
4297+ {
4298+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4299+ Debug . Assert ( result . IsTrue ( ) ) ;
4300+ }
42484301
42494302 ForceCheckBoxUpdate ( ) ;
42504303 }
@@ -4587,6 +4640,34 @@ protected override void OnHandleCreated(EventArgs e)
45874640
45884641 protected override void OnHandleDestroyed ( EventArgs e )
45894642 {
4643+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL ) ;
4644+ if ( previousHandle != IntPtr . Zero )
4645+ {
4646+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4647+ Debug . Assert ( result . IsTrue ( ) ) ;
4648+ }
4649+
4650+ previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL ) ;
4651+ if ( previousHandle != IntPtr . Zero )
4652+ {
4653+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4654+ Debug . Assert ( result . IsTrue ( ) ) ;
4655+ }
4656+
4657+ previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE ) ;
4658+ if ( previousHandle != IntPtr . Zero )
4659+ {
4660+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4661+ Debug . Assert ( result . IsTrue ( ) ) ;
4662+ }
4663+
4664+ previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER ) ;
4665+ if ( previousHandle != IntPtr . Zero )
4666+ {
4667+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4668+ Debug . Assert ( result . IsTrue ( ) ) ;
4669+ }
4670+
45904671 // don't save the list view items state when in virtual mode : it is the responsability of the
45914672 // user to cache the list view items in virtual mode
45924673 if ( ! Disposing && ! VirtualMode )
@@ -4822,22 +4903,42 @@ protected void RealizeProperties()
48224903
48234904 if ( _imageListLarge != null )
48244905 {
4825- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL , _imageListLarge . Handle ) ;
4906+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . NORMAL , _imageListLarge . CreateUniqueHandle ( ) ) ;
4907+ if ( previousHandle != IntPtr . Zero )
4908+ {
4909+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4910+ Debug . Assert ( result . IsTrue ( ) ) ;
4911+ }
48264912 }
48274913
48284914 if ( _imageListSmall != null )
48294915 {
4830- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL , _imageListSmall . Handle ) ;
4916+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL , _imageListSmall . CreateUniqueHandle ( ) ) ;
4917+ if ( previousHandle != IntPtr . Zero )
4918+ {
4919+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4920+ Debug . Assert ( result . IsTrue ( ) ) ;
4921+ }
48314922 }
48324923
48334924 if ( _imageListState != null )
48344925 {
4835- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , _imageListState . Handle ) ;
4926+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , _imageListState . CreateUniqueHandle ( ) ) ;
4927+ if ( previousHandle != IntPtr . Zero )
4928+ {
4929+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4930+ Debug . Assert ( result . IsTrue ( ) ) ;
4931+ }
48364932 }
48374933
48384934 if ( _imageListGroup != null )
48394935 {
4840- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER , _imageListGroup . Handle ) ;
4936+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . GROUPHEADER , _imageListGroup . CreateUniqueHandle ( ) ) ;
4937+ if ( previousHandle != IntPtr . Zero )
4938+ {
4939+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
4940+ Debug . Assert ( result . IsTrue ( ) ) ;
4941+ }
48414942 }
48424943 }
48434944
@@ -5364,8 +5465,13 @@ private void SmallImageListRecreateHandle(object sender, EventArgs e)
53645465 return ;
53655466 }
53665467
5367- IntPtr handle = ( SmallImageList is null ) ? IntPtr . Zero : SmallImageList . Handle ;
5368- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL , handle ) ;
5468+ IntPtr handle = ( SmallImageList is null ) ? IntPtr . Zero : SmallImageList . CreateUniqueHandle ( ) ;
5469+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . SMALL , handle ) ;
5470+ if ( previousHandle != IntPtr . Zero )
5471+ {
5472+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
5473+ Debug . Assert ( result . IsTrue ( ) ) ;
5474+ }
53695475
53705476 ForceCheckBoxUpdate ( ) ;
53715477 }
@@ -5396,8 +5502,13 @@ private void StateImageListRecreateHandle(object sender, EventArgs e)
53965502 return ;
53975503 }
53985504
5399- IntPtr handle = ( StateImageList is null ) ? IntPtr . Zero : StateImageList . Handle ;
5400- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , handle ) ;
5505+ IntPtr handle = ( StateImageList is null ) ? IntPtr . Zero : StateImageList . CreateUniqueHandle ( ) ;
5506+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , handle ) ;
5507+ if ( previousHandle != IntPtr . Zero )
5508+ {
5509+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
5510+ Debug . Assert ( result . IsTrue ( ) ) ;
5511+ }
54015512 }
54025513
54035514 /// <summary>
@@ -6164,7 +6275,12 @@ internal void RecreateHandleInternal()
61646275 // (Yes, it does exactly that even though our wrapper sets LVS_SHAREIMAGELISTS on the native listView.)
61656276 if ( IsHandleCreated && StateImageList != null )
61666277 {
6167- User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , IntPtr . Zero ) ;
6278+ var previousHandle = User32 . SendMessageW ( this , ( User32 . WM ) LVM . SETIMAGELIST , ( IntPtr ) LVSIL . STATE , IntPtr . Zero ) ;
6279+ if ( previousHandle != IntPtr . Zero )
6280+ {
6281+ var result = ComCtl32 . ImageList . Destroy ( previousHandle ) ;
6282+ Debug . Assert ( result . IsTrue ( ) ) ;
6283+ }
61686284 }
61696285
61706286 RecreateHandle ( ) ;
0 commit comments