c++visual-c++mfcevent-handlingonpaint

Rectangle not showing on OnPaint MFC


I have a dialog based application written in c++ and MFC. The dialog has a CStatic picture control. I am drawing a BITMAP in the OnPaint() function of the PictureCtrl. The relevant code is as follows:

void PictureCtrl::OnPaint()
{
    CDC* pDC = this->GetDC();
    pDC->SelectStockObject(PS_SOLID);
    pDC->Rectangle(CRect(0, 0, 400, 400));
    ReleaseDC(pDC);

    CStatic::OnPaint();
}

When the application runs, the rectangle is drawn right on the top-left corner of the dialog, and not the picture control.

enter image description here

Secondly, if I minimize and maximize the dialog window, the image shows up, but the rectangle doesn't.

However, if I hover the mouse in the windows taskbar and a tooltip appears on the icon of the dialog application, the rectangle shows up.

enter image description here

I want to show the rectangle over the image no matter what the user does to the window (minimize, maximize, move, etc.).


Solution

  • CStatic::OnPaint handles BeginPaint/EndPaint (main WinAPI functions) in response to WM_PAINT message. Therefore it should be called first. Moreover, you can use CClientDC which has automatic clean up:

    void PictureCtrl::OnPaint()
    {
        CStatic::OnPaint();
        CClientDC dc(this); //<- uses GetDC
        dc.SelectStockObject(BLACK_PEN);
        dc.Rectangle(CRect(0, 0, 400, 400));
    } //<- ReleaseDC is automatically called
    

    Better yet, use CPaintDC directly in response to WM_PAINT message:

    void PictureCtrl::OnPaint()
    {
        CPaintDC dc(this); //<- calls `BeginPaint`
        dc.SelectStockObject(BLACK_PEN);
        dc.Rectangle(CRect(0, 0, 400, 400));
    } //<- EndPaint is automatically called
    

    Unrelated, use BLACK_PEN as parameter for SelectStockObject. Use PS_SOLID as parameter for CPen:

    CPen pen(PS_SOLID, 1, RGB(0,0,0));