C++ MFC Picturebox 改变位图

标签 c++ bitmap mfc picturebox

我创建派生类以在图片框中显示位图并在必要时滚动。

我在更改位图时遇到一个问题,背景不清晰并且保留了以前的位图。当新图像的宽度/高度较小时就会出现问题。

您知道我该如何解决这个问题吗?

我的代码:

我在函数 ChargerImage 中加载位图,并在函数 DessinerImage 中绘制它。

// Picturebox.cpp : fichier d'implémentation
//

#include "stdafx.h"
#include "Picturebox.h"


// CPicturebox

IMPLEMENT_DYNAMIC(CPicturebox, CWnd)

    CPicturebox::CPicturebox()
{
    coeffZoom=8;
}

CPicturebox::~CPicturebox()
{
}


BEGIN_MESSAGE_MAP(CPicturebox, CWnd)
    ON_WM_HSCROLL(5000,OnHScroll)
    ON_WM_VSCROLL(5001,OnVScroll)
END_MESSAGE_MAP()

void CPicturebox::ReserverMemoire()
{
    CPaintDC dc(this);
    m_dcMem.CreateCompatibleDC(&dc );
    ModifyStyle(WS_HSCROLL|WS_VSCROLL,0);
    UINT uiHHeight = GetSystemMetrics(SM_CYHSCROLL);
    UINT uiVWidth = GetSystemMetrics(SM_CXVSCROLL);
    CRect rectClient, rectH, rectV;
    GetClientRect(rectClient);
    rectH = rectClient;
    rectH.top = rectH.bottom - uiHHeight;
    rectH.right -= uiVWidth;

    rectV = rectClient;
    rectV.left = rectV.right - uiVWidth;
    rectV.bottom -= uiHHeight;
    m_HScroll.Create(SBS_HORZ | SBS_BOTTOMALIGN | WS_CHILD , rectH, this, 5000);
    m_HScroll.EnableScrollBar();
    m_VScroll.Create(SBS_VERT | SBS_RIGHTALIGN | WS_CHILD , rectV, this, 5001);
    m_VScroll.EnableScrollBar();
}

void CPicturebox::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    switch (nSBCode)
    {
    case SB_TOP:
        sourcey = 0;
        break;
    case SB_BOTTOM:
        sourcey = INT_MAX;
        break;
    case SB_THUMBTRACK:
        sourcey = nPos;
        break;
    }

    m_VScroll.SetScrollPos(sourcey);
    InvalidateRect(&rectStaticClient);
    CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
    DessinerImage();
}

void CPicturebox::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    switch (nSBCode)
    {
    case SB_TOP:
        sourcex = 0;
        break;
    case SB_BOTTOM:
        sourcex = INT_MAX;
        break;
    case SB_THUMBTRACK:
        sourcex= nPos;
        break;
    }    
    m_HScroll.SetScrollPos(sourcex);
    InvalidateRect(&rectStaticClient);
    CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
    DessinerImage();
}
void CPicturebox::ChargerImage(CString lien,int ImageLargeur,int ImageHauteur)
{
    if(m_hBmpNew != NULL )
        DeleteObject(m_hBmpNew);

    sourcex=sourcey=0;        // Set starting Position of Source Bitmap to 
    //be copied to (0,0)
    m_hBmpNew =    (HBITMAP) LoadImage(AfxGetInstanceHandle(), // handle to instance
        lien,  // name or identifier of the image (say "C:\\bitmap.bmp")
        IMAGE_BITMAP,        // image types
        0,     // desired width
        0,     // desired height
        LR_LOADFROMFILE); 
    if( m_hBmpNew == NULL ) {
        AfxMessageBox("Load Image Failed");
    }    
    // put the HBITMAP info into the CBitmap (but not the bitmap itself)
    else {
        GetClientRect( &rectStaticClient );
        rectStaticClient.NormalizeRect();
        m_size.cx = rectStaticClient.Width();    // zero based
        m_size.cy = rectStaticClient.Height();    // zero based

        // Convert to screen coordinates using static as base,
        // then to DIALOG (instead of static) client coords 
        // using dialog as base
        ClientToScreen( &rectStaticClient );
        ScreenToClient( &rectStaticClient);

        m_pt.x = rectStaticClient.left;
        m_pt.y = rectStaticClient.top;
        GetObject( m_hBmpNew , sizeof(BITMAP), &m_bmInfo );
        VERIFY(m_hBmpOld = (HBITMAP)SelectObject(m_dcMem, m_hBmpNew ));
        if(ImageLargeur>600*coeffZoom)
            largeur=600*coeffZoom;
        else
            largeur=ImageLargeur;
        if(ImageHauteur>300*coeffZoom)
            hauteur=300*coeffZoom;
        else
            hauteur=ImageHauteur;

        impressionLargeur=largeur/coeffZoom*m_size.cx/600;
        impressionHauteur=hauteur/coeffZoom*m_size.cy/300;

        int PrintedWidth=m_bmInfo.bmWidth/coeffZoom;
        int PrintedHeight=m_bmInfo.bmHeight/coeffZoom;

        horz.cbSize = sizeof(SCROLLINFO);
        horz.fMask = SIF_ALL;
        horz.nMin = 0;
        horz.nMax = (m_bmInfo.bmWidth-largeur)/coeffZoom;
        horz.nPage =0;
        horz.nPos = 0;
        horz.nTrackPos=0;

        if(PrintedWidth<=600)
            m_HScroll.ShowScrollBar(false);
        else
            m_HScroll.ShowScrollBar(true);

        m_HScroll.SetScrollInfo(&horz);

        vert.cbSize = sizeof(SCROLLINFO);
        vert.fMask = SIF_ALL;
        vert.nMin = 0;
        vert.nMax = (m_bmInfo.bmHeight-hauteur)/coeffZoom;
        vert.nPage = 0;
        vert.nTrackPos=0;

        if(PrintedHeight<=300)
            m_VScroll.ShowScrollBar(false);
        else
            m_VScroll.ShowScrollBar(true);

        m_VScroll.SetScrollInfo(&vert);

        InvalidateRect(&rectStaticClient);
        DessinerImage();
    }
}
void CPicturebox::DessinerImage()
{
    CPaintDC dc(this);
    dc.SetStretchBltMode(HALFTONE);
    CBitmap* pOldBitmap = (CBitmap*)m_dcMem.SelectObject(&m_bmpBitmap);
    dc.StretchBlt(0,0,impressionLargeur,impressionHauteur, &m_dcMem, sourcex+m_HScroll.GetScrollPos()*coeffZoom, sourcey+m_VScroll.GetScrollPos()*coeffZoom,largeur,hauteur,SRCCOPY);
}

最佳答案

您必须在 WM_PAINT 消息处理程序中进行绘制,并且您必须仅在该处理程序中使用 CPaintDC。有关示例,请参阅 SCRIBBLE 教程或 DRAWCLI 示例程序。

关于C++ MFC Picturebox 改变位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28265385/

相关文章:

c# - 我可以更快地复制这个数组吗?

android - BitmapFactory.decodeFile() 在某些设备中返回 null

c++ - 我将在哪个 Windows dll 中找到 afxwin/CFrameWnd?

c++ - getter 函数是否需要互斥体?

c++ - C++ 中未初始化的变量行为

c++ - 使用 C++ 抛硬币的嵌套循环

android - 为什么我所有的位图都上采样了 200%?

c++ - 包含不透明文本和按钮的透明窗口

c++ - 如何使用 Microsoft 链接器工具链接静态 MFC 库

c++ - 引用在堆栈上使用了多少内存