[Win32] Bring Trayicon tooltip to front?
BlitzMax Forums/MaxGUI Module/[Win32] Bring Trayicon tooltip to front?
| ||
Hello all, the code below is a simple example how to set up a trayicon. ' TrayIcon Framework Maxgui.Drivers Import BRL.EventQueue Import "object.o" ' <- YOU NEED TO CHANGE THAT TO ANOTHER ICON OBJ FILE OR COMMENT IT OUT (= NO ICON) SuperStrict AppTitle = "TrayIcon Example" ?Win32 ' Tray icon related stuff Const NIM_ADD:Int = 0 Const NIM_MODIFY:Int = 1 Const NIM_DELETE:Int = 2 Const NIM_SETFOCUS:Int = 3 Const NIM_SETVERSION:Int= 4 Const NIF_MESSAGE:Int = $1 Const NIF_ICON:Int = $2 Const NIF_TIP:Int = $4 Const NIF_STATE:Int = $8 Const NIF_INFO:Int = $10 Const NIF_GUID:Int = $20 Global nid:TNotifyIconData Type TNotifyIconData Field Size:Int Field HWND:Int Field id:Int Field Flags:Int Field CallbackMessage:Int Field Icon:Int ' HICON Field Tip:Long ' array [0..63] of AnsiChar; Field Tip2:Long Field Tip3:Long Field Tip4:Long Field Tip5:Long Field Tip6:Long Field Tip7:Long Field Tip8:Long EndType Extern "win32" Function Shell_NotifyIcon:Int(message:Int, notifyicondata:Byte Ptr) = "Shell_NotifyIconA@8" End Extern ? Local FLAGS:Int FLAGS:| WINDOW_TITLEBAR FLAGS:| WINDOW_RESIZABLE FLAGS:| WINDOW_MENU FLAGS:| WINDOW_CLIENTCOORDS 'FLAGS:| WINDOW_HIDDEN FLAGS:| WINDOW_ACCEPTFILES Global MainWindow:TGadget = CreateWindow( AppTitle, 100, 100, 320, 240, Null, FLAGS ) Global TrayIconPanel:TGadget = CreatePanel(0, 0, 0, 0, MainWindow, 0 ) Global win_trayed:Int=0 Repeat WaitEvent() Print CurrentEvent.ToString() Select EventID() Case EVENT_AppSuspend ' DebugLog "App now suspended!" If WindowMinimized(Mainwindow) Then ?win32 HideGadget(MainWindow) RegisterTrayIcon(TrayIconPanel, "This is premade Tooltip!") 'show station currently on AIR! ? EndIf Case EVENT_MOUSEDOWN Select EventSource() Case TrayIconPanel If EventData()=1 Then RemoveTrayIcon() RedrawGadget(Mainwindow) ShowGadget(MainWindow) RedrawGadget (MainWindow) RestoreWindow(Mainwindow) EndIf If EventData()=2 Then ' Set a new Tooltip when you hit the right mouse button over the trayicon SetNotifyIconDataTip( nid, "I'm a reborn Tooltip! :)" ) Shell_NotifyIcon( NIM_MODIFY, nid) EndIf End Select Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE End End Select Forever ' Tray Icon Functions, Win 32 only! ---------------------------------------------------------- Function RegisterTrayIcon( window:TGadget, toolTip:String ) ' Register tray icon ?Win32 nid = New TNotifyIconData nid.Size = SizeOf(TNotifyIconData) nid.hwnd = QueryGadget(window, QUERY_HWND) SetWindowLongW(nid.hwnd,GWL_WNDPROC,Int Byte Ptr SysTrayWndProc) nid.id = 0 nid.CallbackMessage = WM_APP nid.Icon = LoadIconW(GetModuleHandleW(Null),Short Ptr(101)) nid.Flags = NIF_MESSAGE | NIF_TIP | NIF_ICON SetNotifyIconDataTip( nid, toolTip ) Shell_NotifyIcon( NIM_ADD, nid) ? Win_trayed:Int=1 End Function Function SysTrayWndProc%(hwnd%,msg%,wp%,lp%) "win32" 'WndProc NotifyIcon -> Blitz Event ?Win32 Select msg Case WM_APP Local owner:TGadget = TWindowsGUIDriver.GadgetFromHwnd(hwnd) If owner Then Select lp Case WM_MOUSELEAVE PostGuiEvent( EVENT_MOUSELEAVE, owner ) Case WM_MOUSEMOVE PostGuiEvent( EVENT_MOUSEMOVE, owner ) Case WM_RBUTTONDOWN PostGuiEvent( EVENT_MOUSEDOWN, owner, MOUSE_RIGHT ) Case WM_LBUTTONDOWN PostGuiEvent( EVENT_MOUSEDOWN, owner, MOUSE_LEFT ) Case WM_RBUTTONDOWN PostGuiEvent( EVENT_MOUSEDOWN, owner, MOUSE_RIGHT ) EndSelect EndIf EndSelect Return TWindowsGUIDriver.ClassWndProc(hwnd,msg,wp,lp) ? EndFunction Function RemoveTrayIcon() ' Remove tray icon from taskbar ?Win32 Shell_NotifyIcon(NIM_DELETE, nid) win_trayed=0 ? End Function ?Win32 Function SetNotifyIconDataTip( nid:TNotifyIconData, s:String) MemClear( Varptr nid.Tip, 64) If s.length > 0 Then Local p:Byte Ptr = s.ToCString() If s.length < 64 Then MemCopy( Varptr nid.Tip, p, s.length) Else MemCopy( Varptr nid.Tip, p, 63) EndIf MemFree(p) EndIf EndFunction ? I'm trying to figure out how I can change the tooltip of a trayicon so that it shows up in front. This way the user doesn't need to move the mouse over it in order to make it visible. Is that possible? Some research I did: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773352%28v=vs.85%29.aspx https://msdn.microsoft.com/de-de/library/windows/desktop/hh298401%28v=vs.85%29.aspx But I couldn't find a clue how to do that. :/ |
| ||
Hi, there is the balloon infotip available which can be popuped with 'ShellNotifyInfo' function. I can take a look at it later if you want. -Henri |
| ||
A 'tooltip' by definition will show only when the user moves the mouse over an icon that has a tooltip associated with it. So what you have would be 'expected behavaiour'. An 'infotip' on the other hand can be made to show information using the Shell_NotifyInfo function using a popup ( which you get when you plug in or remove a usb device into a usb port ). If you fill out the rest of the NOTIFYICONINFO structure ( you have the info and guid etc parts missing ) then it should work. |
| ||
@Henri: If you could take a look, that would be nice. I don't know anything about this API stuff. As far as I know, balloon tips aren't supported by lower Windows versions. So I'd like to make this optional. Just in case the OS doesn't support it or the user doesn't want it (i.e. "If balloon_tip=true and OS > WinXP then"). I would use the code to make a small notification when a new song is played and my apps sits in the system tray. |
| ||
I'll try to work it out on weekend. -Henri |
| ||
Great, thanks a lot. |
| ||
Hiya, As far as I know, balloon tips aren't supported by lower Windows versions. Infotips ( or balloon tips ) are supported down to and including XP, but that's it. |
| ||
Allrighty, here is a working example for displaying balloon info in taskbar. I haven't tested it in other than Windows 7 64-bit, but should work from XP to Win 8 (if not then do let me know). This version is ANSI-standard so not sure how it behaves in all localizations, but making UNICODE version isn't that difficult if needed. I would perhaps wrap all this functionality inside a type just for neatness, but thats optional. EDIT: Updated code for Unicode support and few fixes. EDIT2: Fixed EditInfo() so that if no parameters are supplied then the balloontip is disabled. Example: -Henri |
| ||
Thanks for digging into this. I'm need of a unicode version if that is possible. Because some stations transmit data in Cyrillic for instance. So far it seems to work: ![]() Only thing I have noticed under windows 8 is that when I edited a balloon-tip, the normal tooltip for the tray icon itself will no longer show up if you move the mouse over it. Use the line "RegisterTrayIcon(TrayIconPanel, "THIS IS MY COOL APP")" as replacement for your example code above. Still testing... |
| ||
No problem, I'll see about that unicode version and tooltip. -Henri |
| ||
Thanks Henri! Do you have an e-mail address where I can contact you? |
| ||
OK, I've updated the example above for Unicode support and couple of fixes. You can contact me at kp9176<at>gmail.com .I usually don't watch it frequently, but if you post within a week I can get back to you from a proper email address. -Henri |
| ||
Hi again! For my testing the new code works fine, I only ran into one issue. I need to enable and disable the tips from within the app. For this I use a simple option "ini_dis_balloontip" to determine this. It works if I have the balloontips disabled and then enable them. But if they are disabled after being enabled, they always appear. Even though the EditInfo() and ShowInfo() aren't called anymore? Example function code: Function RegisterTrayIcon( window:TGadget, toolTip:String="" ) ' Register tray icon ?Win32 Titlebak:String="" Artistbak:String="" If Not nid Then nid = New TNotifyIconData nid.Size = SizeOf(TNotifyIconData) nid.hwnd = QueryGadget(window, QUERY_HWND) SetWindowLongW(nid.hwnd,GWL_WNDPROC,Int Byte Ptr SysTrayWndProc) nid.CallbackMessage = WM_APP nid.Icon = LoadIconW(GetModuleHandleW(Null),Short Ptr(101)) nid.Flags = NIF_MESSAGE | NIF_TIP | NIF_ICON | NIF_INFO EndIf If toolTip Then _stringCopy( Varptr nid.Tip, toolTip, 128) 'Print "ini dis ball: "+ini_dis_balloontip If ini_dis_balloontip=0 Then EditInfo(station_genre, station_name) Showinfo() EndIf Shell_NotifyIcon(NIM_ADD, nid) ? prp_trayed:Int=1 End Function Any idea, what might cause this behaviour? P.S. You've got mail. |
| ||
I have revised the code above (see EDIT2:). P.S. You've got mail. Answered.-Henri |
| ||
. |
| ||
I made a function to only update the tooltip itself.Function EditTrayTooltip(toolTip:String="") ?win32 If toolTip Then _stringCopy( Varptr nid.Tip, toolTip, 128) Shell_NotifyIcon( NIM_ADD, nid) ? End Function The only issue left is that when the balloon tips are disabled, the function does no longer update the tooltip? |
| ||
Hi, only thing I see a bit off is the use of NIM_ADD instead of NIM_MODIFY ? -Henri |
| ||
When I use NIM_MODIFY, the balloon tip will show up. But the tooltip on the tray icon stays the same. I only need to set the tooltip on an already registered tray icon. I could remove and set it again for each new song, but this would look strange. :) I uploaded the latest prp testbuild (III) to my website. If you want to see, how it currently works. |
| ||
I see :-). Ok, modify ShowInfo() function a bit like so: Function ShowInfo:Int() If nid Then nid.flags = NIF_MESSAGE | NIF_TIP | NIF_ICON | NIF_INFO Shell_NotifyIcon( NIM_MODIFY, nid) EndIf EndFunction Now modify the EditTrayTooltip() function a bit like so: Function EditTrayTooltip(toolTip:String="") ?win32 If toolTip Then _stringCopy( Varptr nid.Tip, toolTip, 128) nid.flags = NIF_MESSAGE | NIF_TIP | NIF_ICON Shell_NotifyIcon( NIM_MODIFY, nid) ? End Function And here is the newest version of the example in whole: -Henri |
| ||
Not working as expected. The balloon code isn't reliable from my testing so far. Guess, I will fall back to the old code. More testing over the weekend. |
| ||
Okey, I made some 'slight' modifications. Sorry if it's a 'bit' different , but I think it will be cleaner and more OO. -Henri |
| ||
Hi, under Win8 your newest code instantly closes the balloon tip the second time you resink the app into the task bar on Win 8.1. 1. run exampled code 2. minimise app -> balloon shows up for 3 seconds. 3. maximise app 4. minimise app again -> no ballon shows or only for a blink of time. Will try to implement your new code structure into my main code now. |
| ||
Hmm, it's probably not a Win8 issue as it seems to work fine on my Win8. I believe whenever app is added to systemtray it's automatically focused and if you press somewhere else causing it to lose focus ignites the fading out pocess for the balloon tip. Maybe one thing to try out as Win8 notification time is defaulted to 5 seconds so you could try to change this from the 'Easy access settings' to longer time to see if it makes any difference. EDIT: Could you send me your manifest file for testing ? -Henri |
| ||
Hello again. Thanks for all your help. After spending my saturday on this matter. I'm going back to the old code as I couldn't get it to work properly. |