How to make a system tray program in Windows?

How can I make my program appear in the system tray of the Windows?

What I want my program do is to keep track of time regularly (using
timer) and do something behind the scene. (like a scheduler.)
So, I want to make my program disappear from main desktop and appear in the
system tray.

What can I do?

Sung Soo Kim wrote:

How can I make my program appear in the system tray of the Windows?

What I want my program do is to keep track of time regularly (using
timer) and do something behind the scene. (like a scheduler.)
So, I want to make my program disappear from main desktop and appear in the
system tray.

What can I do?

This puts a green tick in the SysTray, then changes it to a red minus
(No Entry sign in UK), then removes it. Delays in between (sleep).

I was going to send a traffic light sequence but I'm not certain whether
it's using a generally available DLL. I think most will have INETCPL.CPL

You can use any DLL that has icon(s), probably .EXE also ?

Have fun,

daz

···

#-------------------------------------------------------------------------------

require 'Win32API'

RT_ICON = 3
DIFFERENCE = 11
RT_GROUP_ICON = RT_ICON + DIFFERENCE

NIF_MESSAGE = 1
NIF_ICON = 2
NIF_TIP = 4
NIM_ADD = 0
NIM_MODIFY = 1
NIM_DELETE = 2

ExtractIcon = Win32API.new('shell32', 'ExtractIcon', 'LPI', 'L')
Shell_NotifyIcon = Win32API.new('shell32', 'Shell_NotifyIconA', 'LP', 'I')

hicoY = ExtractIcon.call(0, 'C:\WINDOWS\SYSTEM\INETCPL.CPL', 21) # Green tick
hicoN = ExtractIcon.call(0, 'C:\WINDOWS\SYSTEM\INETCPL.CPL', 22) # Red minus

tiptxt = 'test icon (ruby)'
pnid = [6*4+64, 0, 'ruby'.hash, NIF_ICON | NIF_TIP, 0, hicoY].pack('LLIIIL') <<
       tiptxt << "\0"*(64 - tiptxt.size)
ret = Shell_NotifyIcon.call(NIM_ADD, pnid)
p 'Err: NIM_ADD' if ret == 0

      sleep(3) # <----<<

pnid = [6*4+64, 0, 'ruby'.hash, NIF_ICON | NIF_TIP, 0, hicoN].pack('LLIIIL') <<
       tiptxt << "\0"*(64 - tiptxt.size)
ret = Shell_NotifyIcon.call(NIM_MODIFY, pnid)
p 'Err: NIM_MODIFY' if ret == 0

      sleep(6) # <----<<

pnid = [6*4+64, 0, 'ruby'.hash, 0, 0, 0].pack('LLIIIL') << "\0"
ret = Shell_NotifyIcon.call(NIM_DELETE, pnid)
p 'Err: NIM_DELETE' if ret == 0

#-------------------------------------------------------------------------------

VisualuRuby makes this pretty easy:

http://www.osk.3web.ne.jp/~nyasu/vruby/vrproject-e.html

Here is the example script for the tray icon stuff:

http://www.osk.3web.ne.jp/~nyasu/vruby/sample/traytest.rb

Ryan

···

On 11/25/05, Sung Soo Kim <sskim.box@gmail.com> wrote:

How can I make my program appear in the system tray of the Windows?

What I want my program do is to keep track of time regularly (using
timer) and do something behind the scene. (like a scheduler.)
So, I want to make my program disappear from main desktop and appear in the
system tray.

What can I do?

Hi,

Very neat. I found the icons in C:\WINDOWS\SYSTEM32\INETCPL.CPL' though.

Do you have pointers to more info on this API? I am not really a windows programmer.

Thanks

Tom

daz wrote:

···

Sung Soo Kim wrote:

How can I make my program appear in the system tray of the Windows?

What I want my program do is to keep track of time regularly (using
timer) and do something behind the scene. (like a scheduler.)
So, I want to make my program disappear from main desktop and appear in the
system tray.

What can I do?

This puts a green tick in the SysTray, then changes it to a red minus
(No Entry sign in UK), then removes it. Delays in between (sleep).

I was going to send a traffic light sequence but I'm not certain whether
it's using a generally available DLL. I think most will have INETCPL.CPL

You can use any DLL that has icon(s), probably .EXE also ?

Have fun,

daz

#-------------------------------------------------------------------------------

require 'Win32API'

RT_ICON = 3
DIFFERENCE = 11
RT_GROUP_ICON = RT_ICON + DIFFERENCE

NIF_MESSAGE = 1
NIF_ICON = 2
NIF_TIP = 4
NIM_ADD = 0
NIM_MODIFY = 1
NIM_DELETE = 2

ExtractIcon = Win32API.new('shell32', 'ExtractIcon', 'LPI', 'L')
Shell_NotifyIcon = Win32API.new('shell32', 'Shell_NotifyIconA', 'LP', 'I')

hicoY = ExtractIcon.call(0, 'C:\WINDOWS\SYSTEM\INETCPL.CPL', 21) # Green tick
hicoN = ExtractIcon.call(0, 'C:\WINDOWS\SYSTEM\INETCPL.CPL', 22) # Red minus

tiptxt = 'test icon (ruby)'
pnid = [6*4+64, 0, 'ruby'.hash, NIF_ICON | NIF_TIP, 0, hicoY].pack('LLIIIL') <<
       tiptxt << "\0"*(64 - tiptxt.size)
ret = Shell_NotifyIcon.call(NIM_ADD, pnid)
p 'Err: NIM_ADD' if ret == 0

      sleep(3) # <----<<

pnid = [6*4+64, 0, 'ruby'.hash, NIF_ICON | NIF_TIP, 0, hicoN].pack('LLIIIL') <<
       tiptxt << "\0"*(64 - tiptxt.size)
ret = Shell_NotifyIcon.call(NIM_MODIFY, pnid)
p 'Err: NIM_MODIFY' if ret == 0

      sleep(6) # <----<<

pnid = [6*4+64, 0, 'ruby'.hash, 0, 0, 0].pack('LLIIIL') << "\0"
ret = Shell_NotifyIcon.call(NIM_DELETE, pnid)
p 'Err: NIM_DELETE' if ret == 0

#-------------------------------------------------------------------------------

Tom Ayerst wrote:

Hi,

Very neat. I found the icons in C:\WINDOWS\SYSTEM32\INETCPL.CPL' though.

Ah, thanks. That may apply to the majority, then.

Do you have pointers to more info on this API? I am not really a
windows programmer.

On MSDN,

I support Ryan's point about VRuby/SWin and I should have mentioned it.

The traytest.rb example he linked to should be more appropriate to the
original poster than I thought.

My example would need a Windows message loop to do anything useful like
minimizing a GUI or waking it up again by clicking on the tray icon.
VRuby implements that and, of course, most Windows users will have it
installed already if they used the RubyForge one-click installer.

Cheers,

daz