我正在与SDI应用程序一起使用视图文件中的计时器重绘图形并更新数据。即使我使用ON_WM_ERASEBKGND消除了闪烁,但仍然会发生。下面是我尝试实现的代码。任何人都有消除闪烁的想法吗?
这是我的MSG_MAP
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
BOOL CVCDSOView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
return CView::OnEraseBkgnd(pDC);
}
void CVCDSOView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CRect Rect;
GetClientRect(&Rect);
CRect m_rcDraw = Rect;
// set timer with 200ms
SetTimer(ID_LABEL_COMPANY,200,NULL);
labelCompany.Create(_T("Company"), WS_CHILD | WS_VISIBLE,
CRect(LEFT_SIDE, TOP_SIDE, RIGHT_SIDE+50, BOTTOM_SIDE), this, ID_LABEL_COMPANY);
textboxCompany.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_NOHIDESEL,
CRect(LEFT_SIDE, TOP_SIDE+VERTICAL_OFFSET, RIGHT_SIDE+50, BOTTOM_SIDE+VERTICAL_OFFSET), this, ID_EDITTEXT_COMPANY);
}
// CVCDSOView message handlers
void CVCDSOView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect Rect;
GetClientRect(&Rect);
CDC dcMem;
CBitmap bmpMem;
dcMem.CreateCompatibleDC(&dc);
bmpMem.CreateCompatibleBitmap(&dc,Rect.Width()- GRID_LEFT,Rect.Height()-35);
dcMem.SelectObject(&bmpMem);
dcMem.FillSolidRect(Rect, RGB(255,255,255));
CRect m_rcDraw = Rect;
m_rcDraw.DeflateRect(GRID_LEFT,GRID_TOP,GRID_RIGHT,GRID_BOTTOM);
DrawGrid(&dcMem,m_rcDraw);
dc.BitBlt(0,0,Rect.Width(),Rect.Height(),&dcMem,0,0,SRCCOPY);
dcMem.DeleteDC();
DeleteObject(bmpMem);
// Do not call CView::OnPaint() for painting messages
}
void CVCDSOView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//
if(nIDEvent==ID_LABEL_COMPANY)
{
CollectData();
Invalidate();
CView::OnTimer(nIDEvent);
}
}
任何想法都将不胜感激。
答案 0 :(得分:4)
您有一些子控件,当绘制其背景时可能会引起闪烁。您想通过向视图类中添加WS_CLIPCHILDREN
标志来从绘制区域中排除子控件:
BOOL CVCDSOView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= WS_CLIPCHILDREN;
return CView::PreCreateWindow(cs);
}
与闪烁问题无关:
不要为主矩形减去任何东西。您应该将位图更改为
bmpMem.CreateCompatibleBitmap(&dc, Rect.Width(), Rect.Height());
您不需要dcMem.DeleteDC()
,DeleteObject(bmpMem)
MFC会自动删除这些对象。
请注意,MFC不会自动取消选择对象。这通常无关紧要,因为Windows会进行必要的清理,如本例所示。但是为了完整起见,请添加以下内容:
CBitmap* oldbitmap = (CBitmap*)dcMem.SelectObject(&bmpMem);
...
dc.BitBlt(0,0,Rect.Width(),Rect.Height(),&dcMem,0,0,SRCCOPY);
dcMem.SelectObject(oldbitmap);
答案 1 :(得分:0)
OnEraseBkgnd
中,您应该返回FALSE
。 OnPaint
中的所有绘图都最好使用CMemDC
类,因为直接在屏幕上绘图也很可能导致闪烁:
CMemDC memDC(*pDC, this);
CDC& rDC = memDC.GetDC();
rDC.ActualDrawing`...