注册 登录
编程论坛 VC++/MFC

MFC 重绘图形闪烁问题

yijianhanmei 发布于 2013-08-23 16:50, 846 次点击
大家好,我的编程意图是在对话框中载入图片,然后添加按钮,点击按钮的时候在图片的某个位置绘制一个圆,下面是我的程序,问题是在点击按钮的时候,图片闪烁了一下。请问该如何消除?有方法说用双缓冲,我照着此方法更改(有几行代码已被我注释),但是程序运行产生中断。请问该如何解决图片重绘闪烁的问题?在我的程序上该如何更改?谢谢。

void CmapDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // 使图标在工作区矩形中居中
        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;

        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
    //    CDialogEx::OnPaint();
        CPaintDC dc(this);
        CRect rect;
        CBitmap bmBackGround;
        CDC dcMem;
        GetDlgItem(IDC_MAP)->GetWindowRect(rect);                    //这里的IDC_STATIC_NAME是你要添加位图的范围
        ScreenToClient(rect);                                            //将屏幕坐标转换成客户区坐标   
        dcMem.CreateCompatibleDC(&dc);                                    //创建兼容DC
        bmBackGround.LoadBitmap(IDB_BITMAP1);
        BITMAP bitmap;
        bmBackGround.GetBitmap(&bitmap);                                //获取位图信息
    //    bmBackGround.CreateCompatibleBitmap(&dcMem,rect.Width(),rect.Height());//创建兼容位图
        CBitmap *pbitold=dcMem.SelectObject(&bmBackGround);                //将位图选入DC中
    //    dcMem.FillSolidRect(rect,dc.GetBkColor());//按原来背景填充客户区,不然会是黑色
        SetStretchBltMode(dc, HALFTONE);
        dc.StretchBlt(rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height(),
        &dcMem,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);                //以stretchBlt的方式添加位图到相应区域
        dcMem.SelectObject(pbitold);
        dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);
    //    dcMem.DeleteDC();                                      //删除DC
    //    bmBackGround.DeleteObject();                                       //删除位图
        CBrush brush;
        brush.CreateSolidBrush(RGB(255, 0, 0));
        dc.SelectObject(brush);
        if (m_draw)
        {
            dc.Ellipse(rect.left+m_x-5, rect.top+m_y-5, rect.left+m_x+5, rect.top+m_y+5);
        }
        m_draw=false;   
    }
}
void CmapDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    m_draw=true;
    m_x=527;
    m_y=337;
    CRect rect;
    GetDlgItem(IDC_MAP)->GetWindowRect(rect);                    //这里的IDC_STATIC_NAME是你要添加位图的范围
    ScreenToClient(rect);   
    InvalidateRect(rect);
}
1 回复
#2
yuccn2013-08-23 19:34
用双缓冲咯
创建一个内存dc,把图像绘图到内存dc中,在一次行把内存dc的数据bitblt到窗口dc。
你搜索下双缓冲 闪烁问题,能够出来现场的例子
1