René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle - Most wanted - Feedback -
 

A class for dynamic icons in Windows


#include <windows.h>

class DynamicIcon {
public:
  DynamicIcon();
 ~DynamicIcon();

  HICON Icon();

private:

  HDC      memDC1_; 
  HDC      memDC2_;
  
  HBITMAP  oldBmp_1; 
  HBITMAP  oldBmp_2;
  HBITMAP  iconBmp_;
  HBITMAP  iconMaskBmp_;

  HBRUSH   hCircleBrush;
  HBRUSH   hTranspBrush;
  HBRUSH   hOldBrush;

  HRGN     circle;

  HICON    icon_;

  static int const iconWidth_;
  static int const iconHeight_;
};

int const DynamicIcon::iconWidth_  = 16;
int const DynamicIcon::iconHeight_ = 16;

DynamicIcon::DynamicIcon() {
  HDC hDC = GetDC (0);

  memDC1_  = CreateCompatibleDC     (hDC);
  memDC2_  = CreateCompatibleDC     (hDC);
  iconBmp_ = CreateCompatibleBitmap (hDC, iconWidth_, iconHeight_);

  iconMaskBmp_ = CreateCompatibleBitmap (hDC, iconWidth_, iconHeight_);
  oldBmp_1    = (HBITMAP) SelectObject (memDC1_, (HBITMAP) iconBmp_);
  oldBmp_2    = (HBITMAP) SelectObject (memDC2_, (HBITMAP) iconMaskBmp_);

  // prepare mask
  HBRUSH hBrush = CreateSolidBrush (RGB (255, 255, 255)); 
  hOldBrush     = (HBRUSH) SelectObject (memDC2_, hBrush);
  PatBlt (memDC2_, 0, 0, iconWidth_, iconHeight_, PATCOPY);
  SelectObject (memDC2_, hOldBrush);
  DeleteObject (hBrush);
  
  // draw circle on both bitmaps
  circle = CreateEllipticRgn (0, 0, iconWidth_, iconHeight_);

  hBrush = CreateSolidBrush (RGB (255, 0, 0)); 
  FillRgn (memDC1_, circle, hBrush);
  DeleteObject (hBrush);

  hBrush = CreateSolidBrush (RGB (0, 0, 0)); 
  FillRgn (memDC2_, circle, hBrush);
  DeleteObject (hBrush);
  DeleteObject (circle);
  
  SelectObject (memDC1_, (HBITMAP) oldBmp_1);
  DeleteDC     (memDC1_);
  SelectObject (memDC2_, (HBITMAP) oldBmp_2);
  DeleteDC     (memDC2_);
  DeleteDC     (hDC);
  
  ICONINFO ii = {TRUE, 0, 0, iconMaskBmp_, iconBmp_};
  icon_ = CreateIconIndirect (&ii);

}

DynamicIcon::~DynamicIcon() {
  DestroyIcon (icon_);
  DeleteObject(iconBmp_);
  DeleteObject(iconMaskBmp_);
}

HICON DynamicIcon::Icon() {
  return icon_;
}


LRESULT CALLBACK WndProc(
    HWND   hWnd,
    UINT   msg,
    WPARAM wParam,
    LPARAM lParam ) {

  switch( msg ) {
    case WM_PAINT: {
      PAINTSTRUCT ps;
      HDC hDC = BeginPaint( hWnd, &ps );
      TextOut(hDC, 10, 10, "ADP GmbH", 8 );
      EndPaint( hWnd, &ps );
    }
    break;

    case WM_DESTROY:
      PostQuitMessage(0);
    break;

    default:
      return DefWindowProc( hWnd, msg, wParam, lParam);
  } 
  return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   LPSTR lpCmdLine, int nCmdShow) {


  DynamicIcon di;

  WNDCLASSEX wce;

  wce.cbSize        = sizeof(wce);
  wce.style         = CS_VREDRAW | CS_HREDRAW; 
  wce.lpfnWndProc   = (WNDPROC) WndProc; 
  wce.cbClsExtra    = 0; 
  wce.cbWndExtra    = 0; 
  wce.hInstance     = hInstance; 
  wce.hIcon         = <b>di.Icon()</b>;
  wce.hCursor       = LoadCursor((HINSTANCE) NULL, IDC_ARROW); 
  wce.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 
  wce.lpszMenuName  = 0;
  wce.lpszClassName = "ADPWinClass",
  wce.hIconSm       = 0;
 
  if (!RegisterClassEx(&wce)) return 0; 
  
  HWND hWnd = CreateWindowEx(
    0,          // Ex Styles
    "ADPWinClass",
    "ADP GmbH",
     WS_OVERLAPPEDWINDOW,
     CW_USEDEFAULT,  // x
     CW_USEDEFAULT,  // y
     CW_USEDEFAULT,  // Hoehe
     CW_USEDEFAULT,  // Breite
     NULL,           // ElternWindow
     NULL,           // Menu respektive Child ID
     hInstance,      // 
     NULL            // Pointer auf Daten zu diesem Window
  );

  ShowWindow( hWnd, nCmdShow );

  MSG msg;
  int r;
  while ((r = GetMessage(&msg, NULL, 0, 0 )) != 0) { 
    if (r == -1) {
      ;  // Error!
    }
    else {
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
    }
  } 

  return msg.wParam;
};