3

Using the function

OnEraseBkgnd(CDC* pDC)

I write on the CDialog derived class, a background image that fills the screen.

Then inside the OnPaint I have the following code that is executed only once (for the 1st time OnPaint is called).

    GetInfoBarRect(&m_InfoBarRect);
    m_InfoBarBGBitmap.CreateCompatibleBitmap(&dc, m_InfoBarRect.Width(), m_InfoBarRect.Height() );

    bdc.CreateCompatibleDC(&dc);    
    pOldBitmap = bdc.SelectObject(&m_InfoBarBGBitmap);

    bdc.BitBlt (m_InfoBarRect.left, m_InfoBarRect.top, m_InfoBarRect.Width(),m_InfoBarRect.Height(), &dc, 0, 0, SRCCOPY);



    CImage image;
    image.Attach(m_InfoBarBGBitmap);
    image.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);

    bdc.SelectObject(pOldBitmap);   
    bdc.DeleteDC();

The above code, copies the m_InfoBarRect part of the screen in the memory CBitmap.

Intead of having the part of the background image, I only get a blank filled rectangle with correct dimensions.

Is there something wrong with my code ?

Maverick
  • 1,105
  • 12
  • 41

2 Answers2

3

You are blitting from the wrong coordinate to the wrong coordinate. Your call should be

bdc.BitBlt( 0, 0, m_InfoBarRect.Width(), m_InfoBarRect.Height(), &dc,
            m_InfoBarRect.left, m_InfoBarRect.top, SRCCOPY);

instead, i.e. blitting from the correct source position (m_InfoBarRect.left/m_InfoBarRect.top) to the destination's origion (0/0). This is assuming, that GetInfoBarRect() returns coordinates from the same coordinate system as your source DC.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • Yeap !! That was the error. I had to read more carefully the manual before I write the code. – Maverick Jun 03 '16 at 20:07
  • @Maverick: Your bitmap had the correct dimensions, because those are the dimensions you passed into the `CreateCompatibleBitmap` call. This is not strictly related to the `BitBlt` operation, and that's why you got something that appeared to work halfway through. – IInspectable Jun 03 '16 at 20:11
0

I think you might want:

bdc.CreateCompatibleDC(&dc);    
pOldBitmap = bdc.SelectObject(&m_InfoBarBGBitmap);

dc.BitBlt (m_InfoBarRect.left, m_InfoBarRect.top, m_InfoBarRect.Width(),m_InfoBarRect.Height(), &bdc, 0, 0, SRCCOPY);
Ryan
  • 314
  • 1
  • 10
  • Hi, the 5th paramater is the source pSrcDC. So, the source should be the screen and not the bitmap itself. https://msdn.microsoft.com/en-us/library/fcbk8779.aspx – Maverick Jun 03 '16 at 19:42
  • You have your device context 'bdc' . You select your source bitmap into that device context. Then you draw the bitmap onto your new device context, dc, which you created to be compatible with your bdc. I'm not sure if I'm misunderstanding your issue, but I have multiple places where I've implemented exactly as above. – Ryan Jun 03 '16 at 19:59
  • My device context of the screen is named *dc* and the bitmap device context *bdc*. You described those with the wrong order. – Maverick Jun 03 '16 at 20:01
  • @Ryan: You've got everything backwards: `bdc` is a memory device context, compatible with the source DC (`dc`). Into this memory DC a bitmap, compatible with the source DC is selected. This bitmap will eventually store a copy of the source DC (`dc`) after the `BitBlt`. – IInspectable Jun 03 '16 at 20:06