Delegates and VB.NET

by Hannes Du Preez
Delegates and VB.NET

Hannes du Preez explains what delegates are and how to use them to call managed and unmanaged code in VB.NET.


Welcome to my article. Today I will demonstrate what delegates are and how to use them to call managed code and unmanaged code.

Managed Code Versus Unmanaged Code

In short: managed code is code that is written in the .NET Framework with C# or VB.NET for example. Unmanaged code is code written in any language that is not .NET. This is most commonly languages such as C or C++ as they are known as low level languages that can call the Operating System's methods directly. Have a look at Managed code and unmanaged code in .NET, which explains this difference better. This brings me to my next topic: API


Have a look Wikipedia's Application programming interface for a detailed explanation of APIs


A delegate is simply a type that represents a reference to physical methods with the same parameter list and return type. OK, what does that mean in simple terms? A delegate is basically a substitute for a method with the same return type and with the same signature. We make use of a delegate when we cannot access certain threads directly (as explained in this article), or when we need to ensure that managed and unmanaged code can be executed properly.

Delegates (C# Programming Guide) at MSDN has a more detailed explanation of delegates.

In order to see how delegates work, let us do a small exercise. This exercise will simply call unmanaged methods and managed methods through the use of Delegates.

Open Visual Studio 2012 and create a new VB.NET Windows Forms project. Design your Form to resemble Figure 1.

Our Design
Figure 1 - Our Design


Add the necessary Imports :

Imports System.Text 'For StringBuilder
Imports System.Runtime.InteropServices 'For API

These Imports enable us to make use of a StringBuilder object as well as to make calls to some system APIs.

Add the necessary modular variables and APIs:

	'Delegate CallBack For EnumWindows Unmanaged API
	Public Delegate Function DelegateCallBack(ByVal hWnd As IntPtr, ByVal lParam As Int32) As Boolean
	'Delegate For Managed Code
	Public Delegate Sub StringSubDelegate(ByVal aString As String)

    Private Const BufferSize As Int32 = 100 'Limit String Builder Size

	'API to List Open Windows & Processes
	<DllImport("user32.dll")> _
    Public shared Function EnumWindows(ByVal callback As DelegateCallBack, ByVal param As Int32) As Int32
    End Function

	'API To Get External Applications' Text
	<DllImport("user32.dll")> _
    Public shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Int32) As Int32
    End Function

Theses APIs enable us to list all of the active system processes and windows. Quite powerful. Although APIs are not the topic of discussion today, you may want to delve into this more, as you will be amazed what you can achieve with them. These APIs will be called via a delegate to do their work.  I also created a delegate to be used with managed code a bit later.

See EnumWindows function and GetWindowText function at MSDN for more detail on the EnumWindows and GetWindowText APIs.

Add the Function to handle the Unmanaged code's execution:

	'Function To CAll APIs
    Public Function DisplayRunningApps(ByVal hWnd As IntPtr, ByVal lParam As Int32) As Boolean
		Dim sbStrings As New StringBuilder(BufferSize) 'To Host App Names

        If GetWindowText(hWnd, sbStrings, BufferSize) <> 0 Then 'Get Text Of Open Window

            lstDelegates.Items.Add(sbStrings.ToString()) 'Add To ListBox

        End If

        Return True

    End Function

The DisplayRunningApps function displays the captions of all active windows and adds each to a StringBuilder object, which ultimately gets added to the ListBox. Add the following code behind the button labelled "Unmanaged Delegate":

	Private Sub btnUnmanaged_Click( sender As Object,  e As EventArgs) Handles btnUnmanaged.Click
		' Unmanaged Code From API 
		EnumWindows(AddressOf DisplayRunningApps, 0)

    End Sub

Voila! You have now successfully called unmanaged code through a delegate.

Add a class inside Form 1 and give it a method to be called from Form 1:

    Public Class ClassForStringSubDelegate
        Public Sub ShowMessage(ByVal strTemp As String)
		    MessageBox.Show(strTemp ) 'Show MessageBox

        End Sub

    End Class

This small example will just show how to use a delegate to call managed code from a separate class. Now, add the following code inside the button labelled "Managed Delegate":

	Private Sub btnManaged_Click( sender As Object,  e As EventArgs) Handles btnManaged.Click
		Dim clsStringDelegate As New ClassForStringSubDelegate 'Create Instance Of Separate Class

        Dim delManaged As StringSubDelegate 'Specify Delegate

        delManaged = AddressOf clsStringDelegate.ShowMessage 'Give It Something To Do

        delManaged.Invoke("Hello") 'Do It
	End Sub

Here, I instantiate the class we created above, and make use of the Invoke method of our delegate to execute the appropriate code. This code simply produces a MessageBox that says 'Hello'.


Short and sweet.  I hope that you have benefited from this article and that you will put your knowledge of delegates to good use. Until next time, cheers!

This article was originally published on Friday Apr 18th 2014
Mobile Site | Full Site