用MFC制作一个图片浏览器

使用基于对话框的MFC应用

一、准备部分

准备如下控件

一个图片控件(picture control),四个按钮,一个文本编辑框(属性设为只读)

为对话框类添加如下成员变量

二、选择图片按钮

在对话框类中的OnPaint函数中,添加如下代码,将图片框背景初始为白色。

	//通过ID获取静态图片控件的所有信息
	CWnd* pWnd = GetDlgItem(IDC_STATIC);
	//targetRect用于选择一个矩形区域,记录了其坐标,长、宽等信息
	CRect rect;
	//获取句柄指向控件区域的Rect赋给rect
	pWnd->GetClientRect(&rect);
	//获取该控件的图像描述表,让其与CDC设备关联
	CDC* pDc = pWnd->GetDC();
	//绘制背景背板
	//使用笔刷
	CBrush brush(RGB(255, 255, 255));
	//将笔刷设置给pDc
	pDc->SelectObject(&brush);
	//绘制矩形
	pDc->Rectangle(rect);
    //回收绘图设置所占用空间
	ReleaseDC(pDc);

为文本编辑框添加值变量(我这里已经添加过了)

同时为对话框添加两个函数,其实现如下:

void CMFCApplication1Dlg::adjustImage(CWnd* pWnd, CImage image)
{
	//targetRect用于选择一个矩形区域,记录了其坐标,长、宽等信息
	CRect rect;
	//获取句柄指向控件区域的Rect赋给rect
	pWnd->GetClientRect(&rect);
	//获取该控件的图像描述表,让其与CDC设备关联
	CDC* pDc = pWnd->GetDC();  
	//绘制背景背板
	CBrush brush(RGB(255,255,255));
	pDc->SelectObject(&brush);
	pDc->Rectangle(rect);
	//设置对要绘图片缩放的方式
	//窗口句柄,缩放方式
	SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);
	//记录要绘画的长与宽
	int width = image.GetWidth();;
	int height = image.GetHeight();
	//如果图片长或宽大于控件区域,就需要调整
	if (width > rect.Width() || height > rect.Width()) {
		float xScale = (float)rect.Width() / (float)width;//x轴缩放倍数
		float yScale = (float)rect.Height() / (float)height;//y轴缩放倍数
		float ScaleIndex = (xScale <= yScale ? xScale : yScale);//谁更小用谁,以防备出界
		width =(int)(image.GetWidth() * ScaleIndex);
		height = (int)(image.GetHeight() * ScaleIndex);
	}
	//更新rect区域,为了尽量将区域确定在控件中间
	rect = CRect(CPoint(rect.CenterPoint().x - width/2,rect.CenterPoint().y-height/2), CSize(width, height));
	//用来放缩并绘制矩形
	//若绘图已绘制会返回0
	//此处使用的是让原图片拷贝到目标位图
	//窗口句柄,绘图区域,缩放方式
	image.StretchBlt(pDc->m_hDC, rect, SRCCOPY);
	//回收绘图设置所占用空间
	ReleaseDC(pDc);
}




void CMFCApplication1Dlg::splitAddress()
{
	// TODO: 在此处添加实现代码
	//倒着寻找相同的字符
	int index = address.ReverseFind('\\');
	//Right将address中字符从右侧开始数的括号中的x(最大个数)个字符赋给m_str
	m_str = address.Right(address.GetLength() - index-1);
	address = address.Left(index+1);
}

随后为“选择图片”按钮添加点击事件

void CMFCApplication1Dlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	CImage image;//存储图片
	//文件对话框
	//基本设置  打开(true)/保存(false)  默认扩展名  默认文件名称 可操作类型  正则表达式配对(符合的才会显示) 父对话框  (一般只用得到这几个)
	CFileDialog dlg(true, _T("*.bmp"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T("image files (*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|"), NULL);
	//设置打开文件对话框的标题名
	dlg.m_ofn.lpstrTitle = _T("open Image ");
	//等待对话框的最后返回值,不是确认消息则结束
	if (dlg.DoModal() != IDOK)
		return;
	//记录地址
	address = dlg.GetPathName();
	//切割地址
	splitAddress();
	//获取图片窗口
	CWnd* pWnd = GetDlgItem(IDC_STATIC);
	//载入图片到image
	image.Load(dlg.GetPathName());
	//调整图片并绘图
	adjustImage(pWnd, image);
	UpdateData(FALSE);
}

此时,导入功能就已经完成了。

三、“上一张”及“下一张”按钮

为对话框类再次添加如下函数

