2016-06-17 5 views
1

비트 맵을 사용하여 현재보기 창을 읽고, 비트 맵을 변경하고, 비트 맵을 다시보기로 출력하고 싶습니다. 이 프로그램은 흰색 창을 읽고이 배경에 사각형을 그려야합니다. 그러나 최종 창에서 볼 수있는 이미지는 검정색 배경의 사각형입니다. 내가 비트 맵이 제대로 내 원래 DC에서 읽을 수 없습니다 것으로 의심 mfc 비트 맵 완전히 검은 비트 맵을 읽습니다.

:

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); 
} 

이 출력됩니다. 그래서 나중에 GetClientDC() -> m_hDC 대신 CClientDC 인 DC를 검색하는 다른 방법을 사용하기로 결정했습니다.

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); 
} 

이제 새 프로그램에는 아무 것도 표시되지 않습니다. 그것은 원래 내가 시작했던 것과 같은 흰색 배경입니다. 이 두 직류의 차이점은 무엇이며 어떻게하면 문제를 해결할 수 있습니까?

+0

좋아, createCompatibleBitmap 기능은 클라이언트 창에 같은 이미지가 포함 된 비트 맵을 생성하지 않는 것 같다. 대신 모든 픽셀 색상이 0으로 초기화 된 클라이언트 윈도우의 크기 인 이미지를 만듭니다 (검정색). – varimax

+0

현재보기 창을 읽는 것은 어쨌든 나쁜 생각입니다. 당신은 실제로 무엇을 성취하려고합니까? –

+0

긴 이야기입니다. 나는 그림판 같은 드로잉 프로그램을하고있다. 지금 나는 직사각형 그리기 작업을하고 있습니다. 원래 마우스를 누르고 드래그하면 OnMouseMove 함수에 새 사각형을 그립니다. 그러나, 뒤쳐진 직사각형의 잔뜩 나뭇잎. 그래서 마우스를 눌렀을 때 클라이언트 뷰를 비트 맵에 저장하기로 결정했습니다. OnMouseMove 함수에서 나는 드래그 작업으로 생성 된 이전 직사각형을 덮어 저장 한 뷰의 맨 위에 그릴 것입니다. – varimax

답변

1

이러한 WinAPI 기능을 모두 정리해야합니다 : ::CetDC, ::CreateCompatibleDC, ::CreateCompatibleBitmap. 각각의 문서를 참조하십시오. 정리가 없으면 프로그램이 10,000 개의 GDI 리소스 제한을 빠르게 사용하고 충돌 할 수 있습니다.

이러한 WinAPI 기능의 MFC 버전을 사용하는 경우 정리를 염려 할 필요가 없습니다. 그래도 확인하려면 문서를 계속 볼 수 있습니다. 이 더블 버퍼링 MFC의 예는 다음과 같습니다 의견 제안

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); 
}; 

당신의 목표는, 화면 버퍼에 그리는 아마. 이 경우에 당신은 구성원 데이터로 memdcbitmap를 선언 :

//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); 
} 
+0

정말 고마워요! – varimax

+0

또 하나의 질문입니다. 일반적으로 CDC 또는 CClientDC에서 HDC를 사용하는 것이 좋지 않습니까? 예 : 직사각형 (m_memdc.m_hDC, 100100200200). – varimax

+0

그건 문제가되지 않습니다. 또한'm_memdc.Rectangle (100100200200)'을 사용하여':: Rectangle (m_memdc.m_hDC, 100100200200)'이라는 핵심 WinAPI 함수를 호출 할 수 있습니다. –

관련 문제