用MFC的对话框制作一个简易的图片浏览器

环境:VS2012,OpenCV 2.4.9


功能描述:

功能1:点击OPEN按钮,选择图片并打开,下方显示图片的信息;

功能2:把图片拖曳到OPEN按钮上,也可以实现打开功能,支持多文件同时打开

用MFC的对话框制作一个简易的图片浏览器_第1张图片


意义:MFC练手程序,涉及一些知识点


过程:


1、前期工作

建立MFC工程,命名“showPicture”,取消unicode,选择对话框,其它默认;

选择Release;

添加opencv的包含目录和库目录,添加依赖项。


2、对话框编辑

a.删除“TODO: 在此放置对话框控件。”控件,把“确认”和“取消”控件的“Visible”属性设为False;

b.添加Button控件,修改以下属性:

ID:IDC_BUTTON_OPEN

Acccept Files:True

Caption:OPEN

c.添加Group Box 控件,Caption属性改为information;

d.添加5个Static Text控件,Caption属性依次改为filename、format、depth、h、w;

e.每个Static Text控件对应添加一个Edit Contral控件,ID依次为IDC_EDIT_filename、IDC_EDIT_FORMAT、IDC_EDIT_DEPTH、IDC_EDIT_H、IDC_EDIT_W,全部的Read Only属性设为True,依次添加成员变量Edit_filename、Edit_format、Edit_depth、Edit_h、Edit_w

f.对文本框左对齐和顶端对齐

如图:

用MFC的对话框制作一个简易的图片浏览器_第2张图片


3、编码实现功能1

a.添加头文件image.h

#pragma once

#pragma comment(lib,"opencv_highgui249.lib")
#pragma comment(lib,"opencv_core249.lib")
#pragma comment(lib,"opencv_imgproc249.lib")

#include <opencv2/opencv.hpp>

#define EPS  2.2204E-16

using namespace std;
using namespace cv;

class image
{
public:
	image(void);
	~image(void);

public:
	Mat img;
};

b.为OPEN按钮添加事件处理程序OnBnClickedButtonOpen()

void CshowPictureDlg::OnBnClickedButtonOpen()
{
	// TODO: 在此添加控件通知处理程序代码

	CFileDialog fDlg(TRUE, _TEXT("*"), NULL, 4|2,  
        _TEXT("全部文件(*.*)|*.*|全部文件(*.*)|*.*||"));  
  
    // 调用 DoModal() 方法来打开对话框  
    if (fDlg.DoModal() == IDOK)  
    {  
        // 设置编辑框1的内容为选择文件的路径  
        // GetPathName() --> 返回选定文件的完整路径  
		CString path;
        path = fDlg.GetPathName(); 

		if(!path.IsEmpty())
		{
			img = imread((LPCSTR)path,CV_LOAD_IMAGE_ANYCOLOR);

			CString imageName; 
			imageName = path;
			imageName.MakeReverse();
			int index=imageName.Find('\\');
			imageName = imageName.Left(index);
			imageName.MakeReverse();

			//显示图像信息
			CString info;
			
			info.Format("%d",img.rows);
			Edit_h.SetWindowText(info);

			info.Format("%d",img.cols);
			Edit_w.SetWindowText(info);

			int depth;
			switch(img.depth())
			{
			case 0 :;
			case 1 :depth=8;break;
			case 2 :;
			case 3 :depth=16;break;				
			}
			info.Format("%d",depth);
			Edit_depth.SetWindowText(info+"bits");

			index = imageName.Find('.');
			info = imageName.Right(imageName.GetLength()-index-1);
			Edit_format.SetWindowText(info);

			info = imageName;
			Edit_filename.SetWindowText(info);

			//显示图像
			namedWindow((LPCSTR)imageName, CV_WINDOW_NORMAL);
			resizeWindow((LPCSTR)imageName,img.cols,img.rows);
			imshow((LPCSTR)imageName,img);
		}
	}

}
showPictureDlg.h中添加

#include "image.h"
以及新增成员变量

private:
	Mat img;

至此,运行程序可以实现功能1。


4、编码实现功能2

在3的基础上继续;

a.用类向导添加一个MFC类,基类为CButton,类名为CFileButton,该类用于实现拖曳文件至OPEN按钮并打开的功能;

b.为CFileButton添加ON_WM_DROPFILES消息,并编辑消息函数

// CFileButton 消息处理程序

