Monday, June 25, 2007

Windows ListView with subitem images

i was assign to migrate our application (Richfocus) from freamwork 1.1 to 2.0. one portion which is using the listview control stoped working suddenly. all the program code works fine in 1.1 but not in 2.0. It was a extended version of the ListView to add images to it's sub items, finally i managed to fix the code by over writing with this code.

i have pasted the code here, so u might save some time.

using System;
using System.Runtime.InteropServices;
public class ListViewEx : System.Windows.Forms.ListView
{
private const int LVIF_IMAGE = 0x2;
private const int LVS_EX_SUBITEMIMAGES = 0x2;
private const int LVM_FIRST = 0x1000;
private const int LVM_GETITEMA = LVM_FIRST + 5;
private const int LVM_GETITEMW = LVM_FIRST + 75;
private static readonly int LVM_GETITEM = (Marshal.SystemDefaultCharSize
== 1) ? LVM_GETITEMA : LVM_GETITEMW;
private const int LVM_SETITEMA = LVM_FIRST + 6;
private const int LVM_SETITEMW = LVM_FIRST + 76;
private static readonly int LVM_SETITEM = (Marshal.SystemDefaultCharSize
== 1) ? LVM_SETITEMA : LVM_SETITEMW;
private const int LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54;

[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr
wParam, ref LVITEM lParam);
[DllImport("User32.dll", CharSet=CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr
wParam, IntPtr lParam);

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct LVITEM
{
public int mask;
public int iItem;
public int subItem;
public int state;
public int stateMask ;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszText;
public int cchTextMax;
public int iImage;
public IntPtr lParam;
public int iIndent;
}

private bool ListView_SetItem(IntPtr hwnd, ref LVITEM lvi)
{
int result = SendMessage(hwnd, LVM_SETITEM, IntPtr.Zero, ref lvi);
return (result == 0) ? false : true;
}

private bool ListView_GetItem(IntPtr hwnd, ref LVITEM lvi)
{
int result = SendMessage(hwnd, LVM_GETITEM, IntPtr.Zero, ref lvi);
return (result == 0) ? false : true;
}

private void ListView_SetExtendedListViewStyleEx(IntPtr hwnd, int mask,
int style)
{
SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, new IntPtr(mask),
new IntPtr(style));
}

private void ListView_SetSubItemImageIndex(IntPtr hwnd, int index, int
subItemIndex, int imageIndex)
{
LVITEM lvi = new LVITEM();
lvi.iItem = index;
lvi.subItem = subItemIndex;
lvi.iImage = imageIndex;
lvi.mask = LVIF_IMAGE;
ListView_SetItem(hwnd, ref lvi);
}

private int ListView_GetSubItemImageIndex(IntPtr hwnd, int index, int
subItemIndex)
{
LVITEM lvi = new LVITEM();
lvi.iItem = index;
lvi.subItem = subItemIndex;
lvi.mask = LVIF_IMAGE;
if (ListView_GetItem(hwnd, ref lvi))
return lvi.iImage;
else
return -1;
}

protected override void OnCreateControl()
{
base.OnCreateControl();
ListView_SetExtendedListViewStyleEx(this.Handle,
LVS_EX_SUBITEMIMAGES, LVS_EX_SUBITEMIMAGES);
}

public void SetSubItemImageIndex(int index, int subItemIndex, int
imageIndex)
{
ListView_SetSubItemImageIndex(this.Handle, index, subItemIndex,
imageIndex);
}

public int GetSubItemImageIndex(int index, int subItemIndex)
{
return ListView_GetSubItemImageIndex(this.Handle, index,
subItemIndex);
}
}

No comments: