This is a simple source code for converting Windows HICON to Fl_RGB_Image for my own customized FLTK window.
Before understanding how it works, It must be requires understanding of some Windows API like LoadImage().
API, icon_to_flrgb()
Fl_RGB_Image* icon_to_flrgb(HICON hIcon) { BITMAP bm; ICONINFO iconInfo; GetIconInfo(hIcon, &iconInfo); GetObject(iconInfo.hbmColor, sizeof(BITMAP),&bm); int width = bm.bmWidth; int height = bm.bmHeight; int bytesPerScanLine = (width * 3 + 3) & 0xFFFFFFFC; int size = bytesPerScanLine * height; BITMAPINFO infoheader = {0}; infoheader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); infoheader.bmiHeader.biWidth = width; infoheader.bmiHeader.biHeight = height; infoheader.bmiHeader.biPlanes = 1; infoheader.bmiHeader.biBitCount = 24; infoheader.bmiHeader.biCompression = BI_RGB; infoheader.bmiHeader.biSizeImage = size; // allocate Memory for Icon RGB data plus Icon mask plus ARGB buffer for the resulting image unsigned char* pixelsIconRGB = new unsigned char[ height * width * 4 ]; if ( pixelsIconRGB == NULL ) { return NULL; } unsigned char* alphaPixels = new unsigned char[ height * width * 4 ]; if ( alphaPixels == NULL ) { delete[] pixelsIconRGB; return NULL; } unsigned char* imagePixels = new unsigned char[ height * width * 4 ]; if ( imagePixels == NULL ) { delete[] pixelsIconRGB; delete[] alphaPixels; return NULL; } HDC hDC = CreateCompatibleDC(NULL); if ( hDC == NULL ) { delete[] pixelsIconRGB; delete[] alphaPixels; return NULL; } HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, (HGDIOBJ)iconInfo.hbmColor); if( GetDIBits(hDC, iconInfo.hbmColor, 0, height, (LPVOID) pixelsIconRGB, &infoheader, DIB_RGB_COLORS) == 0 ) { DeleteDC(hDC); delete[] pixelsIconRGB; delete[] alphaPixels; delete[] imagePixels; return NULL; } SelectObject(hDC, hBmpOld); // now get the mask if( GetDIBits(hDC, iconInfo.hbmMask, 0,height,(LPVOID)alphaPixels, &infoheader, DIB_RGB_COLORS) == 0 ) { DeleteDC(hDC); delete[] pixelsIconRGB; delete[] alphaPixels; delete[] imagePixels; return NULL; } DeleteDC(hDC); int x=0; int currentSrcPos=0; int currentDestPos=0; int linePosSrc = 0; int linePosDest = 0; int vsDest = height-1; for(int y=0; y<height; y++) { linePosSrc = ( vsDest - y ) * ( width * 3 ); linePosDest = y * width * 4; for(x=0; x<width; x++) { currentDestPos = linePosDest + ( x * 4 ); currentSrcPos = linePosSrc + ( x * 3); imagePixels[ currentDestPos + 0 ] = pixelsIconRGB[ currentSrcPos + 2 ]; imagePixels[ currentDestPos + 1 ] = pixelsIconRGB[ currentSrcPos + 1 ]; imagePixels[ currentDestPos + 2 ] = pixelsIconRGB[ currentSrcPos + 0 ]; imagePixels[ currentDestPos + 3 ] = 0xFF - alphaPixels[ currentSrcPos ]; } } Fl_RGB_Image* pImage = new Fl_RGB_Image( imagePixels, width, height, 4 ); delete[] pixelsIconRGB; delete[] alphaPixels; return pImage; }
Plus, to remove Fl_RGB_Image in safe, use this.
remove_fl_rgb_image()
void remove_fl_rgb_image( Fl_RGB_Image** img ) { if ( img != NULL ) { Fl_RGB_Image* srci = (Fl_RGB_Image*)*img; if ( ( srci->array != NULL ) && ( srci->alloc_array == 0 ) ) { delete[] srci->array; } delete srci; *img = NULL; } }
And, let know understand how it calls :
Sequence to convert image and apply, then discard.
// Load small ICON in size 16x16. HICON hIconWindowSmall = (HICON)LoadImage( fl_display,MAKEINTRESOURCE( IDC_ICON_A ),IMAGE_ICON,16,16,LR_SHARED ); // Convert HICON to Fl_RGB_Image .. Fl_RGB_Image* convtitleiconimg = icon_to_flrgb( hIconWindowSmall ); if ( convtitleiconimg != NULL ) { window_title_box->image( convtitleiconimg ); } .... something do .... and now . remove_fl_rgb_image( &convtitleiconimg );
remove_fl_rgb_image() may called in end of program, when it terminates or class destructor to release memory contains user allocated memory, and it is specification of FLTK 1.3.x.