Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Solved] Rectangle smaller when drawn with GDI CDC from QPaintEngine



  • Hi cute world :-)

    I have an MFC dialog application using MFC migration framework 2.8.1.
    I have an implementation of QPaintDevice and QPaintEngine to draw with Windows GDI and CDC.
    In my CDialog::OnPaint() method, when I draw a QRect square with a length of 10 like this :
    @
    QRect rect1(100, 80, 10, 10);
    p.fillRect(rect1, QBrush(QColor("#FF0000")));
    @

    the result on screen is a square with a length of 9 even if I implement the void CPaintEngineCDC::drawRects like
    this :
    @
    void CPaintEngineCDC::drawRects ( const QRect * rects, int rectCount )
    {
    for (int i=0; i < rectCount; i++)
    m_dc->Rectangle(rects[i].left(), rects[i].top(), rects[i].right()+1, rects[i].bottom()+1);
    }
    @

    knowing that the GDI Rectangle method does not include the right and bottom coordinates (Note the "+1" for right and bottom).

    Any idea please?

    Thanks in advance and regards.
    Pascal


  • Moderators

    Are you setting a QPen?



  • No QPen is set.
    And my implementation of "QPaintEngine::updateState ( const QPaintEngineState & state )" for DirtyPen is:
    @
    case Qt::NoPen:
    m_dc->SelectStockObject(NULL_PEN);
    @



  • Here is the solution after several investigation and testing.
    Setting NULL_PEN with CDC makes a CDC.Rectangle have its right and bottom borders transparent.
    Then, here are 2 possible implementation of CPaintEngineCDC::drawRects.

    • 1st solution using CDC::Rectangle:
      @
      void CPaintEngineCDC::drawRects ( const QRect * rects, int rectCount )
      {
      LOGPEN lp;
      VERIFY(m_currentPen->GetLogPen(&lp) != 0);
      int iBorder = (lp.lopnStyle == PS_NULL ? 2 : 1);
      for (int i=0; i < rectCount; i++)
      {
      RECT r = { rects[i].left(), rects[i].top(), rects[i].right()+iBorder, rects[i].bottom()+iBorder };
      m_dc->Rectangle(&r);
      }
      }
      @

    • 2nd solution using CDC::fillRect:
      @
      void CPaintEngineCDC::drawRects ( const QRect * rects, int rectCount )
      {
      for (int i=0; i < rectCount; i++)
      {
      RECT r = { rects[i].left(), rects[i].top(), rects[i].right()+1, rects[i].bottom()+1 };
      m_dc->FillRect(&r, m_currentBrush);
      }
      }
      @

    Note that m_currentPen and m_currentBrush are set in my QPaintEngine::updateState() implementation.

    Dear mlong, thanks for your idea to check QPen setting!

    Bye
    Pascal


  • Moderators

    Be sure and edit your thread to add [Solved] to the title if you have it working. Glad you got it figured out!


Log in to reply