|
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using JGLibrary;
namespace JGFSControls
{
/// <summary>
/// Specialist ListView sorter for JSysListViewFS
/// </summary>
internal class JListViewSorterFS : IComparer
{
private int m_SortColumn;
private ListView m_ParentListView;
private SortOrder m_SortOrder;
internal JListViewSorterFS(ListView parentListView, int sortColumn, SortOrder sortOrder)
{
this.m_ParentListView = parentListView;
m_SortColumn = sortColumn;
this.m_SortOrder = sortOrder;
}
public int Compare(object ob1, object ob2)
{
int compareResult = 0;
JListViewItemFS lvItem1 = (JListViewItemFS)ob1;
JListViewItemFS lvItem2 = (JListViewItemFS)ob2;
string str1 = "", str2 = "";
// If not detail view then use Name
if (this.m_ParentListView.View != View.Details)
{
str1 = lvItem1.Text;
str2 = lvItem2.Text;
compareResult = String.Compare(str1, str2);
}
else
{
string strColumnName = this.m_ParentListView.Columns[m_SortColumn].Text;
// SortName has a prefix to ensure we keep files/folders separate
if (this.m_SortColumn == 0)
{
compareResult = String.Compare(lvItem1.SortName, lvItem2.SortName);
}
// If we are sorting column 1 we want to use sizes - except for folders where we use names
else if (this.m_SortColumn == 1)
{
if (lvItem1.ObjectType == ObjectTypes.FOLDER || lvItem2.ObjectType == ObjectTypes.FOLDER)
{
compareResult = String.Compare(lvItem1.Text, lvItem2.Text);
}
else
{
if (lvItem1.Size > lvItem2.Size)
compareResult = 1;
else if (lvItem1.Size < lvItem2.Size)
compareResult = -1;
else
compareResult = 0;
}
}
// If we are sorting column 2 we want to use dates - but separate folders
else if (this.m_SortColumn == 2)
{
if (lvItem1.ObjectType == ObjectTypes.FOLDER && lvItem2.ObjectType >= ObjectTypes.FILE)
compareResult = -1;
else if (lvItem1.ObjectType >= ObjectTypes.FILE && lvItem2.ObjectType == ObjectTypes.FOLDER)
compareResult = 1;
else
compareResult = DateTime.Compare(lvItem1.LastWriteTime, lvItem2.LastWriteTime);
}
// OK may be Attributes or File Type or File Notes
// Could have a separate SortName for each but is it worth it?
else if (strColumnName == "File Type" || strColumnName == "Attributes" || strColumnName == "File Notes")
{
str1 = lvItem1.SubItems[m_SortColumn].Text;
if (lvItem1.ObjectType == ObjectTypes.FOLDER)
str1 = "0" + str1;
else
str1 = "1" + str1;
str2 = lvItem2.SubItems[m_SortColumn].Text;
if (lvItem2.ObjectType == ObjectTypes.FOLDER)
str2 = "0" + str2;
else
str2 = "1" + str2;
compareResult = String.Compare(str1, str2);
}
}
// Determine whether the sort order is descending - if so Invert the value returned by Compare
if (m_SortOrder == SortOrder.Descending)
compareResult *= -1;
return compareResult;
}
internal void SetSortIcon()
{
const int HDF_LEFT = 0x0000;
const int HDF_RIGHT = 0x0001;
const int HDF_CENTER = 0x0002;
const int HDF_STRING = 0x4000;
const int HDF_SORTUP = 0x0400;
const int HDF_SORTDOWN = 0x0200;
const int HDI_TEXT = 0x0002;
const int HDI_FORMAT = 0x0004;
// NB Only works in XP and later!
const int HDM_FIRST = 0x1200;
// const int HDM_SETITEM = (HDM_FIRST + 4);
// Oooh Unicode in x64?
const int HDM_SETITEMW = (HDM_FIRST + 12);
const int LVM_GETHEADER = 4127;
HDITEM hd;
int intCount;
// In a long operation there can be a problem getting the handle to the ImageList
try
{
IntPtr ipHeader = (IntPtr)JDll.SendMessage(this.m_ParentListView.Handle, LVM_GETHEADER, 0, 0);
// Set/Clear the Appropriate Icon
for (intCount = 0; intCount < this.m_ParentListView.Columns.Count; intCount++)
{
hd = new HDITEM();
hd.mask = HDI_FORMAT | HDI_TEXT;
hd.pszText = this.m_ParentListView.Columns[intCount].Text;
// Set icon
if (intCount == this.m_SortColumn)
{
if (this.m_SortOrder == SortOrder.Ascending)
hd.fmt |= HDF_SORTUP;
else
hd.fmt |= HDF_SORTDOWN;
}
else
// clear icon
{
hd.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
}
hd.fmt |= HDF_STRING;
if (this.m_ParentListView.Columns[intCount].TextAlign == HorizontalAlignment.Left)
hd.fmt |= HDF_LEFT;
else if (this.m_ParentListView.Columns[intCount].TextAlign == HorizontalAlignment.Right)
hd.fmt |= HDF_RIGHT;
else
hd.fmt |= HDF_CENTER;
JDll.SendMessage(ipHeader, HDM_SETITEMW, intCount, ref hd);
}
}
catch
{
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I have been a keen hobbyist programmer since getting my first computer - a Vic 20 (you had to be able to write programs then since few programs were available and all were expensive).
Retired and now living in Pewsey, Wiltshire, where I spend (far too much of) my time writing computer programs to keep my mind active.