🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
16 messages
16 total messages Started by Kris Sun, 17 Feb 2008 16:19
Multiple Shell_NotifyIcon calls
#663
Author: Kris
Date: Sun, 17 Feb 2008 16:19
23 lines
1634 bytes
Hi,

I noticed that when I send 2 Shell_NotifyIcon in a row, only the first 
is processed and the 2nd one is ignored.

So, in order to get both notifications to be processed, I need to 
introduce a  delay.

I expected the last notify to replace the first notify, but apparently 
this does not happen. As longs as the first notify is being processed, 
the 2nd notify is apparently discarded.

// Set default icon colour
Shell_NotifyIcon(dwMessage, &IconData);
// Do something, depending on result set new icon colour
Shell_NotifyIcon(dwMessage, &IconData);

Can someone clarify this behaviour? How can I make certain that all my 
notifications gets processed ?

Thanks,

Kris
Re: Multiple Shell_NotifyIcon calls
#665
Author: Kris
Date: Mon, 18 Feb 2008 09:22
11 lines
1264 bytes
Kris wrote:
> Hi,
> 
> I noticed that when I send 2 Shell_NotifyIcon in a row, only the first 
> is processed and the 2nd one is ignored.

Never mind. I managed to find the problem. I was using NIM_ADD all the 
time, while I should have been using NIM_MODIFY to change the already 
existing icon.

Kris
Re: Multiple Shell_NotifyIcon calls
#667
Author: Remy Lebeau (TeamB)
Date: Tue, 19 Feb 2008 17:38
26 lines
1690 bytes
"Kris" <ks@ks.com> wrote in message news:47B85E8F.6040508@ks.com...

> I noticed that when I send 2 Shell_NotifyIcon in a row,
> only the first is processed and the 2nd one is ignored.

Are you specifying the same ID to update the same icon each time?  Or are 
you specifying different IDs to update separate icons?

> So, in order to get both notifications to be processed, I
> need to introduce a  delay.

No, you don't.

> I expected the last notify to replace the first notify, but
> apparently this does not happen.

Please show your actual code.

> As longs as the first notify is being processed, the 2nd notify
> is apparently discarded.

The first notify is completely finished before Shell_NotifyIcon() exits.


Gambit 
Re: Multiple Shell_NotifyIcon calls
#670
Author: Kris
Date: Wed, 20 Feb 2008 19:40
24 lines
1979 bytes
Remy Lebeau (TeamB) wrote:
> The first notify is completely finished before Shell_NotifyIcon() exits.
> 

Thanks for your response. However, as indicated in my previous posting 
it turned out I was constantly using NIM_ADD instead of using NIM_MODIFY 
when the icon was created.

I do have another question though. My app is loaded during windows 
startup in the system tray (and does not show its main window). Most of 
the time this works just fine, but occasionally the app gets loaded but 
no system tray icon is created. It's hard to reproduce, but it does 
happen from time to time.

Does anyone know why this is happening? As a work-around I was thinking 
about adding a retry mechanism for Shell_NotifyIcon(NIM_ADD) until the 
call eventually returns successfully.

I'm not sure this work around will be sufficient since I don't know the 
real cause of the problem.

Any suggestions are much appreciated,

Kris
Re: Multiple Shell_NotifyIcon calls
#671
Author: Remy Lebeau (TeamB)
Date: Wed, 20 Feb 2008 20:27
23 lines
2040 bytes
"Kris" <ks@ks.com> wrote in message 
news:47bc8219$1@newsgroups.borland.com...

> I do have another question though. My app is loaded during windows startup 
> in the system tray (and does not show its main window). Most
> of  the time this works just fine, but occasionally the app gets loaded
> but no system tray icon is created. It's hard to reproduce, but it does 
> happen from time to time.

It could be that you are simply trying to add the icon before the taskbar 
itself has actualy been created yet.  To handle that (and to handle when the 
Shell crashes and has to recreate the taskbar), you need to intercept the 
"TaskbarCreated" broadcast message.  Refer to the following article for more 
details:

    The Taskbar
    http://msdn2.microsoft.com/en-us/library/bb776822.aspx

In particular, look at the "Taskbar Creation Notification" section.


