绅士亦花心

本博客主题为软件开发。转载使用请遵循署名非商业原则。

姓名ID:ken0426
19764次访问,排名5886好友0人,关注者1
一个好人
ken0426的文章
原创 23 篇
翻译 0 篇
转载 0 篇
评论 36 篇
ken0426的公告

Welcome!

You guys can just call me Ken, :)

Email/Gtalk:
ken0426(#)gmail.com

多多指教。谢谢。

我为什么叫绅士亦花心?
有必要解释一下



最近评论
DarkBlue:点击右键的时候按钮上的虚线还在?
流水线:东大产品主要有:摩托车总装流水线、成套悬挂物料输送线、摩托车发动机生产线、部件装配线、包装流水线;洗衣机、冰箱、空调等家电生产流水线设备.
流水线:东大产品主要有:摩托车总装流水线、成套悬挂物料输送线、摩托车发动机生产线、部件装配线、包装流水线;洗衣机、冰箱、空调等家电生产流水线设备.
流水线:东大产品主要有:摩托车总装流水线、成套悬挂物料输送线、摩托车发动机生产线、部件装配线、包装流水线;洗衣机、冰箱、空调等家电生产流水线设备.
流水线:东大产品主要有:摩托车总装流水线、成套悬挂物料输送线、摩托车发动机生产线、部件装配线、包装流水线;洗衣机、冰箱、空调等家电生产流水线设备.
文章分类
收藏
相册
1.饼子堂
2.文章X图
WinX官网
WinX Blog
WinX Forum
WinX Home
WinX团队
*加入我们?
ebasil
renfengxing
绅士亦花心
许伟群
许式伟(WinX之父)
饼子博客
Dot99
Ricky
txj_killer
废人
影子
晨星
狗狗
猪头
秃子
老迈
参考网站
codeproject
slashdot
sourceforge
友情链接
Kchen
leeson
Victor
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 WinX教程之我的实战(八)收藏

新一篇: 填充与对齐 | 旧一篇: 如何编写线程安全的DLL

现代操作系统都有文件系统的概念,所以有时候程序需要用户自己指定文件。在命令行下用户可以将自己指定的文件以参数形式传递,在图形界面下用户可以采用交互选择方式。在Windows下,我们把它叫做打开文件对话框(Open File Dialog),是通用对话框的一种(通用对话框还包括了颜色选择对话框、页面设置对话框、打印对话框等等)。今天我们来实战WinX里对打开文件对话框和保存文件对话框的封装,我们暂且把他们二者统称为文件对话框。WinX共提供了两种文件对话框,包括单文件对话框和多文件对话框,让我们看看WinX的操作和API方式、MFC方式有什么不同。


我们实战的例子程序就是step008-openfiles,该例程包含两个工程:




  • API方式

API实现打开文件对话框主要通过一个结构(OPENFILENAME)和一个APIGetOpenFileName)实现,此外还有一些辅助函数。OPENFILENAME定义如下(为了方便说明有所修改):

 

typedef struct tagOFN 

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; 
//默认扩展名 

LPARAM lCustData; 
//传递给hook函数的自定义数据 

LPOFNHOOKPROC lpfnHook; 
//hook函数 

LPCTSTR lpTemplateName; 
//对话框模板名 

}
 OPENFILENAME, *LPOPENFILENAME; 

 


详细介绍请参阅MSDN


API方式下,如果要显示打开文件对话框,就需要调用API函数GetOpenFileName,他的参数就是上面这个结构的指针;如果需要显示保存文件对话框,就需要调用API函数GetSaveFileName。二者原型如下:

 

 

BOOL GetOpenFileName( LPOPENFILENAME lpofn); 

BOOL GetSaveFileName( LPOPENFILENAME lpofn); 

用户关心的返回值也都通过参数传回,毕竟用户需要的还是通过显示对话框得到一个全路径和文件名。


不过OPENFILENAME结构的一堆成员都需要用户指定,对于只是一个简单的打开或保存文件对话框来说,也确实麻烦了一些。


  • MFC方式

MFC对于打开和保存文件对话框进行了封装,都包括在CFileDialog里面。MFC方式显示文件对话框,必须先构建CFileDialog对象,然后调用DoModal方法来显示对话框窗口。我们看看CFileDialog构造函数和DoModal函数原型:

 

CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL ); 

virtual int DoModal( ); 

 

可见MFC将指定给OPENFILENAME结构的参数都放在了CFileDialog的构造函数中,DoModal没有参数。


通过查看MFC源代码,发现OPENFILENAME是作为CFileDialog的公共成员变量实现的。MFC还提供了虚拟函数,通过重载虚拟函数可以改变CFileDialg的行为。


