Karl Moore presents more secrets for Visual Basic programmers. Learn how to check for a previous instance in .NET, how to convert RichTextBox to HTML, how to support dragging-and-dropping from Windows Explorer, and the exact code you need to capture the screen, quickly and easily.
Introduction
Welcome to the second article in the .NET secrets series!
I'm Karl Moore and, once again, you're reading another bundle of secrets I've adapted from my soon-to-be-released book, VB .NET and ASP.NET Secrets.
This week, I'm continuing to look at Windows application secrets. Today, we'll figure:
- The .NET method of checking for a previous instance
- How to convert the contents of a RichTextBox control to HTML
- What you need to do to support dragging-and-dropping from Windows Explorer
- The exact code you need to capture the screen, quickly and easily
Got any .NET tips and tricks of your own? I'd love to hear about them and possibly formulate them into this series (with full credit given, naturally!). Drop me a line—karl@karlmoore.com.
But without further ado... the secrets!
The .NET Way of Checking for Previous Instances
There are times when it's useful to check whether another instance of your application is running. For example, when starting up your program, you may want to check whether another version is already running in the background and, if it is, give that instance the focus.
In Visual Basic 6, you had the App.PrevInstance property to do this. In VB.NET, we need to check whether the current process is running more than once. That's what our code does here, encapsulated in the PrevInstance function. It returns a True if your application is already running on the same machine:
Public Function PrevInstance() As Boolean
If Diagnostics.Process.GetProcessesByName _
(Diagnostics.Process.GetCurrentProcess.ProcessName) _
.Length > 1 Then
Return True
Else
Return False
End If
End Function
You might use this code as so:
If PrevInstance() = True Then
' Get all previous instances
Dim Processes() As Process
Processes = _
Diagnostics.Process.GetProcessesByName( _
Diagnostics.Process.GetCurrentProcess.ProcessName)
' Activate the first instance
AppActivate(Processes(0).Id)
' Exit the current instance
Application.Exit()
End If
Top Tip: There's a little bug you may run into when using this code that turns the hair of most developers a funny shade of gray. If your application name is greater than fifteen characters, and running on either Windows NT or 2000, your code won't be able to tell whether a previous instance is running. Weird, but true. Solution: upgrade to XP or higher, or change your application name (Project > Properties).
Converting RTF to HTML
One amazingly common developer request is a method of converting the contents of a RichTextBox control to HTML. But, unless you're willing to spend hundreds on a third-party text editing control, you're out of luck. Even in VB.NET, Microsoft has chosen to remain ignorant to this much desired feature.
So, you need to do it yourself—and the following chunk of code I've put together should get you started. Just pass it a RichTextBox control as a parameter and it'll return a string of HTML, ready for you to perhaps save to a file.
It doesn't handle more complicated features, such as images or tables; however, it will easily cope with fonts, sizes, colors, bold, italic, and paragraphs. Of course, you're more than welcome to expand it to suit your needs exactly.
You can call this code, as so:
strHTML = ConvertToHtml(RichTextBox1)
And here's the actual ConvertToHTML function:
Public Function ConvertToHTML(ByVal Box As RichTextBox) _
As String
' Takes a RichTextBox control and returns a
' simple HTML-formatted version of its contents
Dim strHTML As String
Dim strColour As String
Dim blnBold As Boolean
Dim blnItalic As Boolean
Dim strFont As String
Dim shtSize As Short
Dim lngOriginalStart As Long
Dim lngOriginalLength As Long
Dim intCount As Integer
' If nothing in the box, exit
If Box.Text.Length = 0 Then Exit Function
' Store original selections, then select first character
lngOriginalStart = 0
lngOriginalLength = Box.TextLength
Box.Select(0, 1)
' Add HTML header
strHTML = "<html>"
' Set up initial parameters
strColour = Box.SelectionColor.ToKnownColor.ToString
blnBold = Box.SelectionFont.Bold
blnItalic = Box.SelectionFont.Italic
strFont = Box.SelectionFont.FontFamily.Name
shtSize = Box.SelectionFont.Size
' Include first 'style' parameters in the HTML
strHTML += "<span style=""font-family: " & strFont & _
"; font-size: " & shtSize & "pt; color: " _
& strColour & """>"
' Include bold tag, if required
If blnBold = True Then
strHTML += "<b>"
End If
' Include italic tag, if required
If blnItalic = True Then
strHTML += "<i>"
End If
' Finally, add our first character
strHTML += Box.Text.Substring(0, 1)
' Loop around all remaining characters
For intCount = 2 To Box.Text.Length
' Select current character
Box.Select(intCount - 1, 1)
' If this is a line break, add HTML tag
If Box.Text.Substring(intCount - 1, 1) = _
Convert.ToChar(10) Then
strHTML += "<br>"
End If
' Check/implement any changes in style
If Box.SelectionColor.ToKnownColor.ToString <> _
strColour _ Or Box.SelectionFont.FontFamily.Name _
<> strFont Or _ Box.SelectionFont.Size <> shtSize _
Then
strHTML += "</span><span style=""font-family: " _
& Box.SelectionFont.FontFamily.Name & _
"; font-size: " & Box.SelectionFont.Size & _
"pt; color: " & _
Box.SelectionColor.ToKnownColor.ToString & """>"
End If
' Check for bold changes
If Box.SelectionFont.Bold <> blnBold Then
If Box.SelectionFont.Bold = False Then
strHTML += "</b>"
Else
strHTML += "<b>"
End If
End If
' Check for italic changes
If Box.SelectionFont.Italic <> blnItalic Then
If Box.SelectionFont.Italic = False Then
strHTML += "</i>"
Else
strHTML += "<i>"
End If
End If
' Add the actual character
strHTML += Mid(Box.Text, intCount, 1)
' Update variables with current style
strColour = Box.SelectionColor.ToKnownColor.ToString
blnBold = Box.SelectionFont.Bold
blnItalic = Box.SelectionFont.Italic
strFont = Box.SelectionFont.FontFamily.Name
shtSize = Box.SelectionFont.Size
Next
' Close off any open bold/italic tags
If blnBold = True Then strHTML += ""
If blnItalic = True Then strHTML += ""
' Terminate outstanding HTML tags
strHTML += "</span></html>"
' Restore original RichTextBox selection
Box.Select(lngOriginalStart, lngOriginalLength)
' Return HTML
Return strHTML
End Function
Top Tip: Looking to turn HTML back into text? Check out my "Converting HTML to Text, Easily" tip in the "More .NET Secrets" chapter of my book, VB.NET and ASP.NET Secrets for a ready-to-run algorithm.

