翼是孤独 发表于 2018-11-24 17:36:24

求大神解答,怎么重写MFC背景擦除,解决图形移动时的闪烁(已用双缓冲)

绘图代码如下:
void CTuxinDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // device context for painting
                SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
                // Center icon in client rectangle
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;
                // Draw the icon
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CWnd * pWnd = GetDlgItem(IDC_BIANJIE);//绘图窗口为IDC_BIANJIE
                CDC * pDC1 = pWnd->GetDC();
                pWnd->Invalidate();
                pWnd->UpdateWindow();
                CRect rect;
                GetDlgItem(IDC_BIANJIE)->GetClientRect(&rect);//客户区域为IDC_BIANJIE
               
                CDC dcMem; //用于缓冲作图的内存DC
                CBitmap bmp; //内存中承载临时图象的位图
                dcMem.CreateCompatibleDC(pDC1);
                bmp.CreateCompatibleBitmap(pDC1,rect.Width(),rect.Height());
                dcMem.SelectObject(&bmp); //将位图选择进内存DC
                //按原来背景填充客户区,不然会是黑色
                dcMem.FillSolidRect(rect,pDC1->GetBkColor());
//=========================绘图
                CPen * pNewPen,* pOldPen;//创建新画笔,旧画笔指针
                pNewPen=new CPen; //新建画笔
                pNewPen->CreatePen(PS_SOLID,3, RGB(0,0,0)); //黑线
                pOldPen=dcMem.SelectObject(pNewPen);//选入新画笔 ,并且保存旧的笔
                CBrush *pNewBrush,*pOldBrush;//创建旧画刷指针
                pNewBrush=new CBrush(RGB(255,255,0)); //新画刷
                pOldBrush=dcMem.SelectObject(pNewBrush);//选入新画刷并保存旧画刷

                dcMem.Ellipse(100+x0,50+y0,420+x0,370+y0); //绘制图形1
                dcMem.SelectObject(pOldBrush); //恢复原有画刷
                delete pNewBrush;//删除新画刷

                pNewBrush=new CBrush(RGB(255,0,0));
                pOldBrush=dcMem.SelectObject(pNewBrush);
                dcMem.Rectangle(150+x3,100+y3,370+x3, 320+y3); //绘制图形2
                dcMem.SelectObject(pOldBrush);
                delete pNewBrush;

                dcMem.SelectObject(pOldBrush); //恢复原画刷
                delete pNewBrush;//删除新画刷
                dcMem.SelectObject(pOldPen); //恢复原笔
                delete pNewPen;//删除新笔
               

                pDC1->BitBlt(0,0,rect.Width(),rect.Height(), &dcMem,0,0,SRCCOPY);//将内存DC上的图象拷贝到前台
                ReleaseDC(pDC1);//释放显示设备描述表
                dcMem.DeleteDC();//删除内存dcMem
                bmp.DeleteObject();//删除位图
                CDialog::OnPaint();
        }
}
1.我对这些图形使用滑动条移动时,会出现闪烁现象,查资料说闪烁是因为重绘时背景擦除,移动图形时相当于中间多加了一张空白的背景(类似于gif中多了空白帧)
2.于是我修改了ERASEBKGND消息,修改为return true;,但是这样移动图形时还是会闪烁,并且这样我移动图形时,其他部分(非客户区)的控件也会有一点点闪烁(很轻微的闪烁)
求大神帮助

cquplz 发表于 2018-11-24 17:36:25

要是不想改数据保存的结构的话就去看孙鑫的视频,bilibili上搜一下他的第十课十一课;
要是想改的话,看一下这个https://malagis.com/vc-double-buffered.html

翼是孤独 发表于 2018-11-24 17:45:49

求大神啊

cquplz 发表于 2019-4-24 13:34:54

修改了ERASEBKGND消息,修改为return false

shake_a_tree@16 发表于 2019-4-27 16:25:21

在刷新函数Invalidate()加一个参数false,即Invalidate(false)
页: [1]
查看完整版本: 求大神解答,怎么重写MFC背景擦除,解决图形移动时的闪烁(已用双缓冲)