分类:
2008-10-13 16:47:47
在打开文件对话框上实现图象预览
作者:
正文:
对常用格式的图片,在打开文件对话框中实现预览功能效果如下图:
图一
思路:
从CFileDialog派生CFileDialogEx类,为对话框安装钩子,利用HOOK拦截我们感兴趣的CDN_SELCHANGE消息,在其中加入我们的预览功能,原理就是这么简单!
使用方法:
1):在ResourView中,加一个对话框,其 ID为IDD_DIALOG_HOOK, 注意其属性的设置:Dialog Properties->styles下=>
style为Child、Border为None, 选中Clip siblings。 More Styles下 => 选中3D-look、
Contol。
2):在对话框上加一个 Static Text控件,用来显示图片。ID为IDC_PIC,其属性的设置为:Text Properties下 =>
选中Notify、Sunken。
3):将Picture.h,Picture.cpp;CFileDialogEx.h,CFileDialogEx.cpp添加到工程中。其中类CFileProcess是文件处理类,用于文件进行操作。类CPicture用于处理图片。(详见代码)
4)在应用处,只要包含头文件 #include”FileDialogEx.h”。
For example:注:由于时间紧,在Debug版本下,双击选中文件后,有暴停的现象(内存泄漏),而且显示效果也没有进行处理!
CString strPathName;
CFileDialogEx dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
POSITION Pos;
Pos = dlg.GetStartPosition();
while (Pos != NULL)
{
strPathName = dlg.GetNextPathName(Pos);
if(!strPathName.IsEmpty())
{
MessageBox(strPathName, _T("GetNextPathName"), MB_ICONINFORMATION);
}
}
}
比图一多了左面的快捷栏(方便用户查找)。其实这个实现很简单,只要判断一下系统的版本就可以了,但是98下只显示图一所示的对话框,2000,XP则显示图二的对话框,这是MS在98以后的版本,对这个东东重新进行了封装!
详情请看链接: 利用MFC的CFileDialog怎么样生成Win2000的文件对话框,
图二
只要在CFileDialogEX dlg(TRUE)后面,加上如下代码,就可以显示图2效果。
//--------只要加上下面这段代码,就可以显示2000下的打开文件对话框-------------
//------用来检测目前的操作系统的版本信息
int nStructSize = 0;
DWORD dwVersion, dwWindowsMajorVersion, dwWindwosMinorVersion;
dwVersion = GetVersion();
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwWindwosMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
if(dwVersion < 0x80000000)
{
nStructSize = 88; //2k,xp下显示新的版本
}
else
{
nStructSize = 76; //98下显示老版本,如图1
}
dlg.m_ofn.lStructSize = nStructSize; //------用来检测目前的操作系统的版本信息
OPENFILENAME结构体:虽然成员变量不少,但是我们常用的就几个而已!该结构体包含一些保存或打开文件对话框的重要信息,比如过滤文件名,指定初始化路径,对文件进行多选,显示98风格还是2000风格的open/save对话框!
typedef struct tagOFN { // ofnlStructSize :
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCTSTR lpstrFilter;
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
DWORD lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
} OPENFILENAME;
Members
lpstrDefExt :
指向一个包含默认扩展名的缓冲区。
lpfnHook:
指向一个HOOK的处理过程函数。在该函数里实现拦截我们想要的消息。
lpTemplateName :
指向一个以对话框模板资源命名的字符串(以NULL结尾),该对话框模板在模块中由hInstance成员标识。注意:如果想指定一个对话框模板资源必须在Flags中设定OFN_ENABLETEMPLATE。
如: m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG_HOOK)。
这个对Win98下的对话框用处比较大(个人观点),我在这里不详细的说明只是给大家一个链接:
有时候,我们想把预览区放在右边,而且还想在最下面添加一些控件(如下图三),该怎么办呢?当时,我找了半天资料也没找到,后来我们老大告诉我应该这样…..
图三
其实很简单,只要加一个StaticText控件就可以了,注意其ID设置,我设为stc32。但是其摆放位置很重要。如果你想要实现图三的效果,必须如图四这样放置:
图四
如果你想实现这样的放置效果,并且复选框一定要在预览区的下面,如图五:
图五
则Static text要如图六这样放置:
图六
关于预览区的放置,MSDN上有说明,但是我找不到(找了一个下午)!
1).使用CFileDialog类选择多个文件时,发现选择的文件个数有限,这是因为m_ofn.nMaxFile的值有限:256Btye,解决的办法是:将m_ofn.lpstrFile的缓冲区换成自己的指针。选择多个文件,首先要给m_ofn的标志nFlags加上OFN_ALLOWMULTISELECT。当用户选择多个文件,CFileDialog会把选择后的文件名拷贝到一个缓冲区,默认这个缓冲区有256个字符,这对于要求多选的用户来说是不够的。你可以将m_ofn.lpstrFile替换成自己的缓冲区指针:
char sBuffer[2000];
memset(sBuffer, 0, 2000);
CSTLFileDialog dlg(TRUE);
dlg.m_ofn.lpstrFile = sBuffer;
dlg.m_ofn.nMaxFile = 2000; //解决多选问题
这个方法解决多选问题,就是简便易懂。如果你多选的真好是257或300个字符,那么其余的1400个空间易浪费了。下面介绍一个动态解决分配的方法,请看代码:
//------1.动态分配内存空间,解决多选的问题---------------------------------------
void CSTLFileDialog::SolveMoreSelect()
{
TCHAR chBuffer;
TCHAR *chFiles = NULL;
TCHAR *chFolder = NULL;
UINT nFileSize;
UINT nFolderSize;
nFileSize = CommDlg_OpenSave_GetSpec(GetParent()->m_hWnd, &chBuffer, 1);
nFolderSize = CommDlg_OpenSave_GetFolderPath(GetParent()->m_hWnd, &chBuffer, 1);
if((nFileSize + nFolderSize) > m_ofn.nMaxFile)
{
if(chFiles)
{
delete[] chFiles;
}
chFiles = new TCHAR[nFileSize + 1];
CommDlg_OpenSave_GetSpec(GetParent()->m_hWnd, chFiles, nFileSize);
if(chFolder)
{
delete[] chFolder;
}
chFolder = new TCHAR[nFolderSize + 1];
CommDlg_OpenSave_GetSpec(GetParent()->m_hWnd, chFolder, nFolderSize);
}
else
{
if(chFiles)
{
delete[] chFiles;
chFiles = NULL;
}
if(chFolder)
{
delete[] chFolder;
chFolder = NULL;
}
}
如果您看我的代码比较困难,请到以下链接处:
1)、对文本文件实现预览:
2)、对图象文件(2D)实现预览:
3)、对位图文件实现预览:
4)、对声音文件实现预听:
结束语:
在这里我要感谢帮助过我的朋友们,希望您对我写的文章提出宝贵的意见!另外如果有时间我的另一篇文章将介绍在CFileDialog的打开文件对话框中,实现对3D图形的预览,也就是对STL(CAD中常用的存储格式)格式的文件进行预览,这才是我的要做的!如果表述不清之处,请Email联系!