Dynamic tray icon (Windows)

From LiteratePrograms

Jump to: navigation, search

This program is under development.
Please help to debug it. When debugging
is complete, remove the {{develop}} tag.


This code is an example of how to create a dynamic icon in the Windows system tray. It allows you to draw on top of a template icon or redraw it completely.

<<dynamic_tray_icon.c>>=
/*
**
** Dynamic tray icon example
**
** Link with: shell32.lib
*/
#include <windows.h>
#include <shellapi.h>
#include <stdio.h>
//------------------------------------------------------------------------------------------------------------------
// replaceicon() - draws stuff on top of a template icon. Destroys the input icon and returns a new one
//
// Inputs
// 						hIcon  : Handle to a icon
// 						value  : 0 - 100
//						clear  : 1 = clear icon first, 0 = don't clear icon first
// returns
// 						Failure: 0
//						Success: Handle to a icon
//------------------------------------------------------------------------------------------------------------------
HICON replaceicon(HICON hIcon, int value, BOOL clear)
{
  ICONINFO  uInfo;
  INT       lRes;
  HDC       hMemDc;
  HGDIOBJ   hOldBMP;
  HICON     hNewIcon;
  RECT      rectDraw;
  BITMAP    uBitmap;
  LOGFONT   font;
  HBRUSH    hBrush1;
  HBRUSH    hBrush2;
  lRes = GetIconInfo(hIcon, &uInfo);
  if(!lRes)
    return 0;
  hMemDc = CreateCompatibleDC(NULL);
  if(!hMemDc)
    return 0;
  if(!GetObject(uInfo.hbmColor , sizeof(BITMAP), &uBitmap))
    return 0;
  rectDraw.left  =                   0 ; rectDraw.top                       = 0 ;
  rectDraw.right = uBitmap.bmWidth - 1 ; rectDraw.bottom = uBitmap.bmHeight - 1 ;
  hOldBMP = SelectObject(hMemDc, uInfo.hbmColor);
  // ---
  RECT		bar;
  bar.left      = rectDraw.left;
  bar.right     = rectDraw.right;
  bar.top       = rectDraw.bottom  - (value * ((rectDraw.bottom - rectDraw.top)) / 100);
  bar.bottom    = rectDraw.bottom;
  if(clear)
    FillRect(hMemDc,&rectDraw,(HBRUSH) (hBrush1=CreateSolidBrush(RGB( 64,  0, 64 ))));
  FillRect(hMemDc,&bar,     (HBRUSH) (hBrush2=CreateSolidBrush(RGB( 220,32,255 ))));
  if(hBrush1)
    DeleteObject(hBrush1);
  if(hBrush2)
    DeleteObject(hBrush2);
  // ---
  char string[8];
  font.lfHeight             = uBitmap.bmHeight;
  font.lfWidth              = uBitmap.bmWidth/4;
  font.lfEscapement         = 0;
  font.lfOrientation        = 0;
  font.lfWeight             = 0; //FW_BOLD;
  font.lfItalic             = 0;
  font.lfUnderline          = 0;
  font.lfStrikeOut          = 0;
  font.lfCharSet            = ANSI_CHARSET;
  font.lfOutPrecision       = OUT_DEFAULT_PRECIS;
  font.lfClipPrecision      = CLIP_DEFAULT_PRECIS;
  font.lfQuality            = ANTIALIASED_QUALITY; //DEFAULT_QUALITY;
  font.lfPitchAndFamily     = DEFAULT_PITCH;
  strcpy(font.lfFaceName,   "Tahoma");
       SelectObject(hMemDc, CreateFontIndirect(&font));
          SetBkMode(hMemDc, TRANSPARENT);
            SetROP2(hMemDc, R2_COPYPEN);
  SetStretchBltMode(hMemDc, COLORONCOLOR);
       SetTextColor(hMemDc, RGB(235,235,255));
            sprintf(string, "%d",value);
  lRes = DrawText(hMemDc, string, strlen(string), &rectDraw, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  // ---
  if(!lRes)
    return 0;
  if(NULL || HGDI_ERROR == SelectObject(hMemDc, hOldBMP))
    return 0;
  hNewIcon = CreateIconIndirect(&uInfo);
  if(!hNewIcon)
    return 0;
  DestroyIcon(hIcon);
  hIcon = hNewIcon;
  if(hMemDc)
   DeleteDC(hMemDc);
  if(uInfo.hbmMask)
    DeleteObject(uInfo.hbmMask);
  if(uInfo.hbmColor)
    DeleteObject(uInfo.hbmColor);
  return hIcon;
}
//------------------------------------------------------------------------------------------------------------------
// Add, modify or removes the tray icon. A value of 0 means remove
//------------------------------------------------------------------------------------------------------------------
HICON settrayicon(HICON hIcon,int value)
{
  NOTIFYICONDATA   icon;
  static BOOL      firstrun=1;
  ZeroMemory(&icon,sizeof(NOTIFYICONDATA));
  icon.cbSize               = sizeof(NOTIFYICONDATA);
  icon.uID                  = 0;
  icon.hWnd                 = GetDesktopWindow();
  icon.uFlags               = NIF_ICON | NIF_TIP | NIF_MESSAGE;
  icon.hIcon                = hIcon;
  sprintf(icon.szTip,"Value = %d",value);
  icon.hIcon = replaceicon(icon.hIcon, value, 1); // Modify the icon
  if(!icon.hIcon)
    printf("***ERROR: replaceicon()\n"), exit(0);
  Shell_NotifyIcon(value==0?NIM_DELETE:firstrun?NIM_ADD,firstrun=0:NIM_MODIFY,&icon);
  Sleep(0);
  return icon.hIcon;
}
//------------------------------------------------------------------------------------------------------------------
// Entry point...
//------------------------------------------------------------------------------------------------------------------
int main(void)
{
  HICON		icon;
  icon = LoadImage(0,"c:\\some_icon.ico",IMAGE_ICON,32,32,LR_LOADFROMFILE);
  for(int x=0; x<100; x+=3)
  {
    icon = settrayicon(icon,x); // add/update the icon
    sleep(200);                 // Let us se what happens
  }
  settrayicon(icon,0); // remove the icon
  return 0;
}
Download code
Views