在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 = &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()