Introduction
Sometimes we want use the system ImageList
in the ListView
or TreeView
like the explorer which can show the system ImageList
. We can use SHgetfileinfo
API to get the system ImageList
’s handle and the index which specifically file should use.
Using the system ImageList
In this subject, I use the “SendMessage
” API to binding the System image to TreeView
or ListView
.
public static void SetListViewImageList(
IntPtr hwnd,ListView listView,
SysImageList sysImageList,bool forStateImages)
{
IntPtr wParam = (IntPtr)LVSIL_NORMAL;
if (sysImageList.ImageListSize == SysImageListSize.smallIcons)
{
wParam = (IntPtr)LVSIL_SMALL;
}
if (forStateImages)
{
wParam = (IntPtr)LVSIL_STATE;
}
SendMessage(hwnd,LVM_SETIMAGELIST,wParam,sysImageList.Handle);
}
public static void SetTreeViewImageList(IntPtr hwnd,
TreeView treeView, SysImageList sysImageList,
bool forStateImages )
{
IntPtr wParam = (IntPtr)TVSIL_NORMAL;
if (forStateImages)
{
wParam = (IntPtr)TVSIL_STATE;
}
SendMessage(hwnd, TVM_SETIMAGELIST,
wParam, sysImageList.Handle);
}
Wrap the SHGetFileInfo routine
Wrapping the “SHGetFileInfo
” in the .NET is very difficult. I used eVC for help, to wrap it.
extern "C" __declspec (dllexport) DWORD SHABgetfileinfo(LPCTSTR pszFileName)
{
SHFILEINFO ssfi;
return SHGetFileInfo(pszFileName, 0, &ssfi, sizeof(SHFILEINFO),
SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
}
extern "C" __declspec (dllexport) int SHIndexfileinfo(LPCTSTR pszFileName)
{
SHFILEINFO ssfi;
SHGetFileInfo(pszFileName, 0, &ssfi, sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
return ssfi.iIcon;
}
extern "C" __declspec (dllexport) int SHIndexfileinfoEx(
LPCTSTR pszFileName,DWORD dwAttr, UINT dwFlag)
{
SHFILEINFO ssfi;
SHGetFileInfo(pszFileName, 0, &ssfi, sizeof(SHFILEINFO),dwFlag);
return ssfi.iIcon;
}
Call the routine in form
sysilsSmall = new SysImageList(SysImageListSize.smallIcons);
this.tvFolders.Capture = true;
IntPtr hwnd1 = GetCapture();
this.tvFolders.Capture = false;
this.lvFiles.Capture = true;
IntPtr hwnd2 = GetCapture();
SysImageListHelper.SetTreeViewImageList(hwnd1,tvFolders,
sysilsSmall,false);
SysImageListHelper.SetListViewImageList(hwnd2,
lvFiles,sysilsSmall,false);
this.lvFiles.Capture = false;
Sort by file name, size, create date etc.
I use a PictureBox
to split the window, I process the MouseDown
, MouseMove
and MouseUp
event. When the stylus touch the screen, the MouseDown
records the PictureBox
’s location and shows it. When we move it, the MouseMove
event changes the PictureBox
’s location and when the stylus is up, the MouseUp
event stops to fix up the PictureBox
.
private void FileExplorer_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
this.picSplitter.Top=e.Y-4;
this.picSplitter.Visible=true;
this.Moving=true;
}
private void FileExplorer_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if(this.Moving)
{
this.picSplitter.Top=e.Y;
}
}
private void FileExplorer_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
this.tvFolders.Height=e.Y-5;
this.lvFiles.Top=this.tvFolders.Top+this.tvFolders.Height+10;
this.lvFiles.Height=this.Height-this.lvFiles.Top;
this.picSplitter.Visible=false;
this.Moving=false;
this.ModeChange=false;
}
Sort by file name, size, create date etc.
private void Sort(ref ArrayList AL,string SortBy,bool Asc)
{
IComparer myComparer=null;
switch(SortBy)
{
case "Name":
if(Asc)
myComparer=new SortNameAsc();
else
myComparer=new SortNameDesc();
break;
case "Size":
if(Asc)
myComparer=new SortSizeAsc();
else
myComparer=new SortSizeDesc();
break;
case "Type":
if(Asc)
myComparer=new SortTypeAsc();
else
myComparer=new SortTypeDesc();
break;
case "Modified":
if(Asc)
myComparer=new SortModifiedAsc();
else
myComparer=new SortModifiedDesc();
break;
}
AL.Sort(myComparer);
}
public class SortNameDesc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( (new
CaseInsensitiveComparer()).Compare((object)((sFile)y).Name,
(object)((sFile)x).Name ) );
}
}
public class SortNameAsc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( (new
CaseInsensitiveComparer()).Compare((object)((sFile)x).Name,
(object)((sFile)y).Name ) );
}
}
public class SortFullNmeAsc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( (new
CaseInsensitiveComparer()).Compare((object)((sFile)x).FullName,
(object)((sFile)y).FullName ) );
}
}
public class SortFullNameDesc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( (new
CaseInsensitiveComparer()).Compare( (object)((sFile)y).FullName,
(object)((sFile)x).FullName ) );
}
}
public class SortTypeDesc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( (new
CaseInsensitiveComparer()).Compare( (object)((sFile)y).Type,
(object)((sFile)x).Type ) );
}
}
public class SortTypeAsc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( (new
CaseInsensitiveComparer()).Compare( (object)((sFile)x).Type,
(object)((sFile)y).Type ) );
}
}
public class SortSizeAsc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( int.Parse(((sFile)x).Size)-int.Parse(((sFile)y).Size) ) ;
}
}
public class SortSizeDesc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( int.Parse(((sFile)y).Size)-int.Parse(((sFile)x).Size) ) ;
}
}
public class SortModifiedAsc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( DateTime.Compare( DateTime.Parse(((sFile)x).Modified),
DateTime.Parse(((sFile)y).Modified) ) );
}
}
public class SortModifiedDesc : IComparer
{
int IComparer.Compare( Object x, Object y )
{
return( DateTime.Compare( DateTime.Parse(((sFile)y).Modified),
DateTime.Parse(((sFile)x).Modified) ) );
}
}
Shellex other program
[DllImport("coredll.dll")]
public static extern IntPtr GetCapture();
[DllImport("coredll", EntryPoint="ShellExecuteEx", SetLastError=true)]
private extern static bool ShellExecuteEx( ShellExecuteInfo ex );
private void lvFiles_SelectedIndexChanged(object sender, System.EventArgs e)
{
if(this.lvFiles.SelectedIndices.Count>0)
{
string FullPath=this.lvFiles.Items[this.lvFiles.SelectedIndices[0]].Text;
ShellExecuteInfo sei=new ShellExecuteInfo();
GCHandle hfile = GCHandle.Alloc((FullPath + '\0').ToCharArray(),
GCHandleType.Pinned);
sei.lpFile = (IntPtr)((int)hfile.AddrOfPinnedObject() + 4);
sei.nShow = 1;
GCHandle hverb = new GCHandle();
hverb = GCHandle.Alloc(("Open"+'\0').ToCharArray(), GCHandleType.Pinned);
sei.lpVerb = (IntPtr)((int)hverb.AddrOfPinnedObject() + 4);
bool ret=ShellExecuteEx(sei);
}
sealed class ShellExecuteInfo
{
public UInt32 cbSize = 60;
public UInt32 fMask = 0x00000040;
public IntPtr hwnd = IntPtr.Zero;
public IntPtr lpVerb = IntPtr.Zero;
public IntPtr lpFile = IntPtr.Zero;
public IntPtr lpParameters = IntPtr.Zero;
public IntPtr lpDirectory = IntPtr.Zero;
public int nShow = 0;
public IntPtr hInstApp = IntPtr.Zero;
public IntPtr lpIDList = IntPtr.Zero;
public IntPtr lpClass = IntPtr.Zero;
public IntPtr hkeyClass = IntPtr.Zero;
public UInt32 dwHotKey = 0;
public IntPtr hIcon = IntPtr.Zero;
public IntPtr hProcess = IntPtr.Zero;
}