Click here to Skip to main content
15,893,644 members
Articles / Programming Languages / C#

Dual Pane File Manager

Rate me:
Please Sign up or sign in to vote.
4.64/5 (28 votes)
21 Dec 2010CPOL8 min read 140.8K   2.3K   119  
A dual pane file manager for Windows XP.
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Retired
United Kingdom United Kingdom
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.

Comments and Discussions