0
votes

I want to output an BMP image onto the dialog or the screen from Resources.

Here's the code:

void CMainDlg::OnPaint()
{
        CBitmap bitmap;
        bitmap.LoadBitmap(IDB_BITMAP1);
        CDC *pDC;
        pDC = this->GetDC();
        HDC hDC = pDC->m_hDC;
        HDC hmemdc = CreateCompatibleDC(hDC);

        BITMAP BitMap;
        bitmap.GetBitmap(&BitMap);
        BitBlt(hDC,0,0,BitMap.bmWidth,BitMap.bmHeight,hmemdc,0,0,SRCCOPY);
        DeleteDC(hmemdc);
        DeleteObject(bitmap);
}

I am sure that the BMP image file was imported into Resources and named its ID “IDB_BITMAP1”.

But it doesn't output anything.

What's the problem?

EDIT:

After modifying:

void CMainDlg::OnPaint()
{
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_COVER);
    CPaintDC dc(this);
    HDC hDC = dc.m_hDC;
    HDC hmemdc = CreateCompatibleDC(hDC);
    SelectObject(hmemdc,&bitmap);

    BITMAP BitMap;
    bitmap.GetBitmap(&BitMap);
    BitBlt(hDC,0,0,BitMap.bmWidth,BitMap.bmHeight,hmemdc,0,0,SRCCOPY);
    DeleteDC(hmemdc);
    DeleteObject(bitmap);
}
1
Basic GDI knowledge. You need to select the bmp into the mem-dc, Also, you may not call GetDC() for painting (in response to the WM_PAINT message), instead call BeginPaint()/EndPaint() (or use CPaintDC in MFC). - Constantine Georgiou
@Constantine Georgiou I had tried your suggestions and the modified code is like above, but it still doesn't output anything. What's wrong with it? - Banana Code

1 Answers

0
votes

As noted in comments, don't use GetDC in OnPaint().

For ::SelectObject, the usage is ::SelectObject(hmemdc, bitmap.GetSafeHandle())

::SelectObject is WinAPI function, it doesn't know what to do with CBitmap pointer, therefore ::SelectObject(hmemdc, &bitmap) will fail.

DeleteObject(bitmap) is not necessary because CBitmap will automatically cleanup after itself.

In MFC, this is a better method:

void CMainDlg::OnPaint()
{
    CPaintDC dc(this);
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_COVER);

    CDC memdc;
    memdc.CreateCompatibleDC(&dc);
    CBitmap *oldbmp = memdc.SelectObject(&bitmap);

    BITMAP BitMap;
    bitmap.GetBitmap(&BitMap);
    dc.BitBlt(0, 0, BitMap.bmWidth, BitMap.bmHeight, &memdc, 0, 0, SRCCOPY);

    dc.SelectObject(oldbmp);
}

When selecting the bitmap in memory DC, keep a reference to the previous bitmap (oldbmp), then un-select that bitmap with dc.SelectObject(oldbmp) so that bitmap can be safely deleted.