VB4all - 100 sampli, 50 tipsow, OCX, forum i wiele innych atrakcji

Systray

W sieci krąży wiele OCXów umożliwiających umieszczenie ikonki w zasobniku systemowym (część paska narzędzi na przeciwnym końcu niż przycisk Start, tam jest m. in. zegar). Używanie ich ma wady - trzeba jej dołączać do programu, czasami licencja na ich używanie jest dosyć niejasna. Ja pokażę, jak osiągnąć ten sam efekt bez stosowania kontrolek.

 

Czynności przygotowawcze :)

Aby umieścić jakąś ikonkę w trayu, trzeba najpierw takową mieć :)) Oprócz niej potrzebny nam będzie obiekt przyjmujący komunikaty od systemu (tutaj użyłem PictureBoxa nazwanego picTrayObject). Cała nasza zabawa opierać się będzie na funkcji API Shell_NotifyIcon(). Deklarujemy więc ją (BTW: wszystko w tym tekście będzie Private):

Private Declare Function Shell_NotifyIcon Lib "shell32" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean

NOTIFYICONDATA to typ danych przechowujący informację o ikonie. Oto on:

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

Dim TrayIcon As NOTIFYICONDATA

TrayIcon to będzie nasza struktura. Będzie nam też potrzebne kilka stałych:

' dane dla struktury i funkcji Shell_NotifyIcon
Private Const NIM_ADD = &H0
Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2
Private Const NIF_MESSAGE = &H1
Private Const NIF_ICON = &H2
Private Const NIF_TIP = &H4

' komunikaty Windowsa
Private Const WM_MOUSEMOVE = &H200
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

No, to to już wszystko :))

 

Wypełniamy strukturę

Oto jak należy wypełnić strukturę NOTIFYICONDATA:

W naszym wypadku wypełniamy strukturę w sposób następujący:

With TrayIcon
.cbSize = Len(TrayIcon)
.hWnd = picTrayObject.hWnd
.uId = 1&
.uFlags = NIF_ICON Or NIF_TIP Or NI
F_MESSAGE
.ucallbackMessage = WM_MOUSEMOVE
.hIcon = Me.Icon ' ikona formularza
.szTip = "Przykład ikonki w trayu"
End With

 

Pokazywanie i ukrywanie ikony

No, wreszcie przechodzimy do części zasadniczej, czyli do zaprezentowania naszej ikony! Wywołujemy funkcję:

Shell_NotifyIcon NIM_ADD, TrayIcon

Pierwszy prametr to rodzaj operacji, w tym przypadku dodajemy ikonę do zasobnika. Drugi parametr to struktura z informacjami o ikonie.

Jeżeli nie usuniemy ikony, a zakończymy program, to system po pewnym czasie sam to zrobi. Dla bezpieczeństwa jednak róbmy to pod koniec działania programu lub w każdym inym momencie:

Shell_NotifyIcon NIM_DELETE, TrayIcon

Chcąc zmienić cos w ikonie (np. obrazek lub podpowiedź) modyfikujemy odpowiednie pole w strukturze NOTIFYICONDATA i wywołujemy funkcję:

Shell_NotifyIcon NIM_MODIFY, TrayIcon

 

Zdarzenia pochodzące od ikony

Ikonka w trayu nie jest statycznym obrazkiem, można na niego klikać. A kliknięcia trzeba wykrywac i reagować na nie. Robi się to w sposób następujący.

Zdarzenia od ikony otrzymuje obiekt, którego uchwyt podaliśmy w polu hWnd struktury NOTIFYICONDATA. W naszym przypadku jest to PictureBox picTrayObject. Otrzymanie komunikatu od ikony wywoła u niego zdarzenie MouseMove, je więc wypełnimy:

Private Sub picTrayObject_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Static bCnt As Boolean, Msg As Long ' deklarujemy potrzebne zmienne
Msg = X / Screen.TwipsPerPixelX ' "wydobywamy" numer zdarzenia

If bCnt = False Then
bCnt = True

Select Case Msg ' spr
awdzamy, które zdarzenie wystąpiło
Case WM_LBUTTONDBLCLK 'podwójne kliknięcie lewego przycisku myszki na ikonce
Case WM_LBUTTONDOWN 'lewy przycisk myszki w dół
Case WM_LBUTTONUP: 'lewy przycisk myszki w górę
Case WM_RBUTTONDBLCLK 'podwójne kliknięcie praw
ym przyciskiem na ikonce
Case WM_RBUTTONDOWN 'prawy przycisk myszy w dół
Case WM_RBUTTONUP 'prawy przycisk myszy w górę
End Select

bCnt = False
End If
End Sub

Zmiennej Msg zostaje przypisany numer zdarzenia. Następnie sprawdzamy, jakie zdarzenie wystąpiło i podejmujemy odpowiednie akcje (trzeba wypełnić instrukcje Case). bCnt to zmienna kontrolna, dba o to by nie zajmować się następnym zdarzeniem dopóki to nie zostanie obsłużone.

 

Kończymy :)

To wszystko na dziś. Jeżeli macie jakieś pytania, to piszcie.

 

Karol Kuczmarski
qkarol@go2.pl
http://www.qkarol.prv.pl
ICQ: 69629311