visual-c++ - 如何消除mfc中删除背景的闪烁

标签 visual-c++ timer mfc onpaint

我正在使用 SDI 应用程序通过在 View 文件中使用计时器来重绘图形并更新数据。尽管我使用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);
         }

        }

任何想法将不胜感激。

最佳答案

您的子控件在绘制背景时可能会导致闪烁。您希望通过向 View 类添加 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);

关于visual-c++ - 如何消除mfc中删除背景的闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54235538/

相关文章:

c++ - 什么是 sourceannotations.h?

java - SharedPreferences getSharedPreferences 总是返回以前的值,即使它已被更改

swift - 定时器只执行一次函数

javascript - forEach 循环中的 setTimeout 仅显示序列中的特定元素

c++ - 比较 2 个字符串格式的 SID

c++ - 如何在 CListCtrl 中捕获滚动事件?

c++ - 在 visual studio 中创建了一个空项目,它似乎不再打开控制台?

c++ - 包含 minwindef.h 后的 BOOL 重新定义

c++ - C++ 行换列

visual-c++ - 使用 DT_WORDBREAK 绘制文本 DT_CALCRECT