[Source Forge] 读cdex源码所想[ZT]

http://dev.csdn.net/Develop/article/18/18388.shtm

 

cdexsourceforge上排名前几位的热门项目,它可以将CD音轨转化为WAV文件,将WAV文件转化为MP3文件,也可以将MP3转化成WAV,目前的最新版本是1.40Beta9,我手边有一份1.40Beta3的源码,趁着有空大致看了一下。不过我的目的只限于了解整个软件结构(布局),学习别人的软件是怎样组织的。我的工作与多媒体没有太大的关系,因此我也没有能力对cdex所用到的算法做什么评论,在这里胡乱写一点别的想法。

cdex是一个典型的Windows应用程序,从外观来讲,它实现了一个Windows应用程序所需要的基本要素,各种标准的Windows控件(如组合框、列表控件、文本编辑框),带有热点功能的水平工具栏和一个垂直的工具栏(均使用了256色的图片),一个设置对话框(典型的属性表实现,里面包括了好几个属性页),一个旧式的帮助(HLP格式),另外还有一些必要的防错信息。 

从程序的内部结构来讲,它是一个典型的MFC应用程序,由三个主要的MFC类搭成了程序的框架(CWinAppCDocumentCViewCMainFrame),用户事件的响应也非常标准,基本是在CView里面捕获事件,然后通过GetDocument函数存取相关数据,再转到相关的对话框里处理。 

从整个程序的结构来讲,CDEX是主工程,其它几个辅助工程包括CDRIPID3LIBLIBSNDDLLMp2EncDllMp3EncDllMpgLibDllVorbisDllzlib,它们都是以DLL形式出现。它们导出自身的函数供主工程使用,主工程只要IncludeDll目录下的相关头文件就可以使用这些导出函数了。而如果辅助工程需要使用主工程里面的类,则在头文件中用Class xx(前向类声明/forward class declaration),然后在实现文件中Include用到的头文件即可。CDEX的这几个工程之间是一种松耦合的结构,它们相互依赖性比较强,经常要用到别的工程里的数据结构。 

归纳了一下,有这么几点:

1.外观:

1个或者2256色的热点工具栏(工具栏里一般还会放置12个控件)、状态栏、设置对话框(属性表)、关于对话框、相应的超链接(连接到公司网页或者产品主页)、各种各样的对话框。

 这些外观要求有以下的类支持:

一个注册表类CRegistry ,用于在注册表中存取信息,INI文件的读写类CIni,用于在文件中存取程序运行的一些信息; 

属性表、属性页类,通常包括56个页面,用于构造一个设置对话框,相对应还有一个struct,定义了一个全局的变量,专门保存各种设置信息;例如,CConfig就是这样一个类,声明了g_config这个全局变量,任何需要存取设置信息的,只要Include这个头文件即可; 

位图类CDIBStaticCDib、超链接类CHypeLink,用于About对话框里的显示图片和连接到相关网址。 

2.通常还以全局函数或者DLL导出函数的形式实现的一些常用函数:

与窗口位置尺寸有关的,如判断屏幕的色素和尺寸以确定使用的字体和窗口的大小,在OnSize里面响应以调整窗口的布局,保存窗口的位置尺寸,下次启动时会使用这些保存值; 

提供了检测操作系统版本和CommCtl运行库(Windows标准控件库)版本的全局函数,以判断某些功能是否可以实现; 

检查某个文件或目录是否存在,用于保存文件之前检查; 

Cdex里面有一个DebugPrintf函数,用于Debug状态时打印相关调试信息。 

1.  MFC应用程序需要用到的类,如视图、文档、CWinApp类、FrameWnd类等。文档类负责数据存取,视图类负责与用户交互。 

CCdexDoc类不是很长,主要提供了两个接口,一个是数据存储的接口,如SaveToIni,将一些信息保存到文件中;另一个是与逻辑处理类的接口,如CDInfo是一个专门读取CDROM信息的类,CCdexDoc里声明了一个CDInfo类的成员变量,通过这个成员变量来获取CDROM的信息;CDInfo里面又含有一个CDTrackInfo类的成员变量,通过这个类又可以读取相关的音轨信息,程序便是这样层层组织起来。 

