mfc bitmap reads a completely black bitmap

雨燕双飞 提交于 2021-01-28 18:40:13

问题


I want to use a bitmap to read the current view window, make some changes to it and output the bitmap back to the view. The program is supposed to read a white window and draw a square against this background. However, the image that I see in the final window is a square in a black background.

void CScribbleView::OnLButtonDown(UINT, CPoint point) 
{
    //CClientDC dc(this);
    //OnPrepareDC(&dc);
    HBITMAP initialMap;
    RECT t;
    BITMAP bmpScreen;
    GetClientRect(&t);
    initialMap = CreateCompatibleBitmap(GetDC()->m_hDC,t.right-t.left,t.bottom-t.top);        
    HDC tempDC = CreateCompatibleDC(GetDC()->m_hDC);
    SelectObject(tempDC,initialMap);
    SelectObject(tempDC,getStockObject(BLACK_PEN);
    SelectObject(tempDC,GetStockObject(WHITE_BRUSH));
    Rectangle(tempDC,100,100,200,200);
    BitBlt(GetDC()->m_hDC,clientR.left,clientR.top,clientR.right-clientR.left,t.bottom-clientR.top,tempDC,0,0,SRCCOPY);
}

This is the output:

I suspect that the bitmap was not properly read from my original DC. So I later decided to use a different way of retrieving DC, the CClientDC, instead of GetClientDC()->m_hDC.

void CScribbleView::OnLButtonDown(UINT, CPoint point) 
{
    CClientDC dc(this);
    OnPrepareDC(&dc);
    HBITMAP initialMap;
    RECT t;
    BITMAP bmpScreen;
    GetClientRect(&t);
    initialMap = CreateCompatibleBitmap(dc.m_hDC,t.right-t.left,t.bottom-t.top);        
    HDC tempDC = CreateCompatibleDC(dc.m_hDC);
    SelectObject(tempDC,initialMap);
    SelectObject(tempDC,getStockObject(BLACK_PEN);
    SelectObject(tempDC,GetStockObject(WHITE_BRUSH));
    Rectangle(tempDC,100,100,200,200);
    BitBlt(dc.m_hDC,clientR.left,clientR.top,clientR.right-clientR.left,t.bottom-clientR.top,tempDC,0,0,SRCCOPY);
}

Now, the new program doesn't show anything; it is the same white background as I had originally started with. What is the difference between these two DC's and how can I fix my problem?


回答1:


These WinAPI functions all require cleanup: ::CetDC, ::CreateCompatibleDC, ::CreateCompatibleBitmap. See documentation for each of them. Without cleanup, your program could quickly use its 10,000 GDI resource limit and crash.

You don't have to worry about cleanup if you use the MFC version of these WinAPI functions (you should still see the docs to make sure). This is MFC example for double-buffering:

void foo::OnLButtonDown(UINT nFlags, CPoint point)
{
    CWnd::OnLButtonDown(nFlags, point);

    CClientDC dc(this); 

    CRect rect; 
    GetClientRect(&rect); 

    //create memory dc 
    CDC memdc;
    memdc.CreateCompatibleDC(&dc);
    CBitmap bitmap; 
    bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); 
    memdc.SelectObject(bitmap); 

    //some random drawings:
    memdc.SelectObject(GetStockObject(BLACK_PEN)); 
    memdc.SelectObject(GetStockObject(GRAY_BRUSH)); 
    memdc.Rectangle(10, 10, 100, 100); 

    //draw memory DC to destination DC
    dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
}; 

Your goal is probably to draw on screen buffer, as suggested in comments. In which case you declare memdc and bitmap as member data:

//declare member data
CDC m_memdc;
CBitmap m_bitmap;
CRect m_rect;
CPoint m_point;

void foo::initialize_once()
{
    ASSERT(IsWindow(m_hWnd));
    GetClientRect(&m_rect);
    //create memdc
    m_memdc.CreateCompatibleDC(0);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(&m_memdc, m_rect.Width(), m_rect.Height());
    m_memdc.SelectObject(bitmap);
    //initialize memdc background color
    m_memdc.FillSolidRect(m_rect, RGB(255,255,255));
}

void foo::OnLButtonDown(UINT nFlags, CPoint point)
{
    __super::OnLButtonDown(nFlags, point);
    m_point = point;
    m_memdc.MoveTo(point);
};

void OnMouseMove(UINT nFlags, CPoint point)
{
    __super::OnMouseMove(nFlags, point);
    if (!(nFlags & MK_LBUTTON)) return;
    m_point = point;
    m_memdc.LineTo(point);
    CClientDC dc(this);
    dc.BitBlt(0, 0, m_rect.Width(), m_rect.Height(), &m_memdc, 0, 0, SRCCOPY);
}   


来源:https://stackoverflow.com/questions/37873650/mfc-bitmap-reads-a-completely-black-bitmap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!