Introduction
Have you ever had a nice reusable interface class that relied on an image? Have you ever wished that you could place that image right
inside your source file to make it easier to reuse that class in a new project or send it to a friend? Well, here's how ...
Background
Ever since I began MFC programming I have been building a library of reusable classes. Every once in a while I would create a user interface class that relied
on an image: a list control header sort image or a combo box button. I've always loved being able to drop 2 files into a project, add a #include line, and begin using
my class. Even though it is no big deal to copy a bitmap and add it to the resources before I could use it, I always wondered if there was a way to just put it right
in the source file. One day I was writing a font combo box class and I decided to figure it out.
Using the Code
Step 1: Temporarily add your bitmap to the project resources.
Step 2: Add a CBitmap
or CImageList
member variable to your class.
Step 3: Copy and paste this block of code into your class constructor and change the bitmap id to the correct one.
HBITMAP hBmp = ::LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
ASSERT(hBmp);
BITMAP bm;
::GetObject(hBmp, sizeof(BITMAP), &bm);
int iSize = ::GetBitmapBits(hBmp, 0, NULL);
BYTE* pBuffer = new BYTE[iSize];
ASSERT(pBuffer);
::GetBitmapBits(hBmp, iSize, pBuffer);
TRACE(_T("\n----------------------------------------------------------\n\n"));
TRACE(_T("static BYTE INL_BMP[] = { "));
for(int x = 0; x < iSize; x++)
TRACE1("0x%x, ", pBuffer[x]);
TRACE(_T("};\n"));
TRACE1(_T("const long lInlBmpWidth = %d;\n"), bm.bmWidth);
TRACE1(_T("const long lInlBmpHeight = %d;\n"), bm.bmHeight);
TRACE1(_T("const long lInlWidthBytes = %d;\n"), bm.bmWidthBytes);
TRACE1(_T("const long lInlBPP = %d;\n"), bm.bmBitsPixel);
TRACE(_T("static BITMAP g_bmInl = { 0, lInlBmpWidth,
lInlBmpHeight, lInlWidthBytes, 1, lInlBPP, INL_BMP };\n"));
TRACE(_T("\n\n----------------------------------------------------------\n"));
delete [] pBuffer;
Step 4: Start your project in debug mode and look at your debug output pane. You will see output similar to this:
----------------------------------------------------------
static BYTE INL_BMP[] = { 0x80, 0x80, ...,
const long lInlBmpWidth = 11;
const long lInlBmpHeight = 11;
const long lInlWidthBytes = 44;
const long lInlBPP = 32;
static BITMAP g_bmInl = { 0, lInlBmpWidth, ...
----------------------------------------------------------
Now copy the text between the two dashed lines and paste it at the top of your source file.
Step 5: You can now add the image loading code to your constructor. In this example the member variable is a CBitmap object (m_bmp)
:
VERIFY(m_bmp.CreateBitmapIndirect(&g_bmInl));
Step 6: Clean up time. Remove the TRACE
blocks from your source file and delete the bitmap from your resources.
History
- Initial version: 2013-11-14.