|
-
April 24th, 2005, 09:26 PM
#1
Screen flicker problem? InvalidateRect()
I have some problem with screen flicker, I copy one image from hard disk to view, and draw one circle on the screen, when I move the circle using direction arrow of keyboard, there is flicker problem because redrawing the whole screen. So I called the function InvalidateRect() to redraw specific rectangular, but it seems no action. the following is my code, can you please give some suggestion?
Thanks in advance!
void MyView::OnDraw(CDC* pDC)
{
CString szFilename("c:\\image.bmp");
HBITMAP hBmp = (HBITMAP)::LoadImage(NULL,szFilename,
IMAGE_BITMAP,0,0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);
CBitmap bmp;
bmp.Attach(hBmp);
CClientDC dc(this);
CDC bmDC;
bmDC.CreateCompatibleDC(&dc);
CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
BITMAP bi;
bmp.GetBitmap(&bi);
dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);
dc.SelectObject(pOldbmp);
DrawCircle(pDC);
}
void MyView: rawCircle(CDC *pDC)
{
CPen *penold, pennew;
pennew.CreatePen(PS_DOT,1,RGB(255,255,255));
penold=pDC->SelectObject(&pennew);
CBrush *pBrhold, Brhnew;
Brhnew.CreateStockObject(NULL_BRUSH);
pBrhold=pDC->SelectObject(&Brhnew);
m_tracker.AdjustRect(false,&m_tracker.m_rect);
m_tracker.m_rect.bottom=m_tracker.m_rect.top+m_tracker.m_rect.right -m_tracker.m_rect.left;
m_tracker.AdjustRect(true,&m_tracker.m_rect);
pDC->Ellipse(m_tracker.m_rect);
pDC->SelectObject(penold);
pDC->SelectObject(pBrhold);
pennew.DeleteObject();
}
void MyDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CRect rcClient;
p_view->GetClientRect(&rcClient);
rcClient.top=rcClient.top/2;
if(nChar==VK_LEFT)
{
p_view->m_tracker.m_rect.left-=1;
p_view->m_tracker.m_rect.right-=1;
InvalidateRect(rcClient);
//Invalidate();
}
}
-
April 24th, 2005, 09:49 PM
#2
Re: Screen flicker problem? InvalidateRect()
 Originally Posted by berrywong
I have some problem with screen flicker, I copy one image from hard disk to view, and draw one circle on the screen, when I move the circle using direction arrow of keyboard, there is flicker problem because redrawing the whole screen. So I called the function InvalidateRect() to redraw specific rectangular, but it seems no action. the following is my code, can you please give some suggestion?
A few things:- Calling InvalidateRect() instead of Invalidate() makes no difference if you pass the entire client rect - actually, that's exactly what Invalidate does (calling InvalidateRect with the entire client rect). It only makes sense if you call it for a smaller rectangle (e.g. your circle's bounds, but note that you would have to call that twice: Before the move, and after the move).
- Why are you creating a CClientDC in OnDraw()? You should use the readily prepared CPaintDC you are getting as the pDC parameter.
- To completely avoid flickering, I would suggest to handle WM_ERASEBKGND, and return TRUE. You could also pass FALSE as the second parameter to InvalidateRect(), preventing the background from being drawn.
-
April 24th, 2005, 09:59 PM
#3
Re: Screen flicker problem? InvalidateRect()
Hi,
 Originally Posted by berrywong
void MyDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CRect rcClient;
p_view->GetClientRect(&rcClient);
rcClient.top=rcClient.top/2;
if(nChar==VK_LEFT)
{
p_view->m_tracker.m_rect.left-=1;
p_view->m_tracker.m_rect.right-=1;
InvalidateRect(rcClient);
//Invalidate();
}
}
rcClient.top = rcClient.top / 2 could be a problem. The top of the client is 0.
Another thing is that InvalidateRect() is being called for the dialog and not the view.
Jay
-
April 24th, 2005, 10:29 PM
#4
Re: Screen flicker problem? InvalidateRect()
Thank you so much for your suggestions, gstercken! I have changed code as below, but flicker in specific rectangular area (rcClient) is still visible . Is there effective method to eliminate flicker completely?
void MyDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CRect rcClient(0,250,600,350);
if(nChar==VK_LEFT)
{
p_view->m_tracker.m_rect.left-=1;
p_view->m_tracker.m_rect.right-=1;
InvalidateRect(rcClient, false);
//Invalidate();
}
}
-
April 24th, 2005, 10:32 PM
#5
Re: Screen flicker problem? InvalidateRect()
yes, it should be corrected as rcClient.top=rcClient.right/2!
-
April 25th, 2005, 12:26 AM
#6
Re: Screen flicker problem? InvalidateRect()
I inserted the following, it still flicker!
BOOL BIPTTestView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return true;//CView::OnEraseBkgnd(pDC);
}
BOOL BIPTTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Add your specialized code here and/or call the base class
cs.lpszClass = AfxRegisterWndClass(0);
return CView::PreCreateWindow(cs);
}
-
April 25th, 2005, 01:21 AM
#7
Re: Screen flicker problem? InvalidateRect()
Handle WM_ERASEBKGND as gstercken suggested.
Consider to use "double buffering". Should be easy in your case:
Code:
CClientDC dc(this);
CDC bmDC;
bmDC.CreateCompatibleDC(&dc);
CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
// Draw the circle on the bitmap.
DrawCircle(&bmDC);
BITMAP bi;
bmp.GetBitmap(&bi);
// Blt the whole bitmap including circle to the output dc.
dc.BitBlt(0,0,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);
dc.SelectObject(pOldbmp);
Also, consider to buffer the image to avoid reading it on every paint.
Last edited by Oliver M.; April 25th, 2005 at 01:25 AM.
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
|