One of my customers is reporting a problem with Win XP Pro as follows.
The application uses a taskbar tray icon, and because it is a service application there is an option for the application to hide itself (i.e. not show a user interface). The user can always open the application by clicking on the icon in the tray.
This works perfectly in Windows 2000. But in XP when the application hides itself it also apparently causes the tray icon to disappear - so the user has no means of being able to access the application!
I would welcome suggestions on how I might go about fixing this problem. I'm not very enamoured with Microsoft for having changed such fundamental behaviour, assuming it is an XP problem.
Andrew
in the control panel look at the "Taskbar and Start Menu" applet. there is a checkbox called "Hide inactive icons". Try unchecking that box and see if that helps.
--don
I just heard back from the customer - he's already discovered that option and apparently it makes no difference.
Andrew
I use tray icons all the time in XP Pro with no problems. Is there an icon to begin with? And, is the icon really not there or is it just the wrong type of icon where it reserves a spot for it but it is blank and they think it is gone...I had that happen before too.
The icon is there alright, but when the user minimizes the main dialog (or the auto-hide option is set) I intercept the SC_MINIMIZE event and replace it with a call to SHOWWINDOW hWndForm, %SW_HIDE.
At some later point in time the user is supposed to be able to click on the tray icon for the application, where I issue a %SW_SHOWNORMAL instruction.
But at the time the %SW_HIDE is issued the tray icon is also hidden from sight, leaving the user with no means of being able to bring the application out of peekaboo mode.
Blasted XP. Heaven help us when Longhorn hits the streets.
Andrew
Fixed it.
I reviewed the subject on the PowerBASIC web site and noticed in an example that when an application was hidden the author immediately added the icon again to the tray. I wasn't doing that before - I was setting the icon as the program started up, and clearing it on close down.
I released an update to the customer and have just been advised that the problem is cured.
Subtlely different behaviour between Windows 2000 and Windows XP.
Andrew
I've seen a few apps sometimes having two icons in the systray (XP), might your/this solution trigger this 'problem' instead? Once the mouse is moved over these duplicates, one normally disappears though.
You shouldn't need to add it again. I add my icon at the start of my WebServer App and don't remove it till it exits. Which message do you remove it in, and are you sure you are loading the icon right and have the right type of icon there?
Things nobody tells anyone about Tray Icons:
1. They need to be a single 16x16 and 16 color icon...no other icons in the ico file that are different sizes or color depths.
2. DON'T delete the icon/icon handle once it is given to the Tray. In fact you never need to delete them or their handles and I even use LoadImage with %LR_SHARED.
And opposite the Win Help, are you returning true so the minimize you override isn't further processed?
P.S. Haakon, the double icons are just from crashes when the app doesn't remove the icon. Windows sees the app is gone though when you hover over it and there is no window to handle the message so removes it. But, yes his solution could make 2 icons.
Some code you may find useful:
%WM_TRAYICON = %WM_USER + 500
%WM_SYSHIDE = %WM_USER + 512 '(wParam And &HFFF0) means last hex digit=0
Global ti As NOTIFYICONDATA 'Tray Icon
Global trayMenu As Dword 'Tray Menu Handle
Function FORMNAME_WM_CREATE (hWndForm As Dword) As Long
Local lngSystemMenu As Long 'Handle to System Menu in titlebar
Local mi As MENUITEMINFO
Local tempsz As Asciiz * 6
mi.cbSize=SizeOf(mi)
mi.fMask= %MIIM_TYPE Or %MIIM_STATE Or %MIIM_ID
mi.fType= %MF_STRING
mi.wID= %WM_SYSHIDE
tempsz= "&Hide"
mi.dwTypeData= VarPtr(tempsz)
lngSystemMenu = GetSystemMenu(HWND_FORMNAME, 0)
RemoveMenu lngSystemMenu, %SC_SIZE, %MF_BYCOMMAND 'no resize
RemoveMenu lngSystemMenu, %SC_RESTORE, %MF_BYCOMMAND 'no restore
RemoveMenu lngSystemMenu, %SC_MINIMIZE, %MF_BYCOMMAND 'no minimize
RemoveMenu lngSystemMenu, %SC_MAXIMIZE, %MF_BYCOMMAND 'no maximize
InsertMenuItem(lngSystemMenu, 0, %TRUE, mi)
ti.cbSize = SizeOf(ti)
ti.hWnd = HWND_FORMNAME
ti.uID = App.hInstance
ti.uFlags = %NIF_ICON Or %NIF_MESSAGE Or %NIF_TIP
ti.uCallbackMessage = %WM_TRAYICON
ti.hIcon = LoadImage(App.hInstance, "ICON_NAME", %IMAGE_ICON, 16, 16, %LR_SHARED)
ti.szTip = "Your Text Here"
Shell_NotifyIcon %NIM_ADD, ti
trayMenu= CreatePopupMenu()
'Add items to Tray Menu
'I just reuse the mi structure from above
End Function
Function FORMNAME_WM_DESTROY (hWndForm As Dword) As Long
Shell_NotifyIcon %NIM_DELETE, ti 'remove tray icon
DestroyMenu(trayMenu) 'cleanup tray menu handle
End Function
Function FORMNAME_CUSTOM (hWndForm As Dword, wMsg As Long, wParam As Dword, lParam As Long) As Long
Local Pt As POINTAPI 'Mouse location for tray menu
Local prevWindow As Dword
Select Case wMsg
Case %WM_TRAYICON
Select Case LoWrd(lParam)
Case %WM_LBUTTONUP
If IsWindowVisible(HWND_FORMNAME)= 0 Then
ShowWindow HWND_FORMNAME, %SW_SHOW
End If
SetForegroundWindow(HWND_FORMNAME)
Case %WM_RBUTTONUP
GetCursorPos Pt
prevWindow= GetNextWindow(HWND_FORMNAME, %GW_HWNDNEXT)
SetForegroundWindow(HWND_FORMNAME)
SetWindowPos(HWND_FORMNAME, prevWindow, 0, 0, 0, 0, %SWP_NOSIZE Or %SWP_NOMOVE Or %SWP_NOACTIVATE)
SetFocus(0) 'Block Keystrokes to Window
TrackPopupMenu(trayMenu, %TPM_RIGHTALIGN Or %TPM_LEFTBUTTON Or %TPM_RIGHTBUTTON, Pt.x, Pt.y, 0, HWND_FORMNAME, ByVal 0)
PostMessage(HWND_FORMNAME, %WM_NULL, 0, 0)
End Select
Function= %TRUE
Case %WM_SYSCOMMAND
If (wParam And &HFFF0)= %WM_SYSHIDE Then
ShowWindow HWND_FORMNAME, %SW_HIDE 'hide app so it doesn't appear in the task bar.
Function= %FALSE
End If
Case %WM_NCRBUTTONUP ' Right Click Close Button
If wParam= %HTCLOSE Then
ShowWindow HWND_FORMNAME, %SW_HIDE 'hide app so it doesn't appear in the task bar.
Function = %TRUE
End If
End Select
End Function
Thanks for providing that example, Roger. Just what I was looking for. :D
Knuth