.comment-link {margin-left:.6em;}

kHSw

Wednesday, March 08, 2006

Create an icon using VB.NET

You just have finished your application, the only thing you need is an icon. You don't have icons on your machine and you don't have the graphical skills to create one. But... you have an image on your PC or you found one on Google (watch out for copyrights!) that could be used, too bad it's not in .ico format.

But since you're a .NET-coder, you can create an application to convert an image to an icon in less then one minute!
Have a look at this demo application.
  • Create a new Windows Application
  • Set the value of the AllowDrop property of the form to True
  • Add this code to the DragEnter event of the form

Private Sub Form1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.None
End If
End Sub

  • Add code to the DragDrop event of the form

Private Sub Form1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
Dim arr As Array = DirectCast(e.Data.GetData(DataFormats.FileDrop), Array)
For i As Integer = 0 To arr.Length - 1
CreateIcon(Convert.ToString(arr.GetValue(i)))
Next
End Sub

  • Create the CreateIcon procedure

Private Sub CreateIcon(ByVal bitmapName As String)
Try
Dim fi As New System.IO.FileInfo(bitmapName)
Dim bmp As New Bitmap(fi.FullName)
Dim sw As System.IO.StreamWriter = System.IO.File.CreateText(fi.FullName.Replace(fi.Extension, ".ico"))
Icon.FromHandle(bmp.GetHicon).Save(sw.BaseStream)
sw.Close()
Catch ex As Exception
System.Diagnostics.Debug.WriteLine(ex)
End Try
End Sub

That's all... Just drop an image on your form and the icon will be created.

Copy a complete directory with progress bar

Some months ago I published an article explaining how to copy a file with a progressbar in VB.NET. I would like to thank you all for the great feedback on that article! Some days ago I received a mail with the question how to copy a whole directorystructure while showing the progress. So here's a possible solution. Please have a look at the original article first (http://khsw.blogspot.com/2005/08/copy-file-with-progressbar-in-vbnet.html).

The necessary API functions:
Private Delegate Function CopyProgressRoutine(ByVal totalFileSize As Int64, ByVal totalBytesTransferred As Int64, ByVal streamSize As Int64, ByVal streamBytesTransferred As Int64, ByVal dwStreamNumber As Int32, ByVal dwCallbackReason As Int32, ByVal hSourceFile As Int32, ByVal hDestinationFile As Int32, ByVal lpData As Int32) As Int32

Private Declare Auto Function CopyFileEx Lib "kernel32.dll" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal lpProgressRoutine As CopyProgressRoutine, ByVal lpData As Int32, ByVal lpBool As Int32, ByVal dwCopyFlags As Int32) As Int32


Here we declare some private variables. _totalFileSize will hold the total size of all files, _totalBytesCopied will contain the number of bytes that has been copied in the complete process.
Private _totalFileSize As Long = 0
Private _totalBytesCopied As Long = 0
Private _copyProgressRoutine As CopyProgressRoutine
Private Const ROOTFOLDER As String = "C:\Program Files\Common Files"
Private Const DESTFOLDER As String = "C:\Temp2"

The Click event of the button has been changed. First it will count the total size of all files in the rootfolder and its subfolders. After that, the recursive function CopyFiles will be called.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
GetTotalFileSize(New System.IO.DirectoryInfo(ROOTFOLDER))
_copyProgressRoutine = New CopyProgressRoutine(AddressOf CopyProgress)
CopyFiles(New System.IO.DirectoryInfo(ROOTFOLDER), DESTFOLDER)
End Sub

The CopyProgress function has been changed. The totalBytesTransferred of the current file will be added to the total amount of bytes already copied. The value of the progressbar will be calculated by adding the copied bytes of the current file to the number of bytes transferred by copying the previous files. This sum will be divided by the number of bytes that has to copied in total.
Private Function CopyProgress(ByVal totalFileSize As Int64, ByVal totalBytesTransferred As Int64, ByVal streamSize As Int64, ByVal streamBytesTransferred As Int64, ByVal dwStreamNumber As Int32, ByVal dwCallbackReason As Int32, ByVal hSourceFile As Int32, ByVal hDestinationFile As Int32, ByVal lpData As Int32) As Int32
ProgressBar1.Value = Convert.ToInt32((_totalBytesCopied + totalBytesTransferred) / _totalFileSize * 100)
Application.DoEvents()
End Function

The recursive function GetTotalFileSize will calculate the size of all files within the given folder and it's subfolders.
Private Sub GetTotalFileSize(ByVal folder As System.IO.DirectoryInfo)
For Each fi As System.IO.FileInfo In folder.GetFiles
_totalFileSize += fi.Length
Next
For Each di As System.IO.DirectoryInfo In folder.GetDirectories
GetTotalFileSize(di)
Next
End Sub

The recursive function CopyFiles will copy all files of the given folder and it's subfolders to a new destination. It the destionation (sub)folder does not exists, it will be created. After calling the CopyFileEx function the file size of the copied file will be added to _totalFileSize.
Private Sub CopyFiles(ByVal folder As System.IO.DirectoryInfo, ByVal destinationFolder As String)
If Not System.IO.Directory.Exists(destinationFolder) Then
System.IO.Directory.CreateDirectory(destinationFolder)
End If
For Each fi As System.IO.FileInfo In folder.GetFiles
CopyFileEx(fi.FullName, destinationFolder & "\" & fi.Name, _copyProgressRoutine, 0, 0, 0)
_totalBytesCopied += fi.Length
Next
For Each di As System.IO.DirectoryInfo In folder.GetDirectories
CopyFiles(di, di.FullName.Replace(ROOTFOLDER, DESTFOLDER))
Next
End Sub


 
Stefanie Worm is het liefste vrouwtje van de wereld.
Melina is de liefste schatsie van de wereld (Erik De Maeyer).