Problem with icon in XP

Started by Anonymous, July 23, 2004, 03:34:31 PM

Previous topic - Next topic

Anonymous

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

Don Dickinson

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

Anonymous

I just heard back from the customer - he's already discovered that option and apparently it makes no difference.

Andrew

Roger Garstang

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.

Anonymous

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

Anonymous

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

Haakon Birkeland

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.

Roger Garstang

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.

Roger Garstang

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

Knuth Konrad

Thanks for providing that example, Roger. Just what I was looking for.  :D

Knuth