Как устранить мерцание при стирании фона в mfc - PullRequest
0 голосов
/ 17 января 2019

Я работаю с приложением SDI, чтобы перерисовать график и обновить данные, используя таймер в View file. Хотя я использую 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);
         }

        }

Любая идея была бы очень признательна.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

У вас есть дочерние элементы управления, которые могут вызвать мерцание, когда их фон окрашен. Вы хотите исключить дочерние элементы управления из области рисования, добавив флаг 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);
0 голосов
/ 17 января 2019
  1. В OnEraseBkgnd вы должны вернуть FALSE.
  2. Все рисование в OnPaint лучше выполнять с классом CMemDC, потому что рисование прямо на экране, скорее всего, также вызовет мерцание:

    CMemDC memDC(*pDC, this);
    CDC& rDC = memDC.GetDC();
    rDC.ActualDrawing`...
    
...