Gambit 
Re: Multiple Shell_NotifyIcon calls
#672
Author: Kris
Date: Wed, 20 Feb 2008 21:07
18 lines
1535 bytes
Remy Lebeau (TeamB) wrote:
> "Kris" <ks@ks.com> wrote in message 
> news:47bc8219$1@newsgroups.borland.com...

>     The Taskbar
>     http://msdn2.microsoft.com/en-us/library/bb776822.aspx
> 
> In particular, look at the "Taskbar Creation Notification" section.

Thanks. I'll look into that. In the mean time I logged the error the 
NIM_ADD generated by using GetLastError().

It returned 0x05b4 which translates into "This operation returned 
because the timeout period expired."

Thanks.

Kris
Re: Multiple Shell_NotifyIcon calls
#673
Author: Remy Lebeau (TeamB)
Date: Wed, 20 Feb 2008 21:25
14 lines
1435 bytes
"Kris" <ks@ks.com> wrote in message 
news:47bc9687$1@newsgroups.borland.com...

> Thanks. I'll look into that. In the mean time I logged the
> error the NIM_ADD generated by using GetLastError().
>
> It returned 0x05b4 which translates into "This operation
> returned because the timeout period expired."

Shell_NotifyIcon() uses SendMessageTimeout() internally.


Gambit 
Re: Multiple Shell_NotifyIcon calls
#683
Author: Kris
Date: Fri, 22 Feb 2008 23:33
32 lines
2370 bytes
Remy Lebeau (TeamB) wrote:
> It could be that you are simply trying to add the icon before the taskbar 
> itself has actualy been created yet.  To handle that (and to handle when the 
> Shell crashes and has to recreate the taskbar), you need to intercept the 
> "TaskbarCreated" broadcast message.  Refer to the following article for more 
> details:
> 
>     The Taskbar
>     http://msdn2.microsoft.com/en-us/library/bb776822.aspx

Thanks for the link. It contains very useful info. I implemented 
handling the TaskBarCreated message, but things sometimes still don't 
behave as expected.

Shell crashes are handled just fine now, the message is received and I 
recreate my icon when necessary.

However, while loading my app during Windows startup, I still notice 
from time to time that NIM_ADD fails without ever subsequently receiving 
the TaskBarCreated message.

It's not a real problem handling this issue; I will add a retry 
mechanism that attempts NIM_ADD until the call finally succeeds (I 
hope/expect this to work).

However, I'm still wondering why the TaskBarCreated message solution 
isn't also able to fix the failed startup icon creation ?

FYI. I used the same code as in the MSDN article you suggested (i.e. 
call RegisterMessage() during WM_CREATE).

Kris
Re: Multiple Shell_NotifyIcon calls
#685
Author: Remy Lebeau (TeamB)
Date: Sat, 23 Feb 2008 00:46
18 lines
1700 bytes
"Kris" <ks@ks.com> wrote in message 
news:47bf5bd8$1@newsgroups.borland.com...

> However, while loading my app during Windows startup, I
> still notice from time to time that NIM_ADD fails without
> ever subsequently receiving the TaskBarCreated message.

Why are you creating the icon so early to begin with?

> However, I'm still wondering why the TaskBarCreated message
> solution isn't also able to fix the failed startup icon creation ?

Are you setting up your message handler before "TaskbarCreated" is actually 
broadcasted?


Gambit 
Re: Multiple Shell_NotifyIcon calls
#688
Author: Kris
Date: Sat, 23 Feb 2008 14:26
59 lines
3274 bytes
Remy Lebeau (TeamB) wrote:
> Why are you creating the icon so early to begin with?
Well, I assumed that the best time to create the icon is when my 
application starts.

I suppose I could use a timer and wait until a few seconds after 
initializing my app before actually creating the system tray icon. And 
probably this will reduce, if not eliminate, my problem. But I would 
have to pick an arbitrary number for the delay and I'm unsure what value 
to pick. Should I wait 3 seconds, or maybe 10 seconds just to be sure? 
Furthermore, when the user manually starts the application (instead of 
during Windows start-up), they expect the system tray icon to appear 
immediately).

So, perhaps it still would be best attempt to create the icon asap 
during startup and then retry periodically (e.g. every second) until 
NIM_ADD actually succeeds ?

This is where I attempt to create my icon during startup:

