PreperationsCreate a new form (called PopupMessage)
Place on the form a Label, which we use to display the message. (Name: MessageLabel)
Place on the form a button, which we use so the user can close the pop up. (Name: OK_Button)
The size of the pop up form and position of the controls is up to you.
Form PropertiesSet the following form properties.
AutoSize to true
AutoSizeMode to GrowAndShrink
ControlBox to False
DoubleBuffered to True
FormBorderStyle to FixedDialog
ShowInTaskbar to False
StartPosition to Manual
The CodeAdd the follow code to the class.
vb
Public Class PopUpMessage
' These the variables used by the popup message.
Protected m_WaitFor As Double
Protected m_Cancelled As Boolean = False
Protected Finished As Date
Protected CountdownTiming_Thread As System.Threading.Thread
Protected m_ShowCountdown As Boolean = True
Public Sub New( _
ByVal Str_Title As String, _
ByVal Str_Message As String, _
ByVal WaitFor As Double, _
ByVal ShowCountDown As Boolean, _
ByVal BGCol As System.Drawing.Color, _
ByVal MessageTextBG As System.Drawing.Color, _
ByVal MessageTextColor As System.Drawing.Color, _
ByVal ButtonBG As System.Drawing.Color, _
ByVal ButtonColor As System.Drawing.Color _
)
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
' Create a new Thread, which causes the timing capabilites to run in the background
' it also prevents the popup taking over.
CountdownTiming_Thread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf Me.Timing_Thread))
' Set the thread to be in the background
CountdownTiming_Thread.IsBackground = True
' Set the variables
m_WaitFor = WaitFor
m_ShowCountdown = ShowCountDown
' Set the Popup Form Properties
With Me
.Text = Str_Title
.TopMost = True
.BackColor = BGCol
' Reposition the popup window to be in the bottom-right corner of the screen
.Left = Screen.PrimaryScreen.WorkingArea.Width - Me.Width
.Top = Screen.PrimaryScreen.WorkingArea.Bottom - Me.Height
End With
' Set the Message Label Properties
With Me.MessageLabel
.Text = Str_Message
.ForeColor = MessageTextColor
.BackColor = MessageTextBG
End With
' Set the OK Buttom Properties
With Me.OK_Button
.ForeColor = ButtonColor
.BackColor = ButtonBG
End With
' Start Thread Running
CountdownTiming_Thread.Start()
' Display the popup
Me.Show()
End Sub
Don't worry about the errors, we going to fix the now.
The Timer ThreadI know there is a timer control available in the tool bar but we're going to create our own.
vb
Private Sub Timing_Thread()
' This is the timing thread code.
' Calculate when finish time will be
Finished = Now().AddSeconds(m_WaitFor)
' So long as the finish time as not be reach, and not cancelled (Which happens when you press OK.)
While (Now < Finished) And (Cancelled() = False)
' Is the countdown time to be shown.
If ShowCountdownTimer() Then
' Update the OK button text, with the time left
SetText_ThreadSafe("OK (" & Format(Finished.Subtract(Now).Minutes, "0#") & ":" & Format(Finished.Subtract(Now).Seconds, "0#") & ")")
End If
' Put the thread to sleep for 1/10th of second, to save on CPU resources
Threading.Thread.Sleep(100)
End While
CloseWindows()
CountdownTiming_Thread.Abort()
End Sub
The OK Button Code
vb
Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
' Set the Cancel variable to True
' Which in turn, via tht other thread to cause the timing to stop and closes the popup window.
m_Cancelled = True
End Sub
That small bit a code has a big effect. In do cause it causes the timing thread to exit early, close the window and stops the thread!
The DelegatesDelegates are need because the timing thread is different to the form's thread. They helps us with send thing across to different threads.
vb
' Setup the delegates
Delegate Sub TextCallback_Delegate(ByVal [text] As String)
Delegate Function Cancelled_Delegate() As Boolean
Delegate Function ShowCountdownTimer_Delegate() As Boolean
Delegate Sub CloseWindow_Delegate()
Setting the OK Button Text
vb
Private Sub SetText_ThreadSafe(ByVal [text] As String)
' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.OK_Button.InvokeRequired Then
Dim MyDelegate As New TextCallback_Delegate(AddressOf SetText_ThreadSafe)
Me.Invoke(MyDelegate, New Object() {[text]})
Else
Me.OK_Button.Text = [text]
End If
End Sub
Getting the Cancel State
vb
Public Function Cancelled() As Boolean
' InvokeRequired required compares the thread ID of the
' calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.InvokeRequired = True Then
Dim MyDelegate As New Cancelled_Delegate(AddressOf Cancelled)
Return CBool(Me.Invoke(MyDelegate))
Else
Return Me.m_Cancelled
End If
End Function
Getting the Countdown Visibility
vb
Public Function ShowCountdownTimer() As Boolean
' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.InvokeRequired = True Then
Dim MyDelegate As New ShowCountdownTimer_Delegate(AddressOf ShowCountdownTimer)
Return CBool(Me.Invoke(MyDelegate))
Else
Return Me.m_ShowCountdown
End If
End Function
Handle the closing of the window
vb
Private Sub CloseWindows()
' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.InvokeRequired = True Then
' So it on diffent Thread, create a delegate and invoke it
Dim MyDelegate As New CloseWindow_Delegate(AddressOf CloseWindows)
Me.Invoke(MyDelegate)
Else
' On same thread, so close window
Me.Close()
End If
End Sub
End Class
Now to test it out.
In form1 add in the following code to the FormLoad Event
vb
Dim MyPopup As New PopUpMessage("Test", "Test Message", 20, True, Color.AliceBlue, Color.Aqua, Color.Black, Color.Pink, Color.Purple)
And run.
Now you have the ability to display a popup message.