Я создаю свой производный класс для отображения растрового изображения в картинке и прокрутки при необходимости.
У меня есть одна проблема, когда я изменяю растровое изображение, фон не ясен, и предыдущий растровое изображение остается. Это проблема, когда новое изображение меньше ширины / высоты.
У вас есть идея, как я могу решить эту проблему?
Мой код:
Я загружаю растровое изображение в функцию 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.