CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2009
    Posts
    3

    Resolved MFC: double buffering text

    Hello all,
    I just started with MFC and Document/View architecture and have a problem with displaying text which changes quite often.

    There's the setup:

    1. A packet source sends me about 10 packets in a second.

    2. I read and parse the data in a worker thread in Document.

    3. When I decide it's time to refresh displayed data, I send a message to Main Frame, which reposts the message to View, where I call InvalidateRect() on rectangles with new data.

    4. In OnDraw I just call a member function of Document which gets a CDC and rectangle and does all the drawing:

    void CSimView::OnDraw(CDC* pDC)
    {
    CSimDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here

    CRect clientRectangle;

    GetClientRect(clientRectangle);

    SetScrollSizes(MM_TEXT, pDoc->DrawSelection(pDC, clientRectangle));

    ReleaseDC(pDC);

    }

    (NOTE: DrawSelection returns CSize containing dimensions of scrolling window)

    5. in the DrawSelection I select from several drawing funcions to display a screen selected by user:

    CSize CSimDoc:rawSelection(CDC *pDC, CRect clientRect)
    {

    //vector storing rectangles to be redrawn
    //will be filled in selected function
    m_rectanglesToRedraw.clear();

    if(m_displayMode == PKT)
    {
    return DrawPackets(pDC, clientRect);
    }
    else if(m_displayMode == LOG)
    {
    return DrawVaultText(pDC, clientRect);
    }
    else
    {
    return DrawCommunicationData(pDC, clientRect);
    }

    }

    6. i try to double buffer a text in the selkected function and display it, for example:

    CSize CSimDoc:rawPackets(CDC *pDC, CRect clientRect)
    {

    //SNIP some defines etc

    CDC cdc;
    CBitmap bitmap;

    cdc.CreateCompatibleDC(pDC);

    bitmap.CreateCompatibleBitmap(pDC,clientRect.right,clientRect.bottom);

    CBitmap *pOldBitmap = cdc.SelectObject(&bitmap);

    //locking crit section
    CSingleLock singleLock(m_addPacketCriticalSection);
    singleLock.Lock();

    //SNIP using some text drawing functions on cdc, like TextOut, and SetTextColor

    pDC->BitBlt(0, 0, clientRect.right,clientRect.bottom, &cdc, 0, 0, SRCCOPY);
    //cdc.SelectObject(pOldBitmap);

    DeleteObject(pOldBitmap);

    //define rectangles for redrawing
    m_rectanglesToRedraw.push_back(CRect(CPoint(PKT_TIME_OFFSET, PKT_Y_AXIS_OFFSET),
    CSize(PACKET_SIZE*30, PKT_ARR_SIZE*20)));

    singleLock.Unlock();

    //define scrolling window
    sizeTotal.cx = PACKET_SIZE*3*8;
    sizeTotal.cy = (PKT_ARR_SIZE + 5)*20;

    return sizeTotal;
    }


    There are two problems. I was searching the web for some useful help but found nothing:

    PROBLEM 1: double buffering doesn't help at all with terrible flickering. It seems to be worse than before when I was writing directly into the pDC.

    PROBLEM 2: the text is black on white background but everything but the text and it's closest background is black.

    Last snippet - this is the function I use to redraw:

    LRESULT CSimView::OnUpdateViewMessage(WPARAM wParam, LPARAM lParam)
    {


    UpdateWindow();
    return 0;

    //redraw everything if wParam is nonzero
    if(wParam)
    {
    Invalidate();
    return 0;
    }

    std::vector<CRect> invRectVect;

    CSimDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    invRectVect = pDoc->GiveRectToUpdate();

    //invalidate only specific rectangles
    for(int i = 0; i < invRectVect.size(); i++) InvalidateRect(invRectVect[i]);

    return 0;
    }


    TYVM in advance for some hints.

  2. #2
    Join Date
    Oct 2009
    Posts
    3

    Re: MFC: double buffering text

    ...ooops. Can somebody tell me, too, how to display a code properly here? Looks like all indentation is lost and some parts are replaced with smileys.

  3. #3
    Join Date
    Oct 2009
    Posts
    3

    Re: MFC: double buffering text

    And one more edit: the redrawing function I displayed was wrong, I posted a version where I was trying what would UpdateWindow do. Here goes the correct version:

    LRESULT CSimView::OnUpdateViewMessage(WPARAM wParam, LPARAM lParam)
    {

    //redraw everything if wParam is nonzero
    if(wParam)
    {
    Invalidate();
    return 0;
    }

    std::vector<CRect> invRectVect;

    CSimDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    invRectVect = pDoc->GiveRectToUpdate();

    //invalidate only specific rectangles
    for(int i = 0; i < invRectVect.size(); i++) InvalidateRect(invRectVect[i]);

    return 0;
    }

  4. #4
    Join Date
    Feb 2005
    Posts
    2,160

    Re: MFC: double buffering text

    For code use [code] [/code] tags around your code:

    [code]
    int main(void)...
    [/code]

    gives:
    Code:
     
      int main(void)...
    I haven't analyzed your code in any detail, but for double buffering to work, you also need to prevent erasing the background. Override WM_ERASEBKGND (OnEraseBkgnd) and simply return TRUE. This tells the default message handler that you've handled the message yourself and it will forgo any other processing (which would normally include filling the client area with the background color).

    See the MFC sample DRAWCLI for a good example of double buffering in a CScrollView class.

    http://msdn.microsoft.com/en-us/libr...8VS.80%29.aspx

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured