[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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.