dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15

Thread: What is the best way to do this?

  1. #1
    Join Date
    Feb 2009
    Location
    Portland, OR
    Posts
    1,488

    What is the best way to do this?

    Hi:


    I want to add animation to my program's icon on the system tray. The animation consists of 100 frames. To save CPU cycles I thought to render all 100 frames when the program starts and create 100 small 16x16 icons that I can reuse when the animation has to run. But then I remembered that I read somewhere that GDI doesn't like giving out too many handles (icon handles in this case), so my question is, should I go with my approach above? Or should I create a new icon, render it and then remove it for each frame of animation when it's needed?

  2. #2
    Join Date
    Aug 2008
    Location
    Scotland
    Posts
    379

    Re: What is the best way to do this?

    From google:

    http://blogs.msdn.com/abhinaba/archi...y-using-c.aspx looks interesting.

    Seems the best is to render a bitmap strip that includes all the frames at start up, then create the icons at run time.

  3. #3
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: What is the best way to do this?

    The system tray is not a videoplayer. Don't use it to do animation.

    At best you should have a limited number of INFORMATIVE icons. Anything else is likely going to annoy your users. Rendering an icon with say a percent complete indicator is still going to be ok. But suppose you make a videoplayer and wanted a miniframe of the video playing that would be a bad way to go.

    But to answer your question: Icon handles aren't going to exhaust the GDI, you'll run out of memory before.

    The issue to remember is that updating the system tray is fairly expensive in terms of CPU time involved, it's something you want to do as infrequent as possible. If you plan to update the system tray icon several times per second, you have a wrong idea about what it's for.

  4. #4
    Join Date
    Feb 2009
    Location
    Portland, OR
    Posts
    1,488

    Re: What is the best way to do this?

    I appreciate it guys. And, OReubens, no I'm not planning to run a videoplayer at 29.97 frames per second in 16 by 16 pixel resolution

    Quote Originally Posted by OReubens
    The issue to remember is that updating the system tray is fairly expensive in terms of CPU time involved
    Just curious, where do you take it from? I can't imagine that updating a 16x16 pixel icon should be so demanding for today's systems.

  5. #5
    Join Date
    Apr 1999
    Posts
    3,585

    Re: What is the best way to do this?

    Beyond what OReubens has stated, from a UI standpoint, animation on the task bar would be very annoying. It would force your eye to constantly look down potentially away from your work.
    Gort...Klaatu, Barada Nikto!

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,209

    Re: What is the best way to do this?

    I always hide my taskbar, so for me it would just be a waste of resources.

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,603

    Re: What is the best way to do this?

    I read somewhere that GDI doesn't like giving out too many handles
    "Too many" is about 10000 handles. So you'll still have 9900 more ones to waste.
    Best regards,
    Igor

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,209

    Re: What is the best way to do this?

    The limit used to be about 65K for the whole system.

    I think it's higher now, but not sure what the current max is.

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,603

    Re: What is the best way to do this?

    From MSDN:
    There is a theoretical limit of 65,536 GDI handles per session. However, the maximum number of GDI handles that can be opened per session is usually lower, since it is affected by available memory.
    Windows 2000: There is a limit of 16,384 GDI handles per session.

    There is also a default per-process limit of GDI handles. To change this limit, set the following registry value:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\GDIProcessHandleQuota
    This value can be set to a number between 256 and 65,536.
    Windows 2000: This value can be set to a number between 256 and 16,384.
    Here's my XP default settings:
    Attached Images Attached Images  
    Best regards,
    Igor

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,209

    Re: What is the best way to do this?

    Thanks Igor.

  11. #11
    Join Date
    Feb 2009
    Location
    Portland, OR
    Posts
    1,488

    Re: What is the best way to do this?

    Guys, I did a test. First I created an empty MFC project and clocked in its memory. Then I added 100 HICON handles and loaded them up using LoadImage() and 16x16 pixel color icons each with its own alpha channel. Now look at the memory usage difference:

    Empty MFC project ---------------------- 3516K
    MFC project w/100 icons --------------- 3596K
    Windows Explorer ---------------------- 19,924K
    Internet Explorer 6.0 (empty screen) ---- 21,400K

    80K! How about IE eating up 20MB just to show an empty screen, hah. So those 100 icons is nothing for a modern PC.

    Quote Originally Posted by OReubens
    The issue to remember is that updating the system tray is fairly expensive in terms of CPU time involved
    I tested what impact does icon animation do on a system tray as well. I'm using the same preloaded 100 icons and increment my program's system tray icon using the following API:
    Code:
    nid.uFlags = NIF_ICON;
    nid.hIcon = g_mGlobalIconPool[g_nIndex++];
    Shell_Notify(NIM_MODIFY, &nid);
    I'm doing this on a Windows XP SP3 Dell desktop with a fairly old hardware (about 4 years old):
    CPU ----------- Intel Pentium 4, 2.90GHz
    RAM ----------- 2.50GB
    Video Card ---- built-in NVIDIA GeForce FX 5200 w/128 MB memory

    First my program w/o animation:
    My process CPU usage: 0%
    System CPU usage: 0-1%

    Then my program w/ animation:
    (Running animation every 100 ms, using SetTimer)
    My process CPU usage: 0%
    System CPU usage: 0-1% (switches every 5-8 seconds)

    Then extreme case - my program w/ animation:
    (Running animation every 10 ms, or going thru all 100 frames in 1 second using SetTimer)
    My process CPU usage: 0%
    System CPU usage: 0-1% (switches every 2-3 seconds)

    In other words I could not see any visible difference in CPU usage. Task manager used more to update its process list.

    Thank you everyone, who contributed.


    PS. I just wish that some advice here was a little bit more based on facts.

  12. #12
    Join Date
    Apr 2010
    Location
    Western WA, USA
    Posts
    59

    Re: What is the best way to do this?

    Quote Originally Posted by ahmd View Post
    ... I just wish that some advice here was a little bit more based on facts.
    The fact remains that the vast majority of software users would hate being distracted by an animated icon.

  13. #13
    Join Date
    Aug 2008
    Location
    Scotland
    Posts
    379

    Re: What is the best way to do this?

    From an MSDN comment:

    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.
    I would expect that could use a "fairly expensive" number of CPU cycles, relative to the actual GDI stuff.

    There are some good reasons for having an animated icon in the system tray, but it should be used sparingly, and only when you actually do want to distract the user.

  14. #14
    Join Date
    Feb 2009
    Location
    Portland, OR
    Posts
    1,488

    Re: What is the best way to do this?

    Quote Originally Posted by cosmicvoid
    The fact remains that the vast majority of software users would hate being distracted by an animated icon.
    What amazes me is that Microsoft uses tray icon animation for almost every new product they come up with (from Task Manager to Security Essentials) and me doing animation is not OK.

    Quote Originally Posted by alanjhd08 View Post
    From an MSDN comment:

    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.
    This is a user comment taken from the Shell_NotifyIcon page. I can post there that pink elephants fly, would you refer to it too?

    Still, what the poster was referring to in that MSDN post is the situation when a tray icon is initiated from a service controlled app that may thwart a timely creation of a tray icon. How does that apply to my situation?

    Quote Originally Posted by alanjhd08 View Post
    I would expect that could use a "fairly expensive" number of CPU cycles, relative to the actual GDI stuff.
    alanjhd08, did you see my benchmark test results above?

    Quote Originally Posted by alanjhd08 View Post
    There are some good reasons for having an animated icon in the system tray, but it should be used sparingly, and only when you actually do want to distract the user.
    Yeah, alanjhd08 and cosmicvoid check my app icon (screenshot).
    Attached Images Attached Images  

  15. #15
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,209

    Re: What is the best way to do this?

    Quote Originally Posted by ahmd View Post
    Yeah, alanjhd08 and cosmicvoid check my app icon (screenshot).
    In technical terms that icon is fugly.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)