-
October 26th, 2009, 06:05 AM
#1
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.
-
October 26th, 2009, 06:08 AM
#2
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.
-
October 26th, 2009, 06:24 AM
#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;
}
-
October 26th, 2009, 08:22 AM
#4
Re: MFC: double buffering text
For code use [code] [/code] tags around your code:
[code]
int main(void)...
[/code]
gives:
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|