void CFileButton::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	destroyAllWindows();

	char *lpszFileName=new char[512]; 
	int nFileCount,i; 

	nFileCount=::DragQueryFile   
		(hDropInfo,0xFFFFFFFF,NULL,512); 

	CString   path;
	UINT   nChars;
	Mat img;

	for   (i=0;i <   nFileCount;i++) 
	{ 
	
		nChars=::DragQueryFile 
						(hDropInfo,i,&lpszFileName[0],512); 
		path = lpszFileName;
		path = path.Left(nChars);

		if(!path.IsEmpty())
		{
			img = imread((LPCSTR)path,CV_LOAD_IMAGE_ANYCOLOR);

			if(!img.empty())
			{
				CString imageName; 
				imageName = path;
				imageName.MakeReverse();
				int index=imageName.Find('\\');
				imageName = imageName.Left(index);
				imageName.MakeReverse();

				//显示图像信息		
				HWND   hWnd   =   ::FindWindow(NULL,"showPicture"); 

				info.h.Format("%d",img.rows);
				info.w.Format("%d",img.cols);
				int depth;
				switch(img.depth())
				{
				case 0 :;
				case 1 :depth=8;break;
				case 2 :;
				case 3 :depth=16;break;				
				}
				info.depth.Format("%d",depth);
				index = imageName.Find('.');
				info.format = imageName.Right(imageName.GetLength()-index-1);
				info.filename = imageName;
				 
				HWND   hEdit   =   ::GetDlgItem(hWnd,IDC_EDIT_H); // 取得控件的指针
				::SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)(LPCSTR)(info.h));
				hEdit   =   ::GetDlgItem(hWnd,IDC_EDIT_W); // 取得控件的指针
				::SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)(LPCSTR)(info.w));
				hEdit   =   ::GetDlgItem(hWnd,IDC_EDIT_DEPTH); // 取得控件的指针
				::SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)(LPCSTR)(info.depth));
				hEdit   =   ::GetDlgItem(hWnd,IDC_EDIT_FORMAT); // 取得控件的指针
				::SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)(LPCSTR)(info.format));
				hEdit   =   ::GetDlgItem(hWnd,IDC_EDIT_filename); // 取得控件的指针
				::SendMessage(hEdit,WM_SETTEXT,0,(LPARAM)(LPCSTR)(info.filename));

				//显示图像
				namedWindow((LPCSTR)imageName, CV_WINDOW_NORMAL);
				resizeWindow((LPCSTR)imageName,img.cols,img.rows);
				imshow((LPCSTR)imageName,img);
			}
			else
			{
				MessageBox("fail to open!");
				return;
			}
		}
		else
		{
			MessageBox("path is invalid!");
			return;
		}
	} 

	::DragFinish   (hDropInfo);       //释放内存 
	i=0; 
	delete   []lpszFileName; 
}

FileButton.h中添加成员变量

public:
        struct info
	{
		CString depth;
		CString format;
		CString filename;
		CString h;
		CString w;
	}info;
并添加

#include "image.h"


c.把CFileButton类绑定到OPEN按钮

修改showPictureDlg.h

添加成员变量

public:
           CFileButton m_FileButton;
添加头文件

#include "FileButton.h"

修改showPictureDlg.cpp

改写对话框的DoDataExchange函数

void CshowPictureDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_H, Edit_h);					
	DDX_Control(pDX, IDC_EDIT_W, Edit_w);					
	DDX_Control(pDX, IDC_EDIT_FORMAT, Edit_format);			
	DDX_Control(pDX, IDC_EDIT_DEPTH, Edit_depth);			
	DDX_Control(pDX, IDC_EDIT_filename, Edit_filename);		
	DDX_Control(pDX, IDC_BUTTON_OPEN, m_FileButton);//增加了这一句
}

至此,运行程序可以实现功能2和功能1。


附:涉及的知识点


1、CString的使用,例如字符串的提取、类型转换

参考:

http://blog.csdn.net/kelvin_yan/article/details/41082191

http://blog.csdn.net/kelvin_yan/article/details/41007951

http://blog.csdn.net/kelvin_yan/article/details/41042571


2、拖曳文件的功能

参考:

http://blog.csdn.net/kelvin_yan/article/details/41082299


3、SendMessage向控件发送消息。为什么要用这种方式?在对话框原本的cpp里是不需要这么麻烦的,但因为这里自定义了一个CFileButton类,不能通过Edit控件的成员变量来传值,只能用这种方法。

参考:

http://blog.csdn.net/kelvin_yan/article/details/41082525

http://blog.csdn.net/kelvin_yan/article/details/41082251

4、扩展控件功能的一种办法。这里通过新建一个CFileButton类,使Button控件支持文件拖曳的功能。很奇怪的一点:Button控件有一个接受文件的属性,但为什么就没有一个类似OnDropFiles的事件处理程序?或者是我不知道而已。

还有一种方法是自定义控件,但感觉挺麻烦的。这里要实现的功能比较简单,可能这种方式可用于实现一些复杂的功能。


你可能感兴趣的:(mfc)