user13267
user13267

Reputation: 7193

What happens if I use CClientDC in OnPaint() function?

I am new to MFC and Windows programming in general and this is something I haven't understood
Everywhere I have been reading it says not to use CClientDC in OnPaint and only use CPaintDC
In my code, I append my rectangle drawing functions to the default OnPaint() handler created when I make a dialog based MFC application using the wizard

void Cgraph_on_dlgboxDlg::OnPaint()
{
    CPaintDC dc(this); // ----------------------------> LINE 1
    if (IsIconic())
    {
        // CPaintDC dc(this); // device context for painting // ----------------------------> LINE 2

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }

    COLORREF pencolour = RGB(0, 0, 0);
    COLORREF brushcolour = RGB(0, 0, 255);
    CPen pen(PS_SOLID, 5, pencolour);
    CBrush brush(HS_CROSS, brushcolour);
     // CPaintDC Dc(this);      // ----------------------------> LINE 3
     // CClientDC Dc(this);     // ----------------------------> LINE 4
    dc.SetBkMode(TRANSPARENT);
/****
get rectangle coordinates and properties
****/
    dc.Rectangle(CRect(point1, point2));
}

In this code, originally, LINE 1 doesn't exist. In this case, the program draws a rectangle if CClientDC is declared in LINE 4, but does not draw anything in CPaintDC in LINE 3 is enabled. If the CPaintDC in LINE 2 is removed to LINE 1 and LINE 3 and 4 are commented out, it works. Why is this happening? From what I understood, CClientDC should not work at all here, or am I missing something?
Again, shouldn't the CPaintDC in LINE 2 have it's scope within the if block only? Why does declaring CPaintDC twice create no output at all?

Upvotes: 0

Views: 1276

Answers (1)

ScottMcP-MVP
ScottMcP-MVP

Reputation: 10415

The CPaintDC constructor calls BeginPaint to get a DC that is clipped to the invalid area (the area that needs painting). Constructing a second CPaintDC gets an empty invalid area, so it can't paint anything.

The default code constructs a CPaintDC only at line 2 because it is not going to call CDialogEx::OnPaint when the dialog is minimized. When the dialog is not minimized then CDialogEx::OnPaint will construct a CPaintDC. One and only one CPaintDC can be used for any particlular call to OnPaint.

You can use CClientDC to paint your rectangle, as long as you leave the original treatment of CPaintDC as it was.

Upvotes: 1

Related Questions