How to save Icon as bitmap?

Icons are being a bit mysterious comparing to bitmaps. Now how we can save and icon to bitmap. There are several methods to do this. Here’s a simple tweak to save it using memory DC.

void SaveBitmapToFile( BYTE* pBitmapBits, LONG lWidth, LONG lHeight,WORD wBitsPerPixel, LPCTSTR lpszFileName )
{
    BITMAPINFOHEADER bmpInfoHeader = {0};
    // Set the size
    bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    // Bit count
    bmpInfoHeader.biBitCount = wBitsPerPixel;
    // Use all colors
    bmpInfoHeader.biClrImportant = 0;
    // Use as many colors according to bits per pixel
    bmpInfoHeader.biClrUsed = 0;
    // Store as un Compressed
    bmpInfoHeader.biCompression = BI_RGB;
    // Set the height in pixels
    bmpInfoHeader.biHeight = lHeight;
    // Width of the Image in pixels
    bmpInfoHeader.biWidth = lWidth;
    // Default number of planes
    bmpInfoHeader.biPlanes = 1;
    // Calculate the image size in bytes
    bmpInfoHeader.biSizeImage = lWidth* lHeight * (wBitsPerPixel/8);

    BITMAPFILEHEADER bfh = {0};
    // This value should be values of BM letters i.e 0x4D42
    // 0x4D = M 0×42 = B storing in reverse order to match with endian
    bfh.bfType=0x4D42;
    /* or
    bfh.bfType = ‘B’+(‘M’ << 8);
    // <<8 used to shift ‘M’ to end
    */
    // Offset to the RGBQUAD
    bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
    // Total size of image including size of headers
    bfh.bfSize = bfh.bfOffBits + bmpInfoHeader.biSizeImage;
    // Create the file in disk to write
    HANDLE hFile = CreateFile( lpszFileName,GENERIC_WRITE, 0,NULL,

                               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);

    if( !hFile ) // return if error opening file
    {
        return;
    }

    DWORD dwWritten = 0;
    // Write the File header
    WriteFile( hFile, &bfh, sizeof(bfh), &dwWritten , NULL );
    // Write the bitmap info header
    WriteFile( hFile, &bmpInfoHeader, sizeof(bmpInfoHeader), &dwWritten, NULL );
    // Write the RGB Data
    WriteFile( hFile, pBitmapBits, bmpInfoHeader.biSizeImage, &dwWritten, NULL );
    // Close the file handle
    CloseHandle( hFile );
}

void CLoadIconSampleDlg::OnBnClickedButtonSaveIcon()
{
	// Loading resource from DLL.
	HMODULE h = LoadLibrary( L"myresource.dll" );

	if( !h )
	{
		MessageBox( L"Failed to load library" );
		return;
	}

	INT id = GetDlgItemInt( IDC_EDIT1 );
	m_hLoadedIcon = LoadIcon( (HINSTANCE) h , MAKEINTRESOURCE( id ) );

	CBitmap bmpSave;
	CClientDC dc(this);
	bmpSave.CreateCompatibleBitmap( &dc, 32, 32 );

	CDC dcMem;
	dcMem.CreateCompatibleDC( &dc );
	dcMem.SelectObject( &bmpSave );
	dcMem.DrawIcon( 0, 0, m_hLoadedIcon );

	BITMAP bmpInfo;
	bmpSave.GetBitmap( &bmpInfo );

	int size = bmpInfo.bmHeight* bmpInfo.bmWidth * (bmpInfo.bmBitsPixel / 8 );
	unsigned char* pBytes = new unsigned char[size];
	bmpSave.GetBitmapBits( size, pBytes );
	SaveBitmapToFile( pBytes, 32, 32, bmpInfo.bmBitsPixel, _T( "C:\\temp\\temp.bmp" ));
	delete []pBytes;

	FreeLibrary( h );
}

const to data and pointer

This is a fundamental thing that every C++ programmers must know.

const to data

This is the simplest form of pointer definition that we always do.

const int* data3 = arr2; // Const to data
data3[0] = 55;  // ERROR: Data can't be changed
data3 = arr1;    // Success:  Can't change the pointer to somewhere else

Here the data is can’t changed using data3 pointer. but the pointer itself can be modified and can point to some other location.

Usually we don’t care even if pass the pointer to some function and that pointer changes to some other location, as the function parameters points to same location but the pointer is a copy of actual parameter. But things may go different if we wrongly pass reference to function parameters even it’s const. So we’ve to take care this while designing the interfaces.

void Foo(  LPCTSTR& lpszValue )
{
	lpszValue = _T( "codereflect.com" );
}

int _tmain(int argc, _TCHAR* argv[])
{
	LPCTSTR sz = NULL;
	Foo(sz);
	_tprintf( sz );
	return 0;
}

const to pointer

In this form of usage, the pointer can’t be changed to some location but the data can be changed.

int* const data2 = arr2; // const to pointer
data2 = arr1;    // Can't change the pointer to somewhere else
data2[0] = 55;  // SUCCESS: Data can be changed

const to both data and pointer

This is the goodness of both :) . The most secure pointer.

const int* const data1 = arr1; // Const to both pointer and data
data1 = arr2;    // ERROR: can't change the pointer
data1[0] = 100; // ERROR: can't change the data

Using Ribbon Editor to design the Ribbon for your application

Visual Studio 2010 has integrated the new Ribbon Designer for MFC Applications. Previously I blogged about integrating ribbon with the MFC application and adding even handlers to get the notifications. But the developer must visualize the ribbon while scripting the ribbon code. But using the new Ribbon Designer, we can design ribbons designer, just like the menu designer.


Please check the following links to explore more.
How to integrate a simple ribbon with your MFC Application?
How to handle Ribbon Control Events?
Ribbon designer (MSDN)

Proudly powered by WordPress
Theme: Esquire by Matthew Buchanan.