|
-
Sep 26th, 2000, 08:38 AM
#1
Thread Starter
Addicted Member
Hi all !
I found here how to show a icon in the windows tray. It works great when I use pre-existing icons. When I try to creat my own stuff, I get nothing (just a space reserved for my icon I guess...)
What are the requirements for icons to be recognized and display properly ?
(I use the 'Shell_NotifyIconA' API... just in case there are other methods...)
Thanks !
-
Sep 26th, 2000, 09:07 AM
#2
_______
"A myth is not the succession of individual images,
but an integerated meaningful entity,
reflecting a distinct aspect of the real world."
___ Adolf Jensen
-
Sep 26th, 2000, 09:08 AM
#3
Guru
Here's a fake-form-which-is-actually-just-an-object example I found lying around my HD. 
Create a form, call it frmTray...
IMPORTANT: Change its ScaleMode property to 3 - Pixel!!!
Set its Icon property to the icon you want in the tray, and its Caption property to the ToolTip you want...
And paste this code in it:
Code:
Option Explicit
Private Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
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
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
Private Const WM_MOUSEMOVE = &H200
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202
Private Const WM_LBUTTONDBLCLK = &H203
Private Const WM_RBUTTONDOWN = &H204
Private Const WM_RBUTTONUP = &H205
Private Const WM_RBUTTONDBLCLK = &H206
Private Const WM_MBUTTONDOWN = &H207
Private Const WM_MBUTTONUP = &H208
Private Const WM_MBUTTONDBLCLK = &H209
Dim NID As NOTIFYICONDATA
Public Sub CreateIcon()
With NID
.cbSize = Len(NID)
.hWnd = hWnd
.uCallbackMessage = WM_MOUSEMOVE
.uID = 1
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.szTip = Left(Caption, 63) & vbNullChar
.hIcon = Icon
End With
Call Shell_NotifyIcon(NIM_ADD, NID)
End Sub
Public Sub ModifyIcon()
NID.szTip = Left(Caption, 63) & vbNullChar
NID.hIcon = Icon
Call Shell_NotifyIcon(NIM_MODIFY, NID)
End Sub
Public Sub DeleteIcon()
Call Shell_NotifyIcon(NIM_DELETE, NID)
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Select Case X
Case WM_MOUSEMOVE
' TrayIcon_MouseMove code here
' This means... The cursor moved over the tray icon
Case WM_LBUTTONDOWN
' TrayIcon_LeftButtonDown code here
Case WM_LBUTTONUP
' TrayIcon_LeftButtonUp code here
' This means... The tray icon was clicked
Case WM_LBUTTONDBLCLK
' TrayIcon_LeftButtonDoubleClick code here
Case WM_RBUTTONDOWN
' TrayIcon_RightButtonDown code here
Case WM_RBUTTONUP
' TrayIcon_RightButtonUp code here
' This means... The tray icon was right-clicked - put some PopupMenu call here
Case WM_RBUTTONDBLCLK
' TrayIcon_RightButtonDoubleClick code here
Case WM_MBUTTONDOWN
' TrayIcon_MiddleButtonDown code here
Case WM_MBUTTONUP
' TrayIcon_MiddleButtonUp code here
Case WM_MBUTTONDBLCLK
' TrayIcon_MiddleButtonDoubleClick code here
End Select
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call DeleteIcon
End Sub
Remember, this is a fake form - it is actually a simple class, but it needs a valid hWnd so the easiest thing to do is put it in a form.
Now, in your real form... First of all, you must load the frmTray class when the real form loads.
Code:
Private Sub Form_Load()
Call Load(frmTray)
Now, if you didn't set the Icon and the Caption properties of the frmTray class in design time...
Code:
frmTray.Caption = "ToolTipText for the tray icon goes here... Max of 63 characters"
Set frmTray.Icon = picSomePictureBoxWithAnIconInIt.Picture
Then, create the icon in the tray.
Code:
Call frmTray.CreateIcon
End Sub
When the form unloads, you must destroy the frmTray class.
Code:
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call Unload(frmTray)
Set frmTray = Nothing
End Sub
If at any point of the program (other than unloading), you wish to remove the icon from the tray:
Code:
Call frmTray.DeleteIcon
You may then use the CreateIcon method again when you want the icon to reappear. The CreateIcon method will use frmTray's properties Icon and Caption to create the icon.
If you want to change the ToolTipText, or the icon, or both, without deleting-and-recreating-the-current-icon:
Code:
frmTray.Caption = "New ToolTipText, old limit of 63 characters"
Set frmTray.Icon = picNewIcon.Picture
' The following line must be used for the changes to take effect
Call frmTray.ModifyIcon
To capture events in the tray icon (such as Click, MouseMove, etc.)... See the comments in the MouseMove event of the frmTray class.
If none of the events work:
Change frmTray's ScaleMode property to 3 - Pixel!!!
Enjoy! 
And, by the way, I'll take this opportunity to warn people against the conspiracy...
The declaration of Shell_NotifyIcon in the API viewer is incorrect.
API viewer declaration:
Code:
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
See the space in the beginning of the Alias?
It should not exist, and it does not work with the space, because then it looks for the function name with the space in the shell32.dll file.
The correct declaration is the same, but without the space.
Code:
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Don't sue anybody for that.
-
Sep 26th, 2000, 10:20 AM
#4
Thread Starter
Addicted Member
Thanks !
It helped a lot... now I have another problem. I set it up so that I have a menu popup when I right-mouse-click. It works but the menu never disapears unless I select something off of it. (I would like the menu to go away if I go to another application for instance...)
How do I do this ?
-
Sep 26th, 2000, 10:48 AM
#5
Guru
I think the problem occurs because the tray-icon event-handling routine is in the form's WM_MOUSEMOVE message.
It should be in a WM_USER + n message.
The WM_MOUSEMOVE message is selected as a VB trick to avoid subclassing.
If you really really really really really want to fix the problem, you could try to add subclassing!
-
Sep 26th, 2000, 10:57 AM
#6
Thread Starter
Addicted Member
Well, I'll probably stick to that.... or first learn what subclassing really is... haha
Thanks anyway !
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|