在WINDOWS裡,右下角有許多應用程序的圖標。而程序本身的窗口是隱藏的,若你需要調用應用程序的窗口,則雙擊該圖標即可。這種程序稱為托盤程序。這是WINDOWS98操作系統的一大特色。使用戶能夠更加快捷的顯示和隱藏應用程序,可以使任務欄不致於太亂。托盤程序在Visual Basic裡是怎麼實現的呢?
編寫托盤程序主要解決兩個問題:
(1)創建、修改、刪除托盤;
(2)如何對托 盤接收到的消息進行處理。
這就要用到幾個Windows API函數。
首先,Shell_NotifyIcon是用於托盤的Shell API。該API用到一個NOTIFYICONDATA結構.
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其次,應該考慮怎樣在VB中接收、處理托盤的消息(雙擊、單擊、左鍵、右 鍵)。C++、Delphi等語言對消息循環的處理較簡單,但在VB中處理消息循環時必須應用Win32的SetWindowLong、CallWindowProc這兩個API函數。SetWindowLong函數利用 GWL_WNDPROC 索引來創建窗口類的子類(窗口類是用來創建窗口的),它使用AddressOf關鍵字和回調函數(WindowProc)來截取消息並根據消息來執行相應的功能,如窗口的最大化、最小化、隱藏、退出等。CallWindowProc函數調用原窗口類缺省的指針,程序最後退出時可通過SetWindowLong來關閉子類,重新使原來的Windows過程成為回調函數。
本程序項目包括一個模塊和一個窗體
1、模塊源代碼為:
Option Explicit 強制定義每個使用的變量
Type NOTIFYICONDATA 定義結構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以下為 Shell_NotifyIcon將用到的常量
Public Const NIF_ICON = &H r> Public Const NIF_MESSAGE = &H1
Public Const NIF_TIP = &H4
Public Const NIM_ADD = &H0
Public Const NIM_DELETE = &H2
Public Const NIM_MODIFY = &H1Shell_NotifyIcon的函數聲明
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
處理消息將用到的結構、常量、API聲明
Type POINTAPI
x As Long
y As Long
End Type
Type Msg
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
Public Const WM_USER = &H400
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_LBUTTONDBLCLK = &H203
Public Const GWL_WNDPROC = -4
Public trayflag As Boolean 定義托盤圖標是否在桌面上
Global lpPrevWndProc As Long
Global gHW As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long以下過程為消息循環處理
Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If hw = Form1.hwnd And uMsg = WM_USER+100 Then檢測到鼠標點動托盤圖標
Select Case lParam
Case WM_RBUTTONDOWN 鼠標右鍵按下
Form1.PopupMenu Form1.mainmenu 彈出菜單
Case WM_LBUTTONDBLCLK 鼠標左鍵雙擊
Form1.Show 顯示窗口
Case Else
End Select
Else 調用缺省窗口指針
WindowProc = CallWindowProc(lpPrevWndProc, hw,uMsg, wParam, lParam)
End If
End Function
Public Sub hook()