//获取当前目录下的所有图片名,此方法找出来的图片是按顺序排列的
void CMFCApplication1Dlg::findFIle()
{
	// TODO: 在此处添加实现代码.
	CFileFind  find;
	BOOL result = find.FindFile(address+_T("*.*"));
	while (result) {
		result = find.FindNextFile();
		CString fileName = find.GetFileName();
		int index = fileName.Find(_T("."));
		CString suffix = fileName.Right(fileName.GetLength()-index-1);
		if (suffix == _T("jpg") || suffix == _T("bmp") || suffix == _T("png") || suffix == _T("gif")) {
			m_strs.Append(_T(",")+fileName);
		}
	}
}

现在再次在“选择图片”按钮的点击事件最后添加如下代码

	//读取文件加下所有文件
	findFIle();

为“上一张”及“下一张”按钮添加点击事件后,添加如下代码

//上一张
void CMFCApplication1Dlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString path;
	if (address.IsEmpty()) {//没有图片时
		MessageBox(_T("没有图片"));
		return;
	}
	int index = m_strs.Find(_T(",")+m_str);
	if ( index == 0) {//第一张
		index = m_strs.ReverseFind(',');//找倒数第一个逗号
		path = m_strs.Right(m_strs.GetLength() - index - 1);//逗号以右赋值
	}
	else {//不是第一张
		path = m_strs.Left(index);//逗号以左赋值
		index = path.ReverseFind(',');//找切割后的值的倒数第一的逗号
		path = path.Right(path.GetLength() - index - 1);//逗号以右赋值
	}
	m_str = path;
	path = address+path;
	CImage image;
	//获取图片窗口
	CWnd* pWnd = GetDlgItem(IDC_STATIC);
	//载入图片到image
	image.Load(path);
	//调整图片并绘图
	adjustImage(pWnd, image);
	UpdateData(FALSE);
}


//下一张
void CMFCApplication1Dlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	CString path;
	if (address.IsEmpty()) {//没有图片时
		MessageBox(_T("没有图片"));
		return;
	}
	int index = m_strs.Find(_T(",")+m_str);
	if (index == m_strs.ReverseFind(',')) {//最后一张
		index = m_strs.Find(_T(","),1);//从第二为开始,找正数第二个逗号
		if (index == -1)//只有一张图片
			return;
		path = m_strs.Left(index);//逗号以左赋值
		path = path.Right(path.GetLength() - 1);//将切割后的值的第一个逗号以右赋值
	}
	else {//不是最后一张
		path = m_strs.Right(m_strs.GetLength() - index-1);//逗号以右赋值
		index = path.Find(_T(","));//找切割后的值的第一个逗号
		path = path.Right(path.GetLength() - index - 1);//逗号以右赋值
		index = path.Find(_T(","));//找切割后的值的第一个逗号
		if (index != -1) {//不是倒数第二个
			path = path.Left(index);//逗号以左赋值
		}
	}
	m_str = path;
	path = address + path;
	CImage image;
	//获取图片窗口
	CWnd* pWnd = GetDlgItem(IDC_STATIC);
	//载入图片到image
	image.Load(path);
	//调整图片并绘图
	adjustImage(pWnd, image);
	UpdateData(FALSE);
}

四、自动播放

在对话框类的初始化器,为判断是否自动播放变量初始化。

为上一张和下一张以及自动播放按钮添加控制变量

为自动播放添加点击事件,代码如下

void CMFCApplication1Dlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	if (address.IsEmpty()) {//没有图片时
		MessageBox(_T("没有图片"));
		return;
	}
	if (m_isAuto == false) {
		//按钮变化
		m_isAuto = true;
		m_Pre.EnableWindow(FALSE);
		m_Next.EnableWindow(FALSE);
		m_Auto.SetWindowText(_T("暂停播放"));
		//启动定时器
		SetTimer(1, 1000, NULL);
	}
	else {
		//按钮变化
		m_isAuto = false;
		m_Pre.EnableWindow(TRUE);
		m_Next.EnableWindow(TRUE);
		m_Auto.SetWindowText(_T("自动播放"));
		//关闭定时器
		KillTimer(1);
	}
}

为对话框类添加定时器消息


void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//调用“下一张”按钮的函数
	OnBnClickedButton3();
	CDialogEx::OnTimer(nIDEvent);
}

至此完成了一个图片查看器的基本功能。

注:至于重新调整大小会变白,是因为笔者将背景涂白的部分放入了OnPaint中,OnPaint在每一次窗口重新绘制时,都会调用。此外,本程序只读取了jpg,png,gif,bmp图片,若有需要请自己修改。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值