Page 1 of 4

How to remove systray icon?

Posted: Tue Feb 16, 2010 12:20 pm
by whertz
I'm running an external program, and after I kill it the systray icon remains until you hover over it with the mouse. This isn't such a big deal but when you run the program several times the system icon tray gets massive! Does anyone know how to stop this, maybe by refreshing the tray? I've looked through the forum but can't seem to find anything. Thanks.

Here's a code example:

Code: Select all

processID.l = RunProgram("someprogram.exe","","",#PB_Program_Open)  

Delay(10000) 
 
KillProgram(processID) 
CloseProgram(processID) 

Re: How to remove systray icon?

Posted: Tue Feb 16, 2010 12:29 pm
by Fred
KillProgram() really kills the program, with no chance to correctly exits. That's why its icon is still remaining, and you will have to inform the explorer process than it needs to refresh it's systray bar.

Re: How to remove systray icon?

Posted: Tue Feb 16, 2010 12:42 pm
by Michael Vogel
Maybe you can move this code to PB...

Michael

Re: How to remove systray icon?

Posted: Tue Feb 16, 2010 12:58 pm
by whertz
Fred wrote:KillProgram() really kills the program, with no chance to correctly exits. That's why its icon is still remaining, and you will have to inform the explorer process than it needs to refresh it's systray bar.
I see. I'm no good at API stuff, but is it possible to kill it in a "nice" way, by maybe using sendmessage telling it to close?

Re: How to remove systray icon?

Posted: Tue Feb 16, 2010 5:31 pm
by srod
If you can find the handle of the main window (use FindWindow_()) then try sending the following message :

Code: Select all

SendMessage_(hWnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)(

Re: How to remove systray icon?

Posted: Tue Feb 16, 2010 9:39 pm
by skywalk
Hi,
This is so much easier than VB6!

Questions?...
Why doesn't the internal PB cmd work below?
Is it because I redefined the NOTIFYICONDATA structure?
Note the fixed string in place of the Char array.
And, how do I use the Char array instead of redefining the Structure?
Do I have to destroy the icon before closing?

Code: Select all

; Structure NOTIFYICONDATA
;   cbSize.l
;   hWnd.i
;   uID.l
;   uFlags.l
;   uCallbackMessage.l
;   hIcon.i
;   szTip.c[64]
; EndStructure

Structure m_NOTIFYICONDATA
  cbSize.i
  hwnd.i
  uId.i
  uFlags.i
  uCallBackMessage.i
  hIcon.i
  szTip.s{64}
EndStructure

ImportC "SHELL32.LIB" 
  Shell_NotifyIcon_.i(dwMessage.i, pnid.i) As "_Shell_NotifyIconA" 
EndImport
Define.i hWnd, hIcon

Define.m_NOTIFYICONDATA nid  
hwnd = GetDesktopWindow_()
hicon = ExtractIcon_(0,"c:\windows\notepad.exe",0)

With nid
  \cbSize = SizeOf(nid)
  \hWnd = hWnd
  \uId = #Null
  \uFlags = #NIF_ICON | #NIF_TIP | #NIF_MESSAGE
  \uCallBackMessage = #WM_MOUSEMOVE
  \hIcon = hicon
  \szTip = "Some Text Here" + Chr(0)
EndWith

Shell_NotifyIcon_(#NIM_ADD, nid)
;--> PB cmd does not work --> AddSysTrayIcon(0,hWnd,hicon)
  Debug "...Hold mouse over SysTray icon now..."
  Delay(5000)
  Debug "...Attempting to remove SysTray icon..."
  Debug ""
Shell_NotifyIcon_(#NIM_DELETE, nid)
  Debug "...Quitting in 3 sec..."
DestroyIcon_(hIcon)
  Delay(3000)
End

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 8:56 am
by kryptonn
whertz wrote: I've looked through the forum but can't seem to find anything.
http://www.purebasic.fr/english/viewtop ... =5&t=28500

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 9:55 am
by UserOfPure
There's a PureBasic example somewhere here if you do the right search.

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 11:27 am
by whertz
srod wrote:If you can find the handle of the main window (use FindWindow_()) then try sending the following message :

Code: Select all

SendMessage_(hWnd, #WM_SYSCOMMAND, #SC_CLOSE, 0)(
Thanks srod, I got this working but I found out when you do this, it just minimizes the program. So I really do need to kill it with killprogram. Has anyone found a solution in PB to remove the lingering tray icon??

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 12:14 pm
by UserOfPure
To close a program via its handle, use this:

Code: Select all

PostMessage_(hWnd,#WM_CLOSE,0,0)
Don't use SendMessage because it won't work with folder windows (at least it doesn't for me).

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 12:17 pm
by srod
Yes when I have done this sort of thing; sometimes #WM_CLOSE does the job, but other times the #SC_CLOSE was needed. Depends on the program itself I guess.

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 12:39 pm
by whertz
UserOfPure wrote:To close a program via its handle, use this:

Code: Select all

PostMessage_(hWnd,#WM_CLOSE,0,0)
Don't use SendMessage because it won't work with folder windows (at least it doesn't for me).
That just makes it open up from the tray, and minimizes it again. I think the only way is killprogram.

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 12:44 pm
by UserOfPure
whertz wrote:That just makes it open up from the tray, and minimizes it again.
Not on XP. I've been using it to close apps on XP for years. It's basically the same as doing Alt+F4 on the app. What OS are you using it with?

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 12:49 pm
by whertz
UserOfPure wrote:
whertz wrote:That just makes it open up from the tray, and minimizes it again.
Not on XP. I've been using it to close apps on XP for years. It's basically the same as doing Alt+F4 on the app. What OS are you using it with?
I understand what you are saying, but sending it Alt+F4 minimizes it, it is just the way the program works. It's like when you press the close button on some apps, they minimize instead. BTW I'm using XP too.

Re: How to remove systray icon?

Posted: Wed Feb 17, 2010 12:51 pm
by srod
@Skywalk : with AddSysTrayIcon() there is a linker error which you can resolve by ensuring that PB's image lib is added to the mix. Simply create a dummy function which is never called and which contains an arbitrary image command. E.g. :

Code: Select all

Procedure DoNotCall()
  CreateImage(1, 10,10)
EndProcedure
As for the structure issue; yes your definition makes more sense. However, you can still use PB's NOTIFYICONDATA structure as follows :

Code: Select all

Procedure DoNotCall()
  CreateImage(1, 10,10)
EndProcedure


ImportC "SHELL32.LIB" 
  Shell_NotifyIcon_.i(dwMessage.i, pnid.i) As "_Shell_NotifyIconA" 
EndImport
Define.i hWnd, hIcon

Define.NOTIFYICONDATA nid  
hwnd = GetDesktopWindow_()
hicon = ExtractIcon_(0,"c:\windows\notepad.exe",0)

With nid
  \cbSize = SizeOf(nid)
  \hWnd = hWnd
  \uId = #Null
  \uFlags = #NIF_ICON | #NIF_TIP | #NIF_MESSAGE
  \uCallBackMessage = #WM_MOUSEMOVE
  \hIcon = hicon
  PokeS(@\szTip, "Some Text Here")
EndWith

Shell_NotifyIcon_(#NIM_ADD, nid)
;AddSysTrayIcon(0,hWnd,hicon)
  Debug "...Hold mouse over SysTray icon now..."
  Delay(5000)
  Debug "...Attempting to remove SysTray icon..."
  Debug ""
Shell_NotifyIcon_(#NIM_DELETE, nid)
  Debug "...Quitting in 3 sec..."
DestroyIcon_(hIcon)
  Delay(3000)
End