1

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.).

ubaabd
  • 435
  • 2
  • 13
  • According to the documenation https://learn.microsoft.com/en-gb/cpp/mfc/reference/cdc-class#rectangle the coordinates passed here are **logical coordinates**. An answe here qualifies what logical coordinates are: https://stackoverflow.com/questions/15862205/confused-between-logical-coordinates-and-device-coordinates-in-windows-api – Andrew Truckle Jul 30 '18 at 15:56
  • Show the entire code needed to reproduce this effect. Show all of the code for static control class, plus the relevant code in the parent window (or parent dialog) where the static control is created or subclassed. You should call `CStatic::OnPaint();` first. – Barmak Shemirani Jul 30 '18 at 17:39
  • You should *really* be using a [CPaintDC](https://learn.microsoft.com/en-us/cpp/mfc/reference/cpaintdc-class). Among others, it sets up the correct clipping region, as well as validates the dirty area. You need to have a good reason to not use a `CPaintDC`. From the code posted, it doesn't appear that you do. – IInspectable Jul 30 '18 at 17:46
  • @BarmakShemirani Calling CStatic::OnPaint() did the job. If you please post the answer, I'll accept it. Thanks. – ubaabd Jul 31 '18 at 10:25
  • I would have thought there is a different problem, for example static control is initially created at x/y coordinates 0/0 and painted at that location, then the control is move to a different location. – Barmak Shemirani Jul 31 '18 at 15:47

1 Answers1

0

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));
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77