【MFC】动态加载Picture Control控件中的图片

【MFC】动态加载Picture Control控件中的图片

  • 前言
  • 方法1:CBrush
  • 方法2:SetBitmap
      • 参考链接
  • 方法3:重写MyPictureControl

前言

在MFC窗体中,我们经常需要根据不同的需求来动态显示Pictrue Control上的图片。以下提供若干种方法来实现动态加载图片的目的。

方法1:CBrush

通过画刷方式,将图片刷在界面上,该方法效率较高,只要确保能够及时释放内存,不易造成内存泄漏的风险。

在主线程CTestDlg创建SetBmp()函数来设置图片。

void CTestDlg::SetBmp()
{
	CStatic				m_pic;		//Picture Control控件
	CDC					*pDC;
	CBitmap				bmp;
	CBrush				brush;
	CRect				rect;
	
	pDC = m_pic.GetDC();
	m_pic.GetClientRect(&rect);
	bmp.LoadBitmap(IDB_BITMAP_1);	//IDB_BITMAP_1通过资源管理器加载好的图片
	brush.CreatePatternBrush(&bmp);	//创建位图画刷
	
	pDC->FillRect(rect, &brush);	//用背景画填充区域
	bmp.DeleteObject();
	ReleaseDC(pDC);		//释放资源
}

注意
通过画刷加载的图片,并不是替换掉控件默认载入的图片,所以当你移动窗口或者窗口刷新时,通过该方法加载的图片会被刷掉。

方法2:SetBitmap

//pictureResource为图片资源的ID
//CStatic mPictureViewer;为图片控件变量
void CMyForm::ShowPicture(UINT pictureResource)
{
   CBitmap bitmap;//创建CBitmap对象用于存放我们需要加载的图片
   HBITMAP hbmp;//用于记录图片加载后的句柄
   bitmap.LoadBitmap(pictureResource);//加载图片资源
   hbmp = (HBITMAP)bitmap.GetSafeHandle();//获取图片句柄
   this->mPictureViewer.SetBitmap(hbmp);//为空间设置图片

    //为了让图片自动缩放以适应空间的尺寸 需要获取图片尺寸信息
   BITMAP bmpInfo;//存储图片信息用于获取图片的宽度和高度
   bitmap.GetBitmap($bmpInfo);
   int bmpWith = bmpInfo.bmWidth;//图片宽度
   int bmpHeight = bmpInfo.bmHeight;//图片高度


   CRect rect;//记录Picture Control控件的尺寸
   this->mPictureViewer.GetClientRect(&rect);
   int nx = rect.left + (rect.Width() - bmpWidth) / 2;//计算图片插入位置x
   int ny = rect.top + (rect.Height() - bmpHeight) / 2;//计算图片插入位置y

   CDC *pDC = this->mPictureViewer.GetDC();//获取DC
   pDC->SetStretchBitMode(COLORONCOLOR);//设置图片模式

   CDC dcMemory;
   dcMemory.CreateCompatibleDC(pDC);
   CBitmap *pOldBitmap = dcMemory.SelectObject(&bitmap);

   pDC->StretchBit(0,0,rect.Widht(),rect.Height(),&dcMemory,0,0,bmpWidth,bmpHeight,SRCCOPY);
   ReleaseDC(pDC);//释放DC 注意获取后必须释放
 
}
//实现重绘时更新图片
void CMyForm::OnPaint()
{
    CPaintDC dc(this);
    //myPictureResource为当前需要显示图片的id
    //或者根据实际情况在调用ShowPicture之前 获取到该ID即可
    ShowPicture(myPictureResource);
}

该方案通过SetBitmap可以将图片直接加载进控件当中,并且不会被窗口事件刷新,并且可以根据图片尺寸自动调整以适应控件尺寸。

该方法适合用在不需要经常更新图片的应用场景中,一旦出现Picture Control控件需要频繁加载图片时,该方法容易出现内存泄漏的风险。

参考链接

方法2参考链接: MFC应用程序中如何动态更新Picture Control中的图片.

方法3:重写MyPictureControl

方法1和方法2都能够实现Picture Control控件动态加载图片,但是方法1需要不断调用,来避免被窗口事件刷新,而方法2一旦在频繁加载图片的应用场景中,就会有内存泄漏的风险。

所以我在方法1的基础上,通过继承STATIC类,重写MyPictureControl类,在OnPaint()函数内做加载图片的处理,既保证了效率,也避免了图片会被刷新掉的风险。

void CMyPictureControl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	CRect				rect;
	CBrush				brush;
	CBitmap				bmp;
	
	GetClientRect(&rect);
	bmp.LoadBitmap(IDB_BITMAP_1);	//IDB_BITMAP_1通过资源管理器加载好的图片
	brush.CreatePatternBrush(bmp);

	dc.FillRect(rect, &brush);
	bmp.DeleteObject();
	brush.DeleteObject();
	// 不为绘图消息调用 CStatic::OnPaint()
}

注意:

为了提升MyPictureControl类的灵活性,可以将bmp作为成员变量传递进来,再通过Invalidate(0)来更新控件,触发OnPaint()函数。

代码例程: Picture Control控件自写类实现动态加载图片功能.

你可能感兴趣的:(MFC,mfc)