2016-12-03 1 views
0

OnEraseBkgnd() 다른 함수에서 창을 다시 그리는 것을 시도하고있다. 아래의 코드와 같은 예를 들어OnEraseBkgnd()를 호출하여 다른 함수에서 창을 다시 칠하는 방법? (MFC)

: 위의 예에서

... 

CBitmap Background; 
BITMAP bm; 
CDC dcMemory; 
int width, height; 

... 

BOOL CSplashDlg::OnInitDialog() 
{ 
    CDialog::OnInitDialog(); 

    CDC* dc; 

    Background.LoadBitmap(IDB_COVER); //Load Bitmap 
    Background.GetBitmap(&bm);  //Load Bitmap into handle 

    width = 0; 
    height = 0; 

    while(width < 300) 
    { 
     width += 10; 
     height += 10; 
     OnEraseBkgnd(dc);  //<--- Here I want to call OnEraseBkgnd() 

     Sleep(5);   //Delay 5 millisecond 
    } 

    return TRUE; 
} 



BOOL CSplashDlg::OnEraseBkgnd(CDC* pDC) 
{ 
    /////////////////////////////////// 
     Invalidate();    //I don't know where I should put this function 
    /////////////////////////////////// 

    dcMemory.CreateCompatibleDC(pDC); 
    CBitmap *pOldbmp = dcMemory.SelectObject(&Background); 

    pDC->SetStretchBltMode(HALFTONE); 

    pDC->StretchBlt(0, 0, width, height, &dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); 

    return TRUE; 
} 

, 나는 OnInitDialog() 내에서 실행하는 동안 창을 다시 칠하는 OnEraseBkgnd()를 호출합니다. 나는 인터넷을 검색했으며, 항상 Invalidate(); 또는 RedrawWindow();을 사용하여 다시 칠해 야한다고 말하면 OnEraseBkgnd() 함수를 호출합니다. 질문 : Invalidate(); 또는 RedrawWindow();은 어떻게 사용해야합니까? 어디에서 그 기능을 넣어야합니까?

나는이 두 가지 기능을 어느 곳에 나 두었지만 여전히 작동하지 않습니다.

편집 :

나는 그것을 수정했습니다. 현재 Invalidate()UpdateWindow()OnEraseBkgnd() 함수를 호출하는 데 성공했습니다. 그러나 또 다른 문제점을 발견했습니다 : Invalidate() 또는 UpdateWindow()을 사용하여 다시 그렸지만 FillSolidRect 작업을했을 때 왜 StretchBlt이 작동하지 않았습니까?

... 

BOOL CMainDlg::OnInitDialog() 
{ 
    CSplashDlg Frame; 

    Frame.width = 0; 
    Frame.height = 0; 

    while(Frame.width <= 300) 
    { 
     Frame.width += 10; 
     Frame.height += 10; 

     Frame.Invalidate();  //<---Here I use both Invalidate() and UpdateWindow() 
     Frame.UpdateWindow();  //<---Here I use both Invalidate() and UpdateWindow() 

     Sleep(5);   //Delay 5 millisecond 
    } 

    CDialog::OnInitDialog(); 

    return TRUE; 
} 

BOOL CSplashDlg::OnInitDialog() 
{ 
    CDialog::OnInitDialog(); 

    width = 0; 
    height = 0; 

    Background.LoadBitmap(IDB_COVER); //Load Bitmap 
    Background.GetBitmap(&bm);  //Load Bitmap into handle 


    return TRUE; 
} 



BOOL CSplashDlg::OnEraseBkgnd(CDC* pDC) 
{ 
    dcMemory.CreateCompatibleDC(pDC); 
    CBitmap *pOldbmp = dcMemory.SelectObject(&Background); 

    /////////////////////////////////////////////////////////////// 
    pDC->SetStretchBltMode(HALFTONE); 
    pDC->StretchBlt(0, 0, width, height, &dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);  //It doesn't work when using this one (StretchBlt) 
    /////////////////////////////////////////////////////////////// 
    pDC->FillSolidRect(0, 0, width, height, RGB(255,0,0));      //But it works when using this one (FillSolidRect) 
    /////////////////////////////////////////////////////////////// 

    return TRUE; 
} 