MFC的封装貌似简化了操作,如将打开文件对话框和保存文件对话框封装在一个类里面,似乎达到了界面一致。但MFC方式最大的缺点是并没有把用户和底层完全隔离开来,用户还需要了解OPENFILENAME结构的成员的含义和用法。一般来说,对于文件对话框,包括多文件对话框,无非是用户希望这种GUI交互方式获取用户的输入,获得用户选择的或者要保存的文件名和路径等。一些不常用的不应该成为用户掌握基本用法的障碍。


  • WINX方式

WinX的文件对话框定义在CommonDialogs.h文件中。WinX是将单文件对话框和多文件对话框分别定义的。我们先来看看其对单文件的定义:

 

enum FileDialogType 



fdtSaveFileDialog 
= 0

fdtOpenFileDialog 
= 1

}


template 
<INT nFileDlgType> 

class FileDialogT : public OPENFILENAME 



// ... 

}


typedef FileDialogT
<fdtOpenFileDialog> FileDialog; 

typedef FileDialogT
<fdtOpenFileDialog> OpenFileDialog; 

typedef FileDialogT
<fdtSaveFileDialog> SaveFileDialog; 


枚举界定了文件对话框类型(打开或保存),最终表现为不同的类,OpenFileDialogSaveFileDialog。最有意思的是(个人感觉),WinX不像MFC那样将OPENFILENAME结构作为成员变量封装,而且只是派生自这个系统结构。其实二者对象在二进制结构上没有区别,但是类里面的具体写法WinX方式就简单了,不像MFC那样还要ofn.xxx的方式来引用,WinX直接引用OPENFILENAME成员名就可以了。


当然,上面这个对最终用户基本没什么作用。用户关心的是使用是不是简单。假设你需要一个单文件打开文件对话框,就像本实战分析的教程实例中一样,只需要以下代码就可以:

 

winx::OpenFileDialog dlg(_T("Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0"));

if (IDOK != dlg.DoModal()) 
     
return -1

 

winx::OpenFileDialog类的构造函数中指定文件过滤器(我想一般个人都有不同的过滤器),其他参数都按照常用的默认值,最后DoModal就可以了。


我们看看winx::OpenFileDialog类构造函数和DoModal函数的原型:

 

FileDialogT( 

IN LPCTSTR szFilter 
= NULL, 

IN LPCTSTR szDefExt 
= NULL, 

IN LPCTSTR szDlgTitle 
= NULL, 

IN LPCTSTR szInitFileName 
= NULL, 

IN UINT nInitFilterIndex 
= 1

IN LPCTSTR szInitialDir 
= NULL); 

int winx_call DoModal( 

HWND hWndParent 
= NULL, INT dlgType = nFileDlgType, HINSTANCE hInst =GetThisModule()); 

 

初看起来和MFC相比,只是有些参数顺序和所在函数有变化而已,深层次上来讲,WinX将抽象和具体化分的更清了。构造函数里的参数都是抽象层次上的,他们都不依赖于文件对话框的类型(打开或保存)、父窗口、资源句柄,而这些具体层次上的参数都移到了DoModal里面,在对话框显示出来的前一刻指定。也就是说,你可以构造一个OpenFileDialog对象,然后将它以不同的形式显示出来,如改变父窗口,改变类型,改变资源句柄。


最后又将单一FileDialog模板定义进行分解成了三个类,这样设计的指导思想又是什么?我认为是这样,如果用户一开始对自己要使用什么对话框是清楚的(到底是打开文件对话框还是保存文件对话框),就可以直接选择自己需要的类,其他参数就可以全部采用默认的,使用简单。用户用的中间过程想改变一下对话框行为,还有机会进行修改,使用灵活。这个小问题,WinX为用户还是想得很多。


除此外还有对多文件对话框的封装,基本思想一致,有兴趣的朋友可以看看commondialogs.h的源码。


另人遗憾的是,WinX只对通用对话框中的文件对话框进行了封装。

 

发表于 @ 2007年03月27日 15:08:00|评论(loading...)|编辑

新一篇: 填充与对齐 | 旧一篇: 如何编写线程安全的DLL

评论

#流水线 发表于2008-09-02 10:43:48  IP: 218.75.9.*
东大产品主要有:摩托车总装流水线、成套悬挂物料输送线、摩托车发动机生产线、部件装配线、包装流水线;洗衣机、冰箱、空调等家电生产流水线设备.
#流水线 发表于2008-09-02 10:44:12  IP: 218.75.9.*
东大产品主要有:摩托车总装流水线、成套悬挂物料输送线、摩托车发动机生产线、部件装配线、包装流水线;洗衣机、冰箱、空调等家电生产流水线设备.
发表评论  


登录
Csdn Blog version 3.1a
Copyright © ken0426