Я написал класс MyListView для добавления метода для установки стрелки сортировки:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsDataTypes
{
class MyListView : ListView
{
public const Int32 HDF_SORTDOWN = 0x0200;
public const Int32 HDF_SORTUP = 0x0400;
public const UInt32 HDI_FORMAT = 0x0004;
public const UInt32 HDM_GETITEM = 0x120b;
public const UInt32 HDM_SETITEM = 0x120c;
public const UInt32 LVM_GETHEADER = 0x101f;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 uMsg, UIntPtr wParam, IntPtr lParam);
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
public static extern Int32 SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList);
struct HDITEM
{
public UInt32 mask;
public Int32 cxy;
public String pszText;
public IntPtr hbm;
public Int32 cchTextMax;
public Int32 fmt;
public IntPtr lParam;
public Int32 iImage;
public Int32 iOrder;
public UInt32 type;
public IntPtr pvFilter;
public UInt32 state;
}
public MyListView()
{
this.DoubleBuffered = true;
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
SetWindowTheme(this.Handle, "Explorer", null);
}
public void SetSortArrow(int column, SortOrder sortOrder)
{
IntPtr hHeader = SendMessage(this.Handle, LVM_GETHEADER, UIntPtr.Zero, IntPtr.Zero);
HDITEM headerItem = new HDITEM();
headerItem.mask = HDI_FORMAT;
IntPtr pHeaderItem = Marshal.AllocHGlobal(Marshal.SizeOf(headerItem));
Marshal.StructureToPtr(headerItem, pHeaderItem, true);
SendMessage(hHeader, HDM_GETITEM, new UIntPtr((UInt32)column), pHeaderItem);
headerItem.fmt = ((HDITEM)Marshal.PtrToStructure(pHeaderItem, headerItem.GetType())).fmt;
switch (sortOrder)
{
case SortOrder.Ascending:
headerItem.fmt &= ~HDF_SORTDOWN;
headerItem.fmt |= HDF_SORTUP;
break;
case SortOrder.Descending:
headerItem.fmt &= ~HDF_SORTUP;
headerItem.fmt |= HDF_SORTDOWN;
break;
case SortOrder.None:
headerItem.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
break;
}
Marshal.StructureToPtr(headerItem, pHeaderItem, true);
SendMessage(hHeader, HDM_SETITEM, new UIntPtr((UInt32)column), pHeaderItem);
Marshal.FreeHGlobal(pHeaderItem);
}
}
}
Иногда возникает ошибка, даже если я не изменил исходный код и просто запускаю второй раз, когда звоню SetSortArrow
.
Что не так с моим кодом?