Dynamic tray icon (Windows)
From LiteratePrograms
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 |