Listing DebugControl.cs
using
System;
using
System.IO;
using
System.Collections;
using
System.ComponentModel;
using
System.Drawing;
using
System.Data;
using
System.Windows.Forms;
/*
*
* DebugControl is a simple Windows Forms control that reads all the image
files
* in a directory and provides a thumbnail preview of them.
*
* As always, if this control is of commercial use to you, feel free to use it
under
* the terms of your subscription.
*
*
*/
namespace
WellFormed
{
///
<summary>
/// Summary
description for DebugControl.
///
</summary>
public class
DebugControl : System.Windows.Forms.UserControl
{
string
_path;
[
Category("Data"),
Description("The
current directory path")
]
public
string Path
{
get{return
_path;}
set{
_path=value;
System.Diagnostics.Trace.WriteLine("New
path = "+value);
UpdateListBox();
}
}
//used
to store the icons used in the list box
private
Bitmap _folderImage;
private
Bitmap _imageImage;
//Controls
dragged to the user control surface
private
System.Windows.Forms.ListBox listBox1;
private
System.Windows.Forms.PictureBox pictureBox1;
private
System.ComponentModel.IContainer components;
public
DebugControl()
{
//
This call is required by the Windows.Forms Form Designer.
InitializeComponent();
//Load
the icons and make them transparent
_folderImage=(Bitmap)Bitmap.FromStream(this.GetType().Assembly.GetManifestResourceStream("DebugControl.Folder.bmp"));
_imageImage=(Bitmap)Bitmap.FromStream(this.GetType().Assembly.GetManifestResourceStream("DebugControl.Image.bmp"));
_folderImage.MakeTransparent(Color.Magenta);
_imageImage.MakeTransparent(Color.Magenta);
//Set
the current directory
Path=Directory.GetCurrentDirectory();
}
///
<summary>
///
Clean up any resources being used.
///
</summary>
protected
override void
Dispose( bool disposing )
{
if(
disposing )
{
if(
components != null )
components.Dispose();
}
base.Dispose(
disposing );
}
#region
Component Designer generated code
///
<summary>
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
</summary>
private
void InitializeComponent()
{
this.listBox1
= new System.Windows.Forms.ListBox();
this.pictureBox1
= new System.Windows.Forms.PictureBox();
this.SuspendLayout();
//
//
listBox1
//
this.listBox1.DrawMode
= System.Windows.Forms.DrawMode.OwnerDrawVariable;
this.listBox1.Location
= new System.Drawing.Point(8, 8);
this.listBox1.Name
= "listBox1";
this.listBox1.Size
= new System.Drawing.Size(120, 160);
this.listBox1.TabIndex
= 0;
this.listBox1.DoubleClick
+= new System.EventHandler(this.listBox1_DoubleClick);
this.listBox1.MeasureItem
+= new
System.Windows.Forms.MeasureItemEventHandler(this.listBox1_MeasureItem);
this.listBox1.DrawItem
+= new
System.Windows.Forms.DrawItemEventHandler(this.listBox1_DrawItem);
this.listBox1.SelectedIndexChanged
+= new System.EventHandler(this.listBox1_SelectedIndexChanged);
//
//
pictureBox1
//
this.pictureBox1.Location
= new System.Drawing.Point(136, 8);
this.pictureBox1.Name
= "pictureBox1";
this.pictureBox1.Size
= new System.Drawing.Size(120, 160);
this.pictureBox1.SizeMode
= System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex
= 1;
this.pictureBox1.TabStop
= false;
//
//
DebugControl
//
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.listBox1);
this.Name
= "DebugControl";
this.Size
= new System.Drawing.Size(264, 176);
this.Load
+= new System.EventHandler(this.DebugControl_Load);
this.Layout
+= new System.Windows.Forms.LayoutEventHandler(this.DebugControl_Layout);
this.ResumeLayout(false);
}
#endregion
private
void listBox1_SelectedIndexChanged(object
sender, System.EventArgs e)
{
//When
the selection changes
DirectoryItem
di = (DirectoryItem)this.listBox1.SelectedItem;
//Decide
if the item is a directory or an image
if(di!=null
&& di.ItemType==DirectoryItem.ItemTypes.Image)
{
//if
it's an image
if(this.pictureBox1.Image!=null)
{
//clear
out the old preview
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image=null;
//free up the old thumbnail
}
//load
up the image
Bitmap temp=(Bitmap)Bitmap.FromFile(di.Path);
//extract
a thumbnail from it
this.pictureBox1.Image=temp.GetThumbnailImage(this.pictureBox1.Width,this.pictureBox1.Height,null,IntPtr.Zero);
//and
tidy up
temp.Dispose();
}
}
protected
void UpdateListBox()
{
//if
there is no path, return
if(Path==null
| Path=="")
return;
//clean
out the list box
this.listBox1.Items.Clear();
//
in design mode we don't want it scanning the directories
if(this.DesignMode)
{
DirectoryItem
di=new DirectoryItem();
di.Path=di.Name="Directory
Placeholder";
di.ItemType=DirectoryItem.ItemTypes.Folder;
this.listBox1.Items.Add(di);
return;
}
if(Path!=Directory.GetDirectoryRoot(Path))
{
DirectoryItem
di=new DirectoryItem();
//link
to the parent directory
di.Path=di.Name="..";
di.ItemType=DirectoryItem.ItemTypes.Folder;
this.listBox1.Items.Add(di);
}
//assemble
a list of directories that can be selected first
string[]
directories = Directory.GetDirectories(_path,"*.*");
foreach(string
s in directories)
{
DirectoryItem
i =new DirectoryItem();
i.Path=s;
i.Name=new
DirectoryInfo(s).Name;
i.ItemType=DirectoryItem.ItemTypes.Folder;
this.listBox1.Items.Add(i);
}
//then
a list of all the image files in the current directory
string[]
filetypes=new string[]{"*.bmp","*.jpg","*.gif","*.png"};
ArrayList
al=new ArrayList();
foreach(string
ext in filetypes)
{
string[]
images=Directory.GetFiles(_path,ext);
foreach(string
s in images)
al.Add(s);
}
//these
are sorted alphabetically
al.Sort();
//and
turned into image entries for the list box
foreach(string
s in al)
{
DirectoryItem
i = new DirectoryItem();
i.Path=s;
i.Name=new
DirectoryInfo(s).Name;
i.ItemType=DirectoryItem.ItemTypes.Image;
this.listBox1.Items.Add(i);
}
}
private
void listBox1_DoubleClick(object
sender, System.EventArgs e)
{
if(this.listBox1.SelectedItem!=null)
{
DirectoryItem
di=(DirectoryItem)this.listBox1.SelectedItem;
//if
the item is a directory or the path to the parent directory, select it
if(di.ItemType==DirectoryItem.ItemTypes.Folder)
{
if(di.Path=="..")
Path=Directory.GetParent(Path).FullName;
else
Path=di.Path;
}
}
}
private
void listBox1_MeasureItem(object
sender, System.Windows.Forms.MeasureItemEventArgs e)
{
//measure
the items. If its a valid one, use the string length and the icon size plus a
bit of padding
if(e.Index>-1)
{
e.ItemWidth=(int)(20+e.Graphics.MeasureString(((DirectoryItem)((ListBox)sender).Items[e.Index]).Name,Font,1024,StringFormat.GenericTypographic).Width);
e.ItemHeight=(int)Math.Max(22,Font.Height+4);
}
else
{
e.ItemHeight=22;
e.ItemWidth=this.listBox1.Width;
}
}
private
void listBox1_DrawItem(object
sender, System.Windows.Forms.DrawItemEventArgs e)
{
if(e.Index==-1)
return;
//Draws
each item
System.Diagnostics.Trace.Write(string.Format("Drawing
item {0}",this.listBox1.Items[e.Index].ToString()));
e.DrawBackground();
//Figure
out the forecolour from the select state
SolidBrush
b=new SolidBrush(((e.State &
DrawItemState.Selected)!=DrawItemState.Selected) ? this.ForeColor
: Color.White);
DirectoryItem
di=(DirectoryItem)((ListBox)sender).Items[e.Index];
//draw
the correct icon
if(di.ItemType==DirectoryItem.ItemTypes.Folder)
{
System.Diagnostics.Trace.WriteLine("-Directory");
e.Graphics.DrawImage(_folderImage,new
Rectangle(2,e.Bounds.Top+(e.Bounds.Height/2)-8,16,16),0,0,16,16,GraphicsUnit.Pixel);
}
else
{
System.Diagnostics.Trace.WriteLine("-Image
file");
e.Graphics.DrawImage(_imageImage,new
Rectangle(2,e.Bounds.Top+(e.Bounds.Height/2)-8,16,16),0,0,16,16,GraphicsUnit.Pixel);
}
//and
finally, the string
e.Graphics.DrawString(di.Name,Font,b,22f,e.Bounds.Top+2,StringFormat.GenericTypographic);
b.Dispose();
}
private
void DebugControl_Layout(object
sender, System.Windows.Forms.LayoutEventArgs e)
{
//Reposition
the listbox and picturebox if needed
this.listBox1.Location=new
Point(0,0);
this.listBox1.Size=new
Size(this.Width/2,this.Height);
this.pictureBox1.Location=new
Point(this.Width/2,0);
this.pictureBox1.Size=new
Size(this.Width/2,this.Height);
}
private
void DebugControl_Load(object
sender, System.EventArgs e)
{
if(this.DesignMode)
this.pictureBox1.Image=Image.FromStream(this.GetType().Assembly.GetManifestResourceStream("DebugControl.PicturePlaceholder.bmp"));
}
}
///
<summary>
/// This simple class
represents a single directory item entry and is stored in the listbox
///
</summary>
class DirectoryItem
{
public
enum ItemTypes
{
Image,
Folder
}
string
_path;
public
string Path
{
get{return
_path;}
set{_path=value;}
}
string
_name;
public
string Name
{
get{return
_name;}
set{_name=value;}
}
ItemTypes
_itemType;
public
ItemTypes ItemType
{
get{return
_itemType;}
set{_itemType=value;}
}
public
override string
ToString()
{
return
Name;
}
}
}
Listing DebugControl.vb
Imports
System
Imports
System.IO
Imports
System.Drawing
Imports
System.Windows.Forms
Public
Class DebugControl
Inherits System.Windows.Forms.UserControl
Private _folderImage As
Bitmap
Private _imageImage As
Bitmap
Private _path As
String
Public Property
Path() As String
Get
Return _path
End Get
Set(ByVal Value
As String)
_path = Value
System.Diagnostics.Trace.WriteLine("New path = " & Value)
UpdateListBox()
End Set
End Property
#Region
" Windows Form Designer generated code "
Public Sub
New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Load the icons and make them transparent
_folderImage
= CType(Bitmap.FromStream(Me.GetType().Assembly.GetManifestResourceStream("DebugControlVB.Folder.bmp")),
Bitmap)
_imageImage
= CType(Bitmap.FromStream(Me.GetType().Assembly.GetManifestResourceStream("DebugControlVB.Image.bmp")),
Bitmap)
_folderImage.MakeTransparent(Color.Magenta)
_imageImage.MakeTransparent(Color.Magenta)
'Set the current directory
Path
= Directory.GetCurrentDirectory()
End Sub
'UserControl1 overrides dispose to clean up the
component list.
Protected Overloads
Overrides Sub
Dispose(ByVal disposing
As Boolean)
If disposing Then
If Not
(components Is Nothing)
Then
components.Dispose()
End
If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As
System.ComponentModel.IContainer
'NOTE: The following procedure is required by the
Windows Form Designer
'It
can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents
PictureBox1 As System.Windows.Forms.PictureBox
Friend WithEvents
ListBox1 As System.Windows.Forms.ListBox
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.PictureBox1 = New
System.Windows.Forms.PictureBox
Me.ListBox1 = New
System.Windows.Forms.ListBox
Me.SuspendLayout()
'
'PictureBox1
'
Me.PictureBox1.Location =
New System.Drawing.Point(144, 8)
Me.PictureBox1.Name = "PictureBox1"
Me.PictureBox1.Size =
New System.Drawing.Size(120, 168)
Me.PictureBox1.SizeMode =
System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.PictureBox1.TabIndex = 0
Me.PictureBox1.TabStop =
False
'
'ListBox1
'
Me.ListBox1.DrawMode =
System.Windows.Forms.DrawMode.OwnerDrawVariable
Me.ListBox1.ForeColor =
System.Drawing.Color.Black
Me.ListBox1.Location =
New System.Drawing.Point(0, 8)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New
System.Drawing.Size(128, 160)
Me.ListBox1.TabIndex = 1
'
'DebugControl
'
Me.Controls.Add(Me.ListBox1)
Me.Controls.Add(Me.PictureBox1)
Me.Name = "DebugControl"
Me.Size = New
System.Drawing.Size(280, 184)
Me.ResumeLayout(False)
End Sub
#End
Region
Private Sub
ListBox1_SelectedIndexChanged(ByVal sender
As System.Object, ByVal
e As System.EventArgs)
Handles ListBox1.SelectedIndexChanged
'When the selection changes
Dim di As
DirectoryItem = CType(Me.ListBox1.SelectedItem,
DirectoryItem)
'Decide if the item is a directory or an image
If (Not di
Is Nothing)
And (di.ItemType = DirectoryItem.ItemTypes.Image)
Then
'if it's an image
If Not
Me.PictureBox1.Image Is
Nothing Then
'clear out the old preview
Me.PictureBox1.Image.Dispose()
Me.PictureBox1.Image =
Nothing 'free up the
old thumbnail
End If
'load up the image
Dim temp As
Bitmap = CType(Bitmap.FromFile(di.Path), Bitmap)
'extract
a thumbnail from it
Me.PictureBox1.Image = temp.GetThumbnailImage(Me.PictureBox1.Width,
Me.PictureBox1.Height,
Nothing, IntPtr.Zero)
'and tidy up
temp.Dispose()
End If
End Sub
Private Sub
DebugControl_Layout(ByVal sender
As Object,
ByVal e As
System.Windows.Forms.LayoutEventArgs) Handles
MyBase.Layout
'Reposition the listbox and picturebox if needed
Me.ListBox1.Location =
New Point(0, 0)
Me.ListBox1.Size = New
Size(Me.Width / 2, Me.Height)
Me.PictureBox1.Location =
New Point(Me.Width
/ 2, 0)
Me.PictureBox1.Size =
New Size(Me.Width / 2,
Me.Height)
End Sub
Protected Sub
UpdateListBox()
'if there is no path, return
If (Path Is
Nothing) Or
(Path = "") Then
Return
End If
'clean out the list box
Me.ListBox1.Items.Clear()
' in design mode we don't want it scanning the
directories
If Me.DesignMode
Then
Dim di As
New DirectoryItem
di.Path = "Directory Placeholder"
di.Name = "Directory Placeholder"
di.ItemType = DirectoryItem.ItemTypes.Folder
Me.ListBox1.Items.Add(di)
Return
End If
If Path <> Directory.GetDirectoryRoot(Path)
Then
Dim di As
New DirectoryItem
'link to the parent directory
di.Path = ".."
di.Name = ".."
di.ItemType = DirectoryItem.ItemTypes.Folder
Me.ListBox1.Items.Add(di)
End If
'assemble a list of directories that can be selected
first
Dim directories As
String() = Directory.GetDirectories(_path,
"*.*")
Dim s As
String
For Each s
In directories
Dim i As
New DirectoryItem
i.Path = s
i.Name = New DirectoryInfo(s).Name
i.ItemType = DirectoryItem.ItemTypes.Folder
Me.ListBox1.Items.Add(i)
Next
'then a list of all the image files in the current
directory
Dim filetypes As
String() = New
String() {"*.bmp", "*.jpg", "*.gif", "*.png"}
Dim al As
New ArrayList
Dim ext As
String
For Each ext
In filetypes
Dim images As
String() = Directory.GetFiles(_path, ext)
For Each s
In images
al.Add(s)
Next
Next
'these are sorted alphabetically
al.Sort()
'and turned into image entries for the list box
For Each s
In al
Dim i As
New DirectoryItem
i.Path = s
i.Name = New DirectoryInfo(s).Name
i.ItemType = DirectoryItem.ItemTypes.Image
Me.ListBox1.Items.Add(i)
Next
End Sub
Private Sub
listBox1_DoubleClick(ByVal sender
As Object,
ByVal e As
System.EventArgs) Handles ListBox1.DoubleClick
If Not
Me.ListBox1.SelectedItem
Is Nothing
Then
Dim di As
DirectoryItem = CType(Me.ListBox1.SelectedItem,
DirectoryItem)
'if the item is a directory or the path to the parent
directory, select it
If di.ItemType = DirectoryItem.ItemTypes.Folder
Then
If di.Path = ".."
Then
Path = Directory.GetParent(Path).FullName
Else
Path = di.Path
End If
End If
End If
End Sub
Private Sub
listBox1_MeasureItem(ByVal sender
As Object,
ByVal e As
System.Windows.Forms.MeasureItemEventArgs) Handles
ListBox1.MeasureItem
'measure the items. If its a valid one, use the string
length and the icon size plus a bit of padding
If (e.Index > -1) Then
Dim lb As
ListBox = DirectCast(sender, ListBox)
Dim di As
DirectoryItem = DirectCast(lb.Items(e.Index),
DirectoryItem)
e.ItemWidth = CInt(20 +
e.Graphics.MeasureString(di.Name, Font, 1024,
StringFormat.GenericTypographic).Width)
e.ItemHeight = CInt(Math.Max(22, Font.Height +
4))
Else
e.ItemHeight = 22
e.ItemWidth = Me.ListBox1.Width
End If
End Sub
Private Sub
listBox1_DrawItem(ByVal sender
As Object,
ByVal e As
System.Windows.Forms.DrawItemEventArgs) Handles
ListBox1.DrawItem
If e.Index = -1 Then
Return
End If
Dim lb As
ListBox = DirectCast(sender, ListBox)
'Draws each item
System.Diagnostics.Trace.Write(String.Format("Drawing
item {0}", Me.ListBox1.Items(e.Index).ToString()))
e.DrawBackground()
'Figure out the forecolour from the select state
Dim b As
SolidBrush = New SolidBrush(me.ForeColor)
If (e.State And
DrawItemState.Selected) = DrawItemState.Selected Then
b.Color = Color.White
End If
Dim di As
DirectoryItem = DirectCast(lb.Items(e.Index),
DirectoryItem)
'draw the correct icon
If di.ItemType = DirectoryItem.ItemTypes.Folder
Then
System.Diagnostics.Trace.WriteLine("-Directory")
e.Graphics.DrawImage(_folderImage, New
Rectangle(2, e.Bounds.Top + (e.Bounds.Height / 2) - 8, 16, 16), 0, 0, 16, 16,
GraphicsUnit.Pixel)
Else
System.Diagnostics.Trace.WriteLine("-Image file")
e.Graphics.DrawImage(_imageImage, New
Rectangle(2, e.Bounds.Top + (e.Bounds.Height / 2) - 8, 16, 16), 0, 0, 16, 16,
GraphicsUnit.Pixel)
End If
'and finally, the string
e.Graphics.DrawString(di.Name, Font, b, 22.0F, e.Bounds.Top + 2,
StringFormat.GenericTypographic)
b.Dispose()
End Sub
Private Sub
DebugControl_Load(ByVal sender
As Object,
ByVal e As
System.EventArgs) Handles
MyBase.Load
If Me.DesignMode
Then
Me.PictureBox1.Image = Image.FromStream(Me.GetType().Assembly.GetManifestResourceStream("DebugControlVB.PicturePlaceholder.bmp"))
End If
End Sub
End
Class
'
This simple class represents a single directory item entry and is stored in the
listbox
Class
DirectoryItem
Public Enum
ItemTypes
Image
Folder
End Enum
Dim _path As
String
Public Property
Path() As String
Get
Return _path
End Get
Set(ByVal Value
As String)
_path = Value
End Set
End Property
Dim _name As
String
Public Property
Name() As String
Get
Return _name
End Get
Set(ByVal Value
As String)
_name = Value
End Set
End Property
Dim _itemType As
ItemTypes
Public Property
ItemType() As ItemTypes
Get
Return _itemType
End Get
Set(ByVal Value
As ItemTypes)
_itemType
= Value
End Set
End Property
Public Overrides
Function ToString() As
String
Return Name
End Function
End
Class