編寫托盤程式主要解決兩個問題:
(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 = &H2
Public Const NIF_MESSAGE = &H1
Public Const NIF_TIP = &H4
Public Const NIM_ADD = &H0
Public Const NIM_DELETE = &H2
Public Const NIM_MODIFY = &H1
'Shell_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()
'將程式勾入訊息環中
'利用AddressOf取得訊息處理函數WindowProc的指標,並將其傳給SetWindowLong
'lpPrevWndProc用來儲存原視窗的指標
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub Unhook()
'將程式從訊息環退出。用原視窗的指標替換WindowProc函數的指標,即關閉子類、退 出訊息迴圈
Dim temp As Long
temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub
2、在視窗form1加入一個主菜單mainmenu,設定為不可見。在加入一些子功能表如" 顯示視窗"(名稱為:show),"隱藏視窗"(名稱為:hide),'退出程式"(名稱為:exit)。 在加入四個按鈕Command1,Command2,Command3,Command。caption屬性分別為:"刪除托 盤表徵圖","建立托盤表徵圖","修改托盤表徵圖","退出程式".
代碼視窗的內容為:
Dim MyNot As NOTIFYICONDATA '定義一個托盤結構
Private Sub Command1_Click()
'按下刪除托盤表徵圖按鈕
With MyNot
.hIcon = Form1.Icon '托盤表徵圖指標指向視窗的表徵圖
.hwnd = Form1.hwnd '表單指標
.szTip = "" '彈出提示字串,刪除時應為空白
.uCallbackMessage = WM_USER + 100 '對應程式定義的訊息
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE '表徵圖標誌
.uID = 1 '表徵圖識別符
.cbSize = Len(MyNot) '計算結構執行個體MyNot的長度
End With
hh = Shell_NotifyIcon(NIM_DELETE, MyNot) '刪除該托盤表徵圖
trayflag = False '托盤表徵圖刪除後trayflag為假
End Sub
Private Sub Command2_Click() '按下建立托盤表徵圖按鈕
Dim hh As Long
With MyNot
.hIcon = Form1.Icon
.hwnd = Form1.hwnd
.szTip = "托盤表徵圖" & Chr(&H0)
.uCallbackMessage = WM_USER + 100
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uID = 1
.cbSize = Len(MyNot)
End With
hh = Shell_NotifyIcon(NIM_ADD, MyNot) '添加一個托盤表徵圖
trayflag = True '托盤表徵圖添加後trayflag為真
End Sub
Private Sub Command3_Click() '按下修改托盤表徵圖按鈕
Dim hh As Long
Set P = LoadPicture("cd.ico") '匯入一個新表徵圖
With MyNot
.hIcon = P '將托盤表徵圖改為新表徵圖
.hwnd = Form1.hwnd
.szTip = "光碟片表徵圖" & Chr(&H0) '變更提示資訊
.uCallbackMessage = WM_USER + 100
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uID = 1
.cbSize = Len(MyNot)
End With
hh = Shell_NotifyIcon(NIM_MODIFY, MyNot) '修改托盤表徵圖的某些特徵
End Sub
Private Sub Command4_Click() '退出視窗按鈕被按下
If trayflag = True Then Command1_Click '如果托盤表徵圖仍在,類比按下"刪 除托盤表徵圖"按鈕
Unhook '退出訊息迴圈
Unload Me '卸載表單
End Sub
Private Sub exit_Click()
If trayflag = True Then Command1_Click '如果托盤表徵圖仍在,類比按下"刪除托 盤表徵圖"按鈕
Unhook '退出訊息迴圈
Unload Me '卸載表單
End Sub
Private Sub Form_Load()
gHW = Me.hwnd '取得本表單指標
hook '調用鉤子函數,將自製訊息處理函數鉤入Windows的訊息迴圈
End Sub
Private Sub hide_Click()
Form1.hide '隱藏視窗
End Sub
Private Sub show_Click()
Form1.show 顯示視窗
End Sub
在VB中編譯這個程式,點擊建立托盤表徵圖。則在工作列的右下角出現在一表徵圖。 將滑鼠放在此表徵圖上,則顯示一條資訊。點擊右鍵,快顯功能表,可以選擇相應的功能執 行的。當視窗隱藏時雙擊托盤表徵圖可顯示視窗。注意:在VB中使用函數指標將使程式變 得脆弱,在運用與其相關的函數及關鍵字時要多加小心。