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