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

Why I can’t set cursor position on a child control during OnInitDialog?

One of my colleague asked me. “Why I can’t set the cursor position on a button during OnInitDialog? I need to set the cursor over a button inside the dialog during startup.” The snippet looks like below

BOOL CCursorPositionDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CRect rect;
	GetDlgItem( IDC_BUTTON2 )->GetWindowRect( rect );
	SetCursorPos(rect.left, rect.top );
}

The reason is, the Window initialization has not completed during OnInitDialog operation (even window is not displayed). Once after OnInitDialog returns, the dialog will be positioned, the input focus will be set the child control and finally the dialog is displayed. Also if you notice the, GetWindowRect returns incorrect window cordinate during OnInitDialog execution.

To solve this issue, it’s necessary to rely on other activation functions like WM_ACTIVATE or WM_WINDOWPOSCHANGED (only once) function

void CCursorPositionDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
	CDialog::OnActivate(nState, pWndOther, bMinimized);

	if( WA_ACTIVE == nState )
		SetMousePosition();
}

Alternate method (not recommended)

void CCursorPositionDlg::OnWindowPosChanged(WINDOWPOS* lpwndpos)
{
	CDialog::OnWindowPosChanged(lpwndpos);

 	static bool bFirst = true;
 	if( bFirst) { PositionButton(); bFirst = false;}
}

Proudly powered by WordPress
Theme: Esquire by Matthew Buchanan.