不过CCdexDoc与逻辑处理类的关系并不大,这些逻辑处理类一般都被声明为全局变量,在要用到的地方Include一下头文件就可以了。对了,我指的逻辑处理类就是那些实现程序的主要功能,与UI没什么关系,与数据储存也没什么关系的类,如CAcmCodec这个类,主要用于编码的,就被我归结入逻辑处理类。如果拿WindowsDNA开发来类比,这些类还可以被归结入中间层上。 

CCdexView类大概有2500行,主要功能:1.根据当前状态,刷新各个控件的状态,如使用合适的菜单/工具栏、使某些不可用的菜单/工具图标变灰、调整窗口的位置尺寸;2. 响应用户事件,调出各种对话框处理用户请求。这些对话框的构造函数一般要求传递一个CCDexView的指针,这样,在这些对话框里就可以通过这个指针去做很多事情,象音轨复制对话框CCopyDialog就是这样。基本上CCdexView就是这些功能,核心部分-音轨复制/编解码都没做就足足2500行,可见UI的确是Windows应用程序开发人员一个沉重的负担。 

最早我学WIndows程序时采用的都是MFC里面标准的文档-视图-框架结构,后来有一段时间,没有真正明白这个结构内部那些复杂的东西,就觉得这个结构是个累赘,在MFC写的程序里就不用它,而采用自己的一套数据显示/存取结构。 

后来看了候捷写的MFC深入浅出,对MFC内部的机制明白了许多,对MFC程序里面的文档-视图-框架结构有了点好感,我觉得这是MFC自身提供的一套机制,不用它反而体现不出用MFC的好处。现在许多程序,用SPY++看一下,都像是用了文档视图结构,尤其是这个Cdex,一招一式标准的文档视图结构。 

总的来说,抛开那些多媒体算法不讲,读整个程序还是非常容易的,主要是这个程序的实现手法非常的标准化,界面也不花哨,没有用到时下流行的CJLibraryBCG库和任何漂亮的UI控件,编程上没有什么很奥妙的技巧,实现得很朴实,但是该实现的功能它都实现了,我试了一下,它的CD音轨转MP3比以前解霸里面带的好多了,没有跳音的现象。 

前段时间闲着没事的时候拿了CDEX的这个源码来看,原本是想学一些技巧之类的东西,看看这个排名前10的项目有什么神奇之处。我写程序有差不多三年的功夫了,刚看时觉得CDEX写得太土了,如果不算它的多媒体部分的算法,感觉就像一个学VC1年左右的人写的,比以前看的FreeAmpBO2K有天大的差别,但是这两天对这程序逐渐有了不少好感,的确它的朴实打动了我,也可以说它规范的做法打动了我。 

  一直以来,许多Windows软件开发者时间长了总会对Windows的软件开发感到厌倦,原因就是处理许多Windows自身与程序没太多关系的东西,比如UI就是个很重的负担,前段时间因为要参加北京通信展我需要把一个演示软件的界面重做一遍,通常是今天老板说字体不对,第二天又提出另一个要求,说功能面板应放到哪,应在设置对话框里加进什么信息等等。 

一个软件的核心应该是其算法和逻辑处理部分,而因为没有规范的做法,Windows平台上的UI设计常会占去了1/3多的比例。即使用了CJLibraryBCG之类的界面库,我也曾想自己整理出Windows平台下应用程序应该具备的一套设计要素,比如要具备什么样的UI,要有怎样的设置对话框,是否需要读写注册表等等,但就是一直没有付诸行动,直至看到CDEX,我才有点明白,不管CDEX是返璞归真还是初学者的涂鸦,我想看完了程序的结构大家都会有一些收获,这个收获对于我,可以称为总结出一份Windows程序的基本要素,我觉得这也是一种设计模式。 

  不过CDEX也有一些搞笑的东西,比如有这么一个全局函数TestIni(),很象是作者随手写的一个注册表的测试函数,也扔进了Release版本里。

你可能感兴趣的:(编程)