Our code doing its stuff: translating RTF into HTML
Drag and Drop from Windows Explorer
Dragging and dropping within your application is pretty simple stuff. Simply set a couple of properties and you're rocking: look up 'drag and drop, Windows Forms' in the Help Index for more information. But what if you want to drag and drop from another application, such as Windows Explorer?
One of the most commonly requested, yet infrequently answered Windows form questions is, "How can I let my users drag and drop files and folders directly into my applications?". Simple, just follow these three easy steps:
- Change the AllowDrop property of the control you want users to drop the files onto to True. This could be a ListBox control, a Panel control, or even your form itself.
- Add code to the DragOver event of the control, so the typical 'copy' icon is displayed when files are dragged over:
' As dragged over, check data is file drop
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
' Display the copy (or other) icon
e.Effect = DragDropEffects.Copy
End If
- Finally, add code to the DragDrop event of the control, to receive and process information about the dropped files:
' Check this is a file drop
If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then
' Retrieve list of files and loop through string array
Dim strFiles() As String = e.Data.GetData( _
DataFormats.FileDrop)
Dim intCount As Integer
For intCount = 0 To strFiles.Length
MessageBox.Show(strFiles(intCount))
Next
End If
And that's it! In three simple steps, your application is ready to interoperate with Windows Explorer or any other application supporting the standard Windows file drag and drop routines.
Of course, here we're simply displaying the dropped files or folders in a message box here; however, you could be doing something much more exciting: generating an MP3 play list; processing special work files; loading documents into your own mini word processor. The possibilities are endless.

Click here for a larger image.
Dragging and dropping from Windows Explorer
Capturing the Screen, Quick and Easy
When it comes to showing people how to capture the screen, most VB.NET authors I've seen tend to revert to the old-school method of working: using the API. There is, however, a better way.
The following function is called GetScreenCapture and returns an Image object. It captures the screen by running a series of "Print Screen" key presses, which puts a screen grab on the Clipboard, ready for my nifty little function to devour and return. My function accepts a FullScreen argument, too: Pass True to capture the whole screen, or False to capture just the active window.
Here's the code:
Public Function GetScreenCapture( _
Optional ByVal FullScreen As Boolean = False) As Image
' Captures the current screen and returns as an Image
' object
Dim objSK As SendKeys
Dim imgCapture As Image
If FullScreen = True Then
' Print Screen pressed twice here as some systems
' grab active window "accidentally" on first run
objSK.SendWait("{PRTSC 2}")
Else
objSK.SendWait("%{PRTSC}")
End If
Dim objData As IDataObject = Clipboard.GetDataObject()
Return objData.GetData(DataFormats.Bitmap)
End Function
And here are a couple of examples demonstrating how to use that Image object—firstly, saving it as a file; and secondly, using it to set the Image property of a PictureBox control:
GetScreenCapture(True).Save("c:\screengrab.bmp")
PictureBox1.Image = GetScreenCapture()

My sample application, capturing the active window (again and again)
Next Time
Coming up in part three of Windows Secrets, check out:
- How to 'Reset' a Form
- The Facts on Visual Inheritance
- Secrets of Working with the System Tray
- Best of All Worlds: Creating an Ultra-Thin Client
See you next time!
# # #