Monday, May 30, 2005

vbcity: vb6 system tray

vbCity/DevCity.NET Forums :: FAQ :: Visual Basic :: VB General :: Windows:

Option Explicit

'User-defined variable to pass to the Shell_NotiyIcon function
Private Type NOTIFYICONDATA
cbSize As Long
hWnd As Long
uId As Long
uFlags As Long
uCallBackMessage As Long
hIcon As Long
szTip As String * 64
End Type

'Constants for the Shell_NotifyIcon function
Private Const NIM_ADD = &H0
Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2

Private Const WM_MOUSEMOVE = &H200

Private Const NIF_MESSAGE = &H1
Private Const NIF_ICON = &H2
Private Const NIF_TIP = &H4

Private Const WM_LBUTTONDBLCLK = &H203
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202
Private Const WM_RBUTTONDBLCLK = &H206
Private Const WM_RBUTTONDOWN = &H204
Private Const WM_RBUTTONUP = &H205

'Declare the API function call
Private Declare Function Shell_NotifyIcon Lib "shell32" Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean

Dim nid As NOTIFYICONDATA


Step two: Create add icon procedure
In this step, we're creating the add icon procedure as a separate procedure so that we can:


* Specify a tooltip on-the-fly
* Call the add icon procedure from where ever we choose


Important points to note are the hWnd property, the uCallBackMessage property and the hIcon property.
The hWnd property links the icon to a specific form - where this procedure in a module the code would need to be changed to reference an actual form (Me keyword only works in forms as a reference to the form that the code in contained in).
The uCallBackMessage property lets the system know when the mouse moves over the icon start checking for interaction - I never really played with this to see what else could be done, but there are possibly other ways of checkingfor interaction.
The hIcon property provides a means to change the icon on the system tray at runtime, but the previous icon must be removed to show the new one.

Code:
Public Sub AddIcon(ByVal ToolTip As String)

On Error GoTo ErrorHandler

'Add icon to system tray
With nid
.cbSize = Len(nid)
.hWnd = Me.hWnd
.uId = vbNull
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uCallBackMessage = WM_MOUSEMOVE
.hIcon = Me.Icon
.szTip = ToolTip & vbNullChar
End With
Call Shell_NotifyIcon(NIM_ADD, nid)

Exit Sub
ErrorHandler: 'Display error message
Screen.MousePointer = vbDefault
MsgBox Err.Description, vbInformation, App.ProductName & " - " & Me.Caption

End Sub


Step three: Add code to add icon and remove icon from the system tray
Very straight-forward. Because we've created an add icon procedure, it's one line to add the icon (and modify the tooltip) and one line to remove it.

Code:
Private Sub Form_Load()

Call AddIcon("This would be a tooltip...")

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

'Remove icon from system tray
Call Shell_NotifyIcon(NIM_DELETE, nid)

End Sub


Step four: Interact with system tray icon
The real magic begins! Below I've a select case to check what the user does on the icon - here we see that if the user releases the left mouse button over the icon, the form is either minimised and hidden or restored and shown depending on the current windowstate.
Why hide or show the form?
Hiding the form removes the icon on the taskbar (between start button on left and Clock on right) so that only the system tray icon is visible.

Code:
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim msg As Long

On Error GoTo ErrorHandler

'Respond to user interaction
msg = X / Screen.TwipsPerPixelX
Select Case msg

Case WM_LBUTTONDBLCLK
'nothing

Case WM_LBUTTONDOWN
'nothing

Case WM_LBUTTONUP
If Me.WindowState = vbMinimized Then
Me.WindowState = vbNormal
Me.Show
Else
Me.WindowState = vbMinimized
Me.Hide
End If

Case WM_RBUTTONDBLCLK
'nothing

Case WM_RBUTTONDOWN
'nothing

Case WM_RBUTTONUP
'nothing

End Select

Exit Sub
ErrorHandler: 'Display error message
Screen.MousePointer = vbDefault
MsgBox Err.Description, vbInformation, App.ProductName & " - " & Me.Caption

End Sub


Step five: Add a popup-menu
Making further use of the system tray icon is usually via a popup-menu - here's how to do that!
After creating a menu with the following structure:

File
-Option1
-Option2
----------
-Exit

I can use the popup-menu function to have the options appear where the mouse is. By adding the following code to the Form_MouseMove event. Doing so means a popup-menu appears when the user right-clicks on the system tray icon.

Code:

Case WM_RBUTTONUP
Call PopupMenu(mnuFile, vbPopupMenuRightAlign)


Step six: Interact with popup-menu
Here, if you've any experience working with menus you'll know that it's very straight-forward: depending on the index of the menu clicked, do a specific bit of code (see below).

Code:
Private Sub mnuFileArray_Click(Index As Integer)

Select Case Index
Case 0 'Option 1
MsgBox "You've clicked on option1 - good for you!", _
vbInformation, App.ProductName & Me.Caption

Case 1 'Option 2
MsgBox "You've clicked on option2 - great!", _
vbInformation, App.ProductName & Me.Caption

Case 4 'Option 1
Unload Me
End

End Select

End Sub

0 Comments:

Post a Comment

<< Home