[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. |
