zoukankan      html  css  js  c++  java
  • mfc动态显示图片(bmp以及png)

    参考:https://blog.csdn.net/pudongdong/article/details/69396600

    之前写过win32动态显示图片的博客(程序线程检测图片变动自动刷新,而非按按钮再刷新的情况),这次用到了mfc。原理是一样的。

    OnInitDialog函数初始化

    BOOL CXxxDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();
        if (m_bmp.m_hObject != NULL)
            m_bmp.DeleteObject();
        /*载入图片*/
        HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),L"initPic.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
        if (hbmp == NULL)
            return FALSE;
        /*取得加载的BMP的信息*/
        m_bmp.Attach(hbmp);
        DIBSECTION ds;
        BITMAPINFOHEADER &bminfo = ds.dsBmih;
        m_bmp.GetObject(sizeof(ds), &ds);
        int cx = bminfo.biWidth; 
        int cy = bminfo.biHeight; 
        /*得到了图像的宽度和高度后,对图像大小进行适应,即调整控件的大小,让它正好显示一张图片*/
        CRect rect;
        GetDlgItem(IDC_PIC_ZONE)->GetWindowRect(&rect);
        ScreenToClient(&rect);
        /*调整大小*/
        GetDlgItem(IDC_PIC_ZONE)->MoveWindow(rect.left, rect.top, cx, cy, true);
        return TRUE; 
    }

    OnPaint具体画图。

    IDC_PIC_ZONE为picture control控件。
    void CXxxDlg::OnPaint()
    {
        if (m_bmp.m_hObject != NULL)
            m_bmp.DeleteObject();
        /*重新载入图片,因为可能刷新*/
        HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), L"initPic.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
        if (hbmp == NULL)
            return;
        /*取得加载的BMP的信息*/
        m_bmp.Attach(hbmp);
        DIBSECTION ds;
        BITMAPINFOHEADER &bminfo = ds.dsBmih;
        m_bmp.GetObject(sizeof(ds), &ds);
        /*若用此句,得到的是对话框的DC,图片将被绘制在对话框上*/
        //CPaintDC dc(this);    
        /*用此句,得到picture控件的DC,图像将被绘制在控件上  */
        CPaintDC dc(GetDlgItem(IDC_PIC_ZONE));
        /*若用此两句,得到的是屏幕的DC,图片将被绘制在屏幕上*/
        //  CDC dc;
        //  dc.m_hDC=::GetDC(NULL);  
        CRect rcclient;
        GetDlgItem(IDC_PIC_ZONE)->GetClientRect(&rcclient);
        CDC memdc;
        memdc.CreateCompatibleDC(&dc);
        CBitmap bitmap;
        bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
        memdc.SelectObject(&bitmap);
        CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC, 0);
        CDC maskdc;
        maskdc.CreateCompatibleDC(&dc);
        CBitmap maskbitmap;
        maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
        maskdc.SelectObject(&maskbitmap);
        maskdc.BitBlt(0, 0, rcclient.Width(), rcclient.Height(), &memdc,
            rcclient.left, rcclient.top, SRCCOPY);
        CBrush brush;
        brush.CreatePatternBrush(&m_bmp);
        dc.FillRect(rcclient, &brush);
        dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),
            &memdc, rcclient.left, rcclient.top, SRCPAINT);
        brush.DeleteObject();
    }

    这个程序功能是在设备上按手指后,界面自动刷新指静脉的图片

    所以界面的刷新要自己写代码刷新(刷新区域在RECT里设置,不要刷新面积太大,否则整个界面都闪烁):

    void CXxDlg::refreshImg()
    {
        RECT        rect;
        //idcPicZone.GetWindowRect(&rect);
        SetRect(&rect, 10, 10, 520, 230);
        InvalidateRect( &rect, true);
        UpdateWindow();
    }

    注意,要想程序运行到OnPaint方法,需要在BEGIN_MESSAGE_MAP注册ON_WM_PAINT()

    效果:


    上面程序那样写。是由特定需求决定的:程序检测图片更新后自动刷新图片,而非按了什么按钮产生事件响应。另外,还进行了位图的转化

    由于不触发事件,需要自己手动刷新界面

    实际上,如果是按按钮就刷新界面的话,写法就简单了:

    void CXxDlg::_setPic()
    {
        CImage image;
        CWnd* pWnd = GetDlgItem(IDC_SKIN_SHOW);
        CDC* pDC = pWnd->GetDC();
        HDC hDC = pDC->m_hDC;
        CRect rect_frame;
        pWnd->GetClientRect(&rect_frame);
        image.Load(L"xxx\xxx.png");
        ::SetStretchBltMode(hDC, HALFTONE);
        ::SetBrushOrgEx(hDC, 0, 0, NULL);
        image.Draw(hDC, rect_frame);
        ReleaseDC(pDC);
        image.Destroy();
    }

    在事件响应函数里加入这样代码就可以刷新图片了(图片是load的路径)

    因为有事件响应,界面自动刷新

    不过有个问题,如果是想打开程序后,初始界面显示一张图片的话,把上面的代码写在OnInitDialog()函数里是没用效果的

    必须要把上面的代码写在OnPaint()里:

    void CXxDlg::OnPaint()
    {
        /*默认显示第一张预览图*/
        ………………………………
        __super::OnPaint();
    }

    注意要写__super::OnPaint();

    否则整个界面就只画这一张图了

  • 相关阅读:
    Splashtop :符合 HIPAA 标准的远程桌面软件
    学生如何在家中访问学校许可的软件
    Splashtop用于远程实验室的功能得到增强
    docker环境安装,镜像和容器常用命令
    vue-cli入门
    webpack快速入门
    Vue路由vue-router
    Vue组件化
    Vue指令
    Vue实例
  • 原文地址:https://www.cnblogs.com/rixiang/p/10024741.html
Copyright © 2011-2022 走看看