... 
+0

http://stackoverflow.com/questions/2183649/what-is-invalidate-update-methods-do-in-vc – Ripi2

+0

대화 상자는 'OnInitDialog'가 반환 될 때까지 보이지 않습니다.'OnInitDialog'에서 할 수있는 일은 5 밀리 초'SetTimer (1, 5, 0)'에 대한 타이머를 만들고 메시지 맵에 ON_WM_TIMER를 추가 한 다음 OnTimer (UINT_PTR)에'Invalidate()'를 호출하는 것입니다. 'OnEraseBkgnd'가 아닌'OnPaint'에서 페인팅을하십시오. –

+0

두번째 편집에서,'Frame-> Invalidate' 후에 Windows 메시지가 차단되고, 시스템이 여전히 남아 있기 때문에 창을 업데이트하지 않는다는 점을 제외하면 모든 것이 정확합니다 (WM_INITDIALOG'). 그 뒤에 'UpdateWindow'를 호출하면 Windows가 메시지를 처리하도록 유도하기를 원하지만 여전히 메시지를 처리하지는 않습니다. 유일한 옵션은 메시지 큐에있는 현재 메시지를 처리하기 위해 ('PeekMessage'와 함께) 메시지 루프를 삽입하는 것이지만주의해야합니다. 또는 'WM_TIMER'를 사용하여 이것을 수행하십시오 –

답변

1

당신은 OnEraseBkgnd()OnPaint()의 좋아하는 전화를해서는 안됩니다. MFC는 드로잉이 필요할 때이를 호출합니다. 귀하의 임무는 OnEraseBkgnd()에 그릴 필요를 처리하는 것입니다.

MFC가 도면 영역을 업데이트하게하고 OnEraseBkgnd()OnPaint()을 호출합니다. 이 OnPaint() 또는 OnEraseBkgnd() 인 경우 프로그램이 멈추는 반복적 인 루프 다시 그리기가 발생할 가능성이 있습니다.

에 으로 전화 할 수는 있지만 불필요한 것 같습니다.

OnEraseBkgnd() 중에서 무효화를 취하십시오. OnEraseBkgnd()OnInitDialog()에 전화하지 말고 거기에서 이동하십시오.

는 또한 MFC에 의해 호출되는 사람들을 위해 메시지 맵에

ON_WM_PAINT() ON_WM_ERASEBKGND()

을 가지고 있습니다.

참고 : 저는 바퀴의 재발 명을 믿는 사람이 아닙니다. 그것은 대부분 이전에 이루어졌습니다. 내 프로젝트에 스플래시 화면을 사용하지 않았지만, 시작했다면 여기에서 시작하겠다 : Splash Screen C++ Class using MFC.

코드를 다운로드 및 검토하지는 않았지만 별 4 개로 시작하는 것이 좋습니다. MFC는 야간 학습이 아닙니다. 내가 시작할 때 배울 수있는 책과 수많은 검색을 읽었습니다. 인프라가 어떻게 작동하는지 추측 할 수 없습니다. 희망이 ...

+0

'OnInitDialog()'에'Invalidate()'를 넣고 메시지 맵에'ON_WM_ERASEBKGND()'를 추가했지만 여전히 아무것도 다시 칠하지 않습니다. –

+0

@BananaCode'Invalidate'를 호출하면 다시 칠하기위한 창이 표시됩니다. 무효화 한 후에'UpdateWindow'를 호출 할 필요가있는 변경을 보려면 무효화하고'RedrawWindow'를 호출하거나 무효화 한 후에 메시지 루프를 실행하십시오. – 1201ProgramAlarm

+0

다른 문제가 발견되었습니다 : 왜'StretchBlt'가'Invalidate()'또는'UpdateWindow()'를 사용할 때 작동하지 않았지만'FillSolidRect'가 작동 했나요? 이 코드는 업데이트 된 내용에 있습니다. –

관련 문제