Tired of your tray icon vanishing when Explorer.exe dies?

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Tired of your tray icon vanishing when Explorer.exe dies?

Post by Rescator »

( this is actually from my feature request post http://www.purebasic.fr/english/viewtopic.php?t=20712 )

It annoys the crap out of me when applications do not recreate their tray icons if explorer.exe should "die" and be restarted,
so to make your PureBasic program that much better than te others out there, use this:

Code: Select all

;Put this somewhere early in the app, along with the window creation
Global taskbarrestart.l
taskbarrestart=RegisterWindowMessage_("TaskbarCreated")
Now in your window callback add this:

Code: Select all

Procedure.l WindowCallback(hwnd,message,wparam,lparam)
Protected result.l=#PB_ProcessPureBasicEvents
 Select message
  Case taskbarrestart
   ;Tray icon recreate code here or maybe call a procedure that does this.
 EndSelect
ProcedureReturn result
Endprocedure
Obviously it makes most sense to only use this if you have tray icons in your program.
Also, older Windows does not support this message. (should do no harm though obviously since it's just a message).
I forgot which versions, but I'm guessing Window 2000 or later, maybe Win98 not sure. Vista however seems to need some extra privileges added to your program before you get that message, not sure about a solution there.
maw

Post by maw »

Interestingly enough the code works on Vista if your program is not running as administrator, but if your program is running as administrator it doesn't work. So for all of us always running as administrators has a problem here. The reason for this is simple, if not very logical. Explorer is not running as administrator, and in Vista system messages like these are not allowed to be sent to higher privileged running applications. Yet another security measure gone wrong if you ask me...

So the trick is for your program to first detect if you're running Vista and then make a call to ChangeWindowMessageFilter, http://msdn2.microsoft.com/en-us/library/ms632675.aspx, and allow the message to be sent to your program. Be ware that ChangeWindowMessageFilter is a Vista only command of user32.dll..
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

I'm not so sure its a security measure gone wrong. In previous versions of windows when this happened it was possible for some malware, viruses, trojans, etc...to crash explorer on purpose then run something from the taskbar and gain administrative rights to the system if the user was running as either admin or just a regular user.

The solution to this was to completly divorce explorer from this possibility, this is the reason Vista does this. It keeps the previous security flaw from happening and closes yet another attack vector. People complained about security flaws in Windows, so they fix'd them, maybe not all, but a lot of them.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

It shouldn't be possible to crash explorer on purpose in the first place.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Not 'easy' maybe, but anything is possible.

cheers
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> It shouldn't be possible to crash explorer on purpose in the first place

It's easy to do it. Just terminate the explorer.exe process and you're done.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

I believe Trond means it shouldn't be that easy. explorer should be fairly well protected.

cheers
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> explorer should be fairly well protected

Explorer is nothing special. It's just the visual part of Windows. In fact, you
can easily replace it totally with your own exe if you want. So, I very much
doubt Microsoft sees a need to protect it.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re:

Post by MachineCode »

Got a problem... if I'm sending a large email (with PureSMTP) and explorer.exe has died or crashed during this time, then the callback event is NOT fired; meaning my exe's icon no longer appears in the system tray due to missing the "taskbarrestart" message. How would we work around that situation?
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Tired of your tray icon vanishing when Explorer.exe dies

Post by Zach »

spawn a listening thread?
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Tired of your tray icon vanishing when Explorer.exe dies

Post by MachineCode »

Thanks Zach, I'll have to try that. I don't see why it wouldn't work. :)
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
Phantomas
User
User
Posts: 96
Joined: Wed Jul 01, 2009 12:59 pm

Re: Tired of your tray icon vanishing when Explorer.exe dies

Post by Phantomas »

So sorry for up this old thread, but, I have some question. This is correct code?

Code: Select all

EnableExplicit

Enumeration
  #window
  #icon
  #icon_image
EndEnumeration

#window_w = 320
#window_h = 60
#window_title = "My Window"

#icon_file = "path_to_icon.ico"

Define taskbarrestart.i

Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
  Shared taskbarrestart
  Select Message
    Case taskbarrestart
      AddSysTrayIcon(#icon, WindowID(#window), ImageID(#icon_image))
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(#window, #PB_Ignore, #PB_Ignore, #window_w, #window_h, #window_title, #PB_Window_ScreenCentered | #PB_Window_SystemMenu) And LoadImage(#icon_image, #icon_file)
  
  taskbarrestart = RegisterWindowMessage_("TaskbarCreated")
  AddSysTrayIcon(#icon, WindowID(#window), ImageID(#icon_image))
  SetWindowCallback(@MyWindowCallback())
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
    EndSelect
  ForEver
EndIf
This is work, but I use Shared for "transfer" taskbarrestart INT in MyWindowCallback() procedure, this is correct? Or is there another way?
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Tired of your tray icon vanishing when Explorer.exe dies

Post by ts-soft »

PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Post Reply