TVM_GETITEM or TVM_GETITEMSTATE can be used to get the state, which can then be used to deduce which checkbox image (none, checked or unchecked) is on the node. Here's an extension class that provides the two methods you need.
USAGE:
var treeNode = ...;
if (treeNode.IsCheckBoxVisible())
treeNode.SetIsCheckBoxVisible(false);
else
treeNode.SetIsCheckBoxVisible(true);
EXTENSIONS:
public static class TreeViewExtensions
{
public static bool IsCheckBoxVisible(this TreeNode node)
{
if (node == null)
throw new ArgumentNullException("node");
if (node.TreeView == null)
throw new InvalidOperationException("The node does not belong to a tree.");
var tvi = new TVITEM
{
hItem = node.Handle,
mask = TVIF_STATE
};
var result = SendMessage(node.TreeView.Handle, TVM_GETITEM, node.Handle, ref tvi);
if (result == IntPtr.Zero)
throw new ApplicationException("Error getting TreeNode state.");
var imageIndex = (tvi.state & TVIS_STATEIMAGEMASK) >> 12;
return (imageIndex != 0);
}
public static void SetIsCheckBoxVisible(this TreeNode node, bool value)
{
if (node == null)
throw new ArgumentNullException("node");
if (node.TreeView == null)
throw new InvalidOperationException("The node does not belong to a tree.");
var tvi = new TVITEM
{
hItem = node.Handle,
mask = TVIF_STATE,
stateMask = TVIS_STATEIMAGEMASK,
state = (value ? node.Checked ? 2 : 1 : 0) << 12
};
var result = SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
if (result == IntPtr.Zero)
throw new ApplicationException("Error setting TreeNode state.");
}
private const int TVIF_STATE = 0x8;
private const int TVIS_STATEIMAGEMASK = 0xF000;
private const int TV_FIRST = 0x1100;
private const int TVM_GETITEM = TV_FIRST + 62;
private const int TVM_SETITEM = TV_FIRST + 63;
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
private struct TVITEM
{
public int mask;
public IntPtr hItem;
public int state;
public int stateMask;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref TVITEM lParam);
}