Microsoft KB Archive/313134

= PRB: Windows Forms TreeView Control Does Not Handle State Image Lists in Visual C# .NET =

Article ID: 313134

Article Last Modified on 2/22/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Visual C# .NET 2003 Standard Edition
 * Microsoft Visual C# .NET 2002 Standard Edition

-



This article was previously published under Q313134



This article references the following .NET Framework Class Library namespaces:
 * System.Windows.Forms
 * System.Runtime.InteropServices



SYMPTOMS
The Windows Forms TreeView control displays a hierarchy of nodes similar to the way that Windows Explorer displays folders in the left pane. With the Windows Forms TreeView control, the application cannot use a State image list to display a State icon. The State icon appears to the left of the icon that is displayed for a node in the control. This behavior differs from the behavior of the underlying Win32 TreeView control.



RESOLUTION
The .NET Windows Forms application can use Interop services to direct the underlying Win32 TreeView control to display a State icon. To do this, the application can assign a value to each field in the TVITEM structure and send a TVM_SETITEM message to the underlying Win32 TreeView control through Interop services.



MORE INFORMATION
A Win32 TreeView control has two image lists that are associated with it:
 * Normal image list, which contains selected, nonselected, and overlay images for the items of a TreeView control.
 * State image list, which you can use to indicate application-defined item states. A State image is displayed to the left of an item's selected or nonselected image.

Because the Windows Forms TreeView control does not handle the State image list, follow these steps:
 * 1) Use Interop services to send a TVM_SETIMAGELIST message with the TVSIL_STATE flag to the underlying Win32 control to set the State image list.
 * 2) Send a TVM_SETITEM message to tell the control on which node to display a specific image from the image list. You must define the Win32 API function SendMessage to send these messages.

Because the TVM_SETIMAGELIST message and the TVM_SETITEM message require different parameters when they are sent to a TreeView control, you must overload the SendMessage function (as the following code shows).

This code demonstrates how to add a State image list to a Windows Forms TreeView control and how to display an image from the control on the root node.

Step-by-Step Example
 Start Microsoft Visual Studio .NET, and then create a new Windows Application in Visual C# .NET. Form1 is added to the project by default. On Form1, add a TreeView, a Button, and an ImageList control. Their default names are TreeView1, Button1 and ImageList1 respectively. In the properties of ImageList1, click the ellipsis (...) button of the Images property, and then add at least two images. This is required for the sample to work.  In the code window of Form1.cs, add the following statement after the other Using statements: using System.Runtime.InteropServices;   Copy and paste the following code in Form1 class after the Private statements: public const UInt32 TV_FIRST = 4352; public const UInt32 TVSIL_NORMAL = 0; public const UInt32 TVSIL_STATE  = 2; public const UInt32 TVM_SETIMAGELIST = TV_FIRST + 9; public const UInt32 TVM_GETNEXTITEM = TV_FIRST + 10; public const UInt32 TVIF_HANDLE = 16; public const UInt32 TVIF_STATE = 8; public const UInt32 TVIS_STATEIMAGEMASK = 61440; public const UInt32 TVM_SETITEM = TV_FIRST + 13; public const UInt32 TVGN_ROOT = 0; // Use a sequential structure layout to define TVITEM for the TreeView. [StructLayout(LayoutKind.Sequential, Pack=8, CharSet=CharSet.Auto)] public struct TVITEM {   public uint     mask; public IntPtr  hItem; public uint    state; public uint    stateMask; public IntPtr  pszText; public int     cchTextMax; public int     iImage; public int     iSelectedImage; public int     cChildren; public IntPtr  lParam; } // Declare two overloaded SendMessage functions. The // difference is in the last parameter: one is ByVal and the // other is ByRef. [DllImport(&quot;user32.dll&quot;)] public static extern UInt32 SendMessage( IntPtr hWnd, UInt32 Msg,    UInt32 wParam, UInt32 lParam);

[DllImport(&quot;User32&quot;, CharSet=CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg,    UInt32 wParam, ref TVITEM lParam);   In the Form1_Load event, copy and paste the following code: treeView1.Nodes.Add (&quot;Node1&quot;); treeView1.Nodes.Add (&quot;Node2&quot;); </li>  In the Button1_Click event, copy and paste the following code: IntPtr hWnd; IntPtr hRoot; TVITEM tvi; hWnd = treeView1.Handle;

// Send a TVM_SETIMAGELIST with TVSIL_STATE. SendMessage(hWnd,(UInt32)TVM_SETIMAGELIST,(UInt32)TVSIL_STATE,(UInt32)imageList1.Handle); // Get a handle to the top row. hRoot = (IntPtr)SendMessage(hWnd,(UInt32)TVM_GETNEXTITEM,(UInt32)TVGN_ROOT ,(UInt32)0);

// The following uses the TVM_SETITEM message to set the State // of a given item. It uses the TVITEM structure.

// tvi.mask: include TVIF_HANDLE and TVIF_STATE tvi.mask = TVIF_HANDLE | TVIF_STATE;

// To use the State image, tvi.State cannot be 0. //Setting it to 1 means to use the second image in the image list. tvi.State = (uint)1; // Left shift 12 to put info in bits 12 to 15 tvi.State = tvi.State << 12; // Set StateMask. -This is required to isolate State above. tvi.StateMask = TVIS_STATEIMAGEMASK;

// Define the item we want to set the State in. tvi.hItem = hRoot; //For example, try the root.

// Initialize the rest to zero. tvi.pszText = (IntPtr)0; tvi.cchTextMax = 0; tvi.iImage = 0; tvi.iSelectedImage = 0; tvi.cChildren = 0; tvi.lParam = (IntPtr)0;

// Send the TVM_SETITEM message. // TVM_SETITEM = 4365 SendMessage(hWnd,(UInt32)TVM_SETITEM,(UInt32)0,ref tvi); </li> Press the F5 key to run the application. Click Button1, and notice that the State image is added to the root node.</li></ol>

Keywords: kbgdi kbprb kbwindowsforms KB313134

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.