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.