__fastcall TActivityMonitorServer::TActivityMonitorServer
   (TComponent* Owner): TForm(Owner)
{
    DEBUG("Activity Monitor Server %s started.",SERVER_VERSION);
    SetTrayIcon(NIM_ADD,BALLOON_OFF,"RES_ICON_SERVER_WARNING");
    ...
}

> Are you setting up your message handler before "TaskbarCreated" is actually 
> broadcasted?

I'm setting it up as soon as possible (during WM_CREATE) but since 
NIM_ADD sometimes fails without subsequently ever receiving a 
TaskbarCreated message, I'm guessing that something else is causing my 
NIM_ADD to fail. The actual TaskbarCreated message handler is working 
just fine, as can be confirmed when I simulate a shell crash (by 
terminating and restarting explorer.exe)

void __fastcall TActivityMonitorServer::WndProc(TMessage& Message)
{
   static UINT WM_TASKBARCREATED;

   switch (Message.Msg)
   {
     case WM_CREATE:
       WM_TASKBARCREATED=::RegisterWindowMessage(TEXT("TaskbarCreated"));
       break;

     default:
       if (Message.Msg==WM_TASKBARCREATED)
       {
         // re-create the system tray icon
        SetTrayIcon(NIM_ADD,BALLOON_OFF,"RES_ICON_SERVER_WARNING");
    }

    TForm::WndProc(Message);
}

Kris
Re: Multiple Shell_NotifyIcon calls
#689
Author: Asger Joergensen
Date: Sat, 23 Feb 2008 16:32
28 lines
2168 bytes
Hi Kris 
 
 Kris says:
> Remy Lebeau (TeamB) wrote:
> > Why are you creating the icon so early to begin with?
> Well, I assumed that the best time to create the icon is when my 
> application starts.
> 
> I suppose I could use a timer and wait until a few seconds after 
> initializing my app before actually creating the system tray icon. And 
> probably this will reduce, if not eliminate, my problem. 

Just a couple of ideas:

Create Your icon in the application OnIdle event that way Your 
app will be fully created before You create Your Icon.
OnIdle is called more then once so You need to set a flag when
Your icon is created or if You dont use OnIdle for anything else
You can set Application->OnIdle = 0; when You are done.

or as You mention use a timer with intervall set to e.g. 100 
then start it in WM_CREATE, it will not return until Your app is 
fully created, because it fires using a message which Your app
will not process before it is free to do so.

Kind regards
Asger
Re: Multiple Shell_NotifyIcon calls
#690
Author: Kris
Date: Sat, 23 Feb 2008 21:36
28 lines
2417 bytes
Asger Joergensen wrote:
> Create Your icon in the application OnIdle event that way Your 
> app will be fully created before You create Your Icon.
> OnIdle is called more then once so You need to set a flag when
> Your icon is created or if You dont use OnIdle for anything else
> You can set Application->OnIdle = 0; when You are done.

Hi,

Yes. Doing it in OnIdle is probably preferable. However, some tests 
showed that the NIM_ADD failure is not elimated.

But that's no problem anymore. OnIdle now keeps on retrying NIM_ADD 
until it finally succeeds (even though my app isn't doing a lot of work 
it takes about 5 seconds before the OnIdle gets triggered a 2nd time and 
manages to execute NIM_ADD successfully, but I guess this long delay is 
caused by Windows which was still busy booting?).

[23-feb-2008.22:21:44] NIM_ADD execution at TickCount 32703...
[23-feb-2008.22:21:48] ERROR: Shell_NotifyIcon NIM_ADD failed.
[23-feb-2008.22:21:50] NIM_ADD execution at TickCount 38609...

So, everything seems to be under control now. No sure why the failure is 
  occurring in the first place, but the retry is working as expected.

Thanks for your feedback,

Kris
Re: Multiple Shell_NotifyIcon calls
#694
Author: Remy Lebeau (TeamB)
Date: Mon, 25 Feb 2008 18:36
35 lines
2584 bytes
"Kris" <ks@ks.com> wrote in message 
news:47c02cfe$1@newsgroups.borland.com...

> Well, I assumed that the best time to create the icon is when my 
> application starts.

Yes, that is fine.  But that does no necessarily mean that you are starting 
your app at the right time.  There are several different places in Windows' 
startup where user apps can be loaded automatically.  When exactly are you 
starting your app?

> This is where I attempt to create my icon during startup:

I would suggest overriding the TForm's virtual CreateWnd() and DestroyWnd() 
methods instead of using the constructor.  Issue NIM_ADD in CreateWnd() and 
in response to "TaskbarCreated" message.  Issue NIM_REMOVE in DestroyWnd(). 
Issue NIM_MODIFY when changing the icon.

> I'm setting it up as soon as possible (during WM_CREATE)

That may be too late, depending on when the TForm's HWND is actually 
created.  I would suggest calling RegisterWindowMessage() as soon as 
possible (in the TForm's constructor, or better in WinMain() directly).  You 
do not need to use WM_CREATE at all.

>       if (Message.Msg==WM_TASKBARCREATED)

Make sure you check for 0 as well, in case RegisterWindowMessage() failed. 
0 means WM_NULL, which the VCL uses for other purposes:

    if( (Message.Msg==WM_TASKBARCREATED) && (WM_TASKBARCREATED != 0) )


Gambit 
Re: Multiple Shell_NotifyIcon calls
#698
Author: Kris
Date: Tue, 26 Feb 2008 18:31
12 lines
1486 bytes
Remy Lebeau (TeamB) wrote:

> When exactly are you starting your app?
I'm starting my app by adding a registry entry to following location:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

Thanks for the other suggestions. I will take them into account when 
finalizing my implementation.

Regards,

Kris
Re: Multiple Shell_NotifyIcon calls
#582
Author: Remy Lebeau (TeamB)
Date: Fri, 29 Feb 2008 18:36
52 lines
3173 bytes
"Kris" <ks@ks.com> wrote in message 
news:47bc8219$1@newsgroups.borland.com...

> I do have another question though. My app is loaded during windows startup 
> in the system tray (and does not show its main window). Most of the time 
> this works just fine, but occasionally the app gets loaded but no system 
> tray icon is created. It's hard to reproduce, but it does happen from time 
> to time.

I just noticed this at the bottom of the Shell_NotifyIcon() documentation:

    Shell_NotifyIcon Function
    http://msdn2.microsoft.com/en-us/library/bb762159.aspx

    Handling Shell_NotifyIcon failure

    Shell_NotifyIcon will often fail when called during Windows startup (for 
instance, if your application is listed in 
HKLM\Software\Microsoft\Windows\CurrentVersion\Run. This appears to be 
because the system is busy starting applications. The failure is more common 
on low-spec computers or computers with some brands of antivirus software 
installed, which seem to be very intensive at startup.

    Unfortunately, you cannot rely on the error code returned by 
GetLastError. When Shell_NotifyIcon returns false, some of the common errors 
returned by GetLastError are:

    ERROR_FILE_NOT_FOUND (2)

    ERROR_TIMEOUT (1460)

    ERROR_SUCCESS (0)

    The most appropriate response to any error returned by Shell_NotifyIcon 
is to sleep for a period of time and retry.

    An explanation of why the error code may differ has been made by Paul 
Baker, paraphrased from 
http://groups.google.com/group/microsoft.public.platformsdk.shell/msg/59235b293cbf5dfa 
and 
http://groups.google.com/group/microsoft.public.platformsdk.shell/msg/73973287f15c03fc:

    Shell_NotifyIcon actually calls SetLastError(0) initially. After that, 
basically it uses FindWindow to find the tray notification window. If this 
fails, it will typically return ERROR_FILE_NOT_FOUND. Otherwise it sends a 
WM_COPYDATA message to the tray notification window, using 
SendMessageTimeout with a timeout of only 4 seconds. If that message returns 
zero, then Shell_NotifyIcon will fail with GetLastError returning zero.


Gambit 
Re: Multiple Shell_NotifyIcon calls
#607
Author: Kris
Date: Wed, 05 Mar 2008 18:04
11 lines
1274 bytes
Remy Lebeau (TeamB) wrote:
> I just noticed this at the bottom of the Shell_NotifyIcon() documentation:
> 
>     Shell_NotifyIcon Function
>     http://msdn2.microsoft.com/en-us/library/bb762159.aspx
> 
>     Handling Shell_NotifyIcon failure

Great info. Thanks.

Kris
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads