您的位置:首页 > 其它

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

2014-11-13 15:48 253 查看
环境:VS2012,OpenCV 2.4.9

功能描述:

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

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



意义: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.对文本框左对齐和顶端对齐

如图:



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的使用,例如字符串的提取、类型转换

参考:

/article/9487292.html

/article/9487288.html

/article/9487290.html

2、拖曳文件的功能

参考:

/article/9487294.html

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

参考:

/article/9487295.html

/article/9487293.html

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

还有一种方法是自定义控件,但感觉挺麻烦的。这里要实现的功能比较简单,可能这种方式可用于实现一些复杂的功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: