Banana Code
Banana Code

Reputation: 817

How to call OnEraseBkgnd() to repaint the window in another function? (MFC)

I am trying to call OnEraseBkgnd() to repaint the window in another function.

For example, like the code below:

...

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

In the above example, I want to call OnEraseBkgnd() to repaint the window while executing inside OnInitDialog(). I have searched the Internet and it always says using Invalidate(); or RedrawWindow(); to repaint it and it'll also call the OnEraseBkgnd() function. The question is: How should I use the Invalidate(); or the RedrawWindow();? Where should I put those function?

I have put those two functions in anywhere but it still not works.

EDIT:

I have modified it. Though now Invalidate() and UpdateWindow() are success to call the OnEraseBkgnd() function. But I found another problem: Why didn't the StretchBlt work when I used Invalidate() or UpdateWindow() to repaint it but did the FillSolidRect work?

...

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

...

Upvotes: 1

Views: 5217

Answers (1)

lakeweb
lakeweb

Reputation: 1939

You should never call the likes of OnEraseBkgnd( ) and OnPaint( ). MFC will call these when drawing is needed. Your job is to handle the need to draw in OnEraseBkgnd( ).

Invalidate( ) causes MFC to update the drawing area and then it will call OnEraseBkgnd( ) and OnPaint( ). If you Invalidate( ) in OnPaint( ) or OnEraseBkgnd( ) the program will likely hang as it would cause an endless loop of redrawing the window.

You can call Invalidate( ) in OnInitDialog( ) but it is likely unnecessary.

So take the Invalidate out of OnEraseBkgnd( ), don't call OnEraseBkgnd( ) in OnInitDialog( ) and go from there.

You also have to have

ON_WM_PAINT( ) ON_WM_ERASEBKGND( )

in your message map for those to be called by MFC.

NOTE: I'm not a believer in reinventing wheels. It has mostly been done before. I have not used a splash screen in my projects, but if I were to, I would start here: Splash Screen C++ Class using MFC.

I didn't download and review the code but with four stars, it should be a good place to start. MFC is not an overnight learn. When I started I read books and tons of searches to learn. You just can not make guesses about how the infrastructure works. Hope this helps...

Upvotes: 3

Related Questions