用WTL构建HTML界面应用程序1

来源:百度文库 编辑:神马文学网 时间:2024/04/29 07:57:05
主要针对有一定Windows编程经验的读者。阅读本文需要对COM机制有一定的了解,最好掌握C++的STL,熟悉模板机制。本文假定您使用的是Visual C++(6.0以上版本),并正确安装了WTL 7.0和完整的ATL(Visual C++组件),如果您没有安装Visual C++,请跳过本文;如果您没有安装WTL 7.0,请看这里。
第0章 WTL介绍
ATL想必大家都不陌生,用VC写COM或COM+组件,ATL能够帮助我们完成不少工作。我个人比较喜欢ATL的运作方式——实际上,除了初学COM时编写的几个示例组件之外,我几乎没有完全手工地起草过COM的C++源代码——因为ATL已经完成了这些工作。
如果您不熟悉ATL的话,在这儿我先简单地介绍一下它。ATL是一组C++模板库,最初设计它的目的为编程人员提供一个快捷的途径来编写快而小的COM组件。早期,它特别为实现多层次企业解决方案中的商业逻辑和数据访问的自动化组件而设计。最初的ATL版本中不包括对于界面的支持,但在2.0中,ATL开始包括那些用来支持界面控件的机制。
与MFC相比,ATL最大的优势就在于它是使用模板,而不是类继承实现的。当然它也有不足之处,即它不像MFC那样容易编写界面。通常的应用中,ATL被用来编写非界面的组件,例如,OLE DB、安全验证组件,等等。
对于我本人来说,ATL的优势是非常明显的。MFC需要一些额外的消耗,因为MFC需要支持界面的种种操作,需要支持许多我并不需要的特性(至少是所写的程序中不需要),而由于采用的是类继承,这些额外的设施将不得不被包括到最终的代码中。静态连接MFC库需要增加数百KB,而动态连接,尽管能够有效地减小程序体积,但作为换汤不换药的机制,仍然需要消耗比较多的内存。通常对于组件而言,希望额外的东西越少越好——如果我不需要在屏幕上显示窗口,那么窗口支持就是多余的;如果我不需要处理鼠标事件,那么这段代码就是多余的;而多余的代码最好干脆不要出现。典型的网站服务中,更少的内存占用无疑意味着更大的承载能力。
对于那些希望有良好界面的应用程序开发人员来说,ATL的上述优势的吸引力也许并不大。然而,ATL的许多特性,特别是允许编写更小、更快的代码(与MFC相比),以及对于COM的与生俱来的支持,促使Microsoft在ATL中加入了对编写普通Windows程序的支持。
按照Microsoft的说法,WTL是使用了这些支持的对ATL的一组扩展。它包括了一组扩展ATL的类,使它能够支持更为复杂的,包括应用程序和各种用户界面组件,同时保持ATL最大的好处——能够编写小而快的代码。WTL的目标是成为最好和最简单的实现基于Win32和ATL的应用程序、服务器和控件的方法。
尽管WTL现在还不能像MFC那样方便地用来编写应用程序,但它已经足以在许多地方替代MFC,当然,使用它的开发者也就同时得到了它所带来的好处——紧凑而高效的代码。随着基于HTML页面制作程序界面这一新兴潮流的兴起,使用WTL将不再是一种“另类”的做法。
在本系列的文章中,我将一步一步地带领大家实现一个采用HTML页面作为界面的应用程序。如果你是一个网页设计高手的话,那么你将很快地发现制作一个漂亮的Windows应用程序是如此的得心应手;即使您原来非常熟悉Windows应用程序的界面设计,您也会发现,使用HTML来设计程序界面是一个不错的主意——它将极大地缩短界面的设计时间,并且,与您处于同一个开发组的其他设计人员将能够更容易地帮助您做好界面设计工作,因为编写HTML界面不需要特别的程序设计经验。
第1章 WTL入门
不熟悉COM、ATL都没有关系,因为WTL是一件容易学会的工具。下载之后,执行自解压程序,它将会把WTL复制到你的硬盘上的某个位置。随后,执行与VC版本对应的AppWizard安装程序(一个js文件),并在VC环境中适当地配置Include文件的位置就可以开始使用WTL了。
在开始写程序之前,我还需要唠叨一些关于WTL中宏定义。与MFC一样,ATL/WTL也使用了宏。我并不打算介绍全部这些宏,但几个常用的无疑能够帮助你理解WTL向导生成的代码:
宏名称描述
ALT_MSG_MAP标记新的ATL消息映射的开始
ATLASSERTATLASSERT宏将执行与C运行环境库中_ASSERTE宏同样的功能
ATLTRACE, ATLTRACE2在诸如调试窗口的输出设备中显示信息,具体显示什么与调试状态和级别有关。ATLTRACE2是目前推荐的宏,而ATLTRACE主要是为了兼容以前的代码
BEGIN_MSG_MAP标记默认消息映射的开始
CHAIN_MSG_MAP, CHAIN_MSG_MAP_ALT, CHAIN_MSG_MAP_ALT_MEMBER, CHAIN_MSG_MAP_DYNAMIC, CHAIN_MSG_MAP_MEMBER, COMMAND_HANDLER, MESSAGE_HANDLER, MESSAGE_RANGE_HANDLER定义一个消息映射项目
DECLARE_WND_CLASS指定新窗口类的名字。通常在ATL ActiveX控件的控制类中使用
END_MSG_MAP标记消息映射的结束
WM_FORWARDMSG将消息转发到别的窗口
以及几个智能指针类,以及我们可能会用到的ATL类。智能指针类可以帮助你更好地撰写程序,并避免内存泄漏等问题。
类描述
CAtlWinModule(ATL 7)为所有需要窗口特性的ATL提供支持的类
CAtlExeModuleT包括用于创建EXE文件所需要的代码的类
CAtlFile对Windows文件API进行的封装的类
CAtlFileMapping对Windows内存映射文件API进行封装的类(限于篇幅,我不打算对这个类的内部构造进行详细介绍)
CAutoPtr普通的智能指针类
CAutoPtrArray用于建立智能指针数组
CAutoPtrList用于建立智能指针表
CAutoVectorPtr用于建立智能指针向量(类似C++ vector)
CAxWindow管理作为ActiveX控件宿主窗口的类
CComBSTR对于BSTR(类似Basic字符串,限于篇幅将不作详细介绍)的封装
CComPtr管理COM接口指针的智能指针类
CComQIPtr同上。具体区别将在后文介绍
CComVariant对于VARIANT类型的封装
CWindow管理窗口
CWindowImpl创建和继承窗口
限于篇幅,我不打算介绍WTL的类——除非在后面的文字中提到它们。这里列出它们的名字,WTL的类包括CAppModule,CServerAppModule,CMessageLoop,CMessageFilter,CIdleHandler,CFrameWindowImplBase,CFrameWindowImpl,COwnerDraw,CDialogResize,CMDIWindow,CMDIFrameWindowImpl,CMDIChildWindowImpl,CUpdateUIBase,CUpdateUI,CStatic,CButton,CListBox,CComboBox,CEdit,CEditCommands,CScrollBar,CImageList,CListViewCtrl,CTreeViewCtrl,CTreeItem,CTreeViewCtrlEx,CHeaderCtrl,CToolBarCtrl,CStatusBarCtrl,CTabCtrl,CToolTipCtrl,CToolInfo,CTrackBarCtrl,CUpDownCtrl,CProgressBarCtrl,CHotKeyCtrl,CAnimateCtrl,CRichEditCtrl,CRichEditCommands,CDragListBox,CDragListNotifyImpl,CReBarCtrl,CComboBoxEx,CDateTimePickerCtrl,CFlatScrollBarImpl,CFlatScrollBar,CIPAddressCtrl,CMonthCalendarCtrl,CCustomDraw,CPropertySheetWindow,CPropertySheetImpl,CPropertySheet,CPropertyPageWindow,CPropertyPageImpl,CPropertyPage,CAxPropertyPageImpl,CAxPropertyPage,CFileDialogImpl,CFileDialog,CFolderDialogImpl,CFolderDialog,CFontDialogImpl,CFontDialog,CRichEditFontDialogImpl,CRichEditFontDialog,CColorDialogImpl,CColorDialog,CPrintDialogImpl,CPrintDialog,CPrintDialogExImpl,CPrintDialogEx,CPageSetupDialogImpl,CPageSetupDialog,CFindReplaceDialogImpl,CFindReplaceDialog,CMenu,CDC,CPaintDC,CClientDC,CWindowDC,CPen,CBrush,CFont,CBitmap,CPalette,CRgn,CCommandBarCtrlImpl,CCommandBarCtrl,CBitmapButtonImpl,CBitmapButton,CCheckListViewCtrlImpl,CCheckListViewCtrl,CHyperLinkImpl,CHyperLink,CWaitCursor,CMultiPaneStatusBarCtrlImpl,CMultiPaneStatusBarCtrl,CPaneContainerImpl,CPaneContainer,CScrollImpl,CScrollWindowImpl,CMapScrollImpl,CMapScrollWindowImpl,CSplitterImpl,CSplitterWindowImpl,CSplitterWindow,CTheme,CThemeImpl,CPrinterInfo,CPrinter,CDevMode,CPrinterDC,CPrintJobInfo,CPrintJob,CPrintPreview,CPrintPreviewWindow,CSize,CPoint,CRect,CString,CWinDataExchange,CRecentDocumentList。许多类对于MFC程序员来说是非常熟悉的,仅从类名我们就可以看出,WTL具有相当强大的界面支持。与MFC不同,WTL并不是一个框架——它不强加任何应用程序模型,并能够适应几乎所有的应用程序模型。WTL基本上是模板库,这不仅意味着它包括了全部源代码,并且,也意味着只需要实例化使用到的那些数据结构和内联函数,从而得到尽可能小的代码。
第2章 使用WTL应用程序向导
Visual C++ 7和Visual C++ 6中的WTL应用程序向导的界面差异比较大(内容相同)。为了创建一个支持HTML界面的应用程序,需要作如下选择:

首先是选择WTL应用程序向导,然后

选择SDI应用程序,最后,

将View窗口的类型选定为HTML Page,并去掉Toolbar, Rebar, Command Bar, Status Bar这些特性。
假定我们在第一步中输入的工程名称为webui,则我们将拿到一组文件:stdafx.cpp、stdafx.h(这个就不用说了吧?),webui.cpp(程序实现),MainFrm.h(CMainFrame类),webuiView.h(CWebuiView类),AboutDlg.h(CAboutDlg类),resource.h(资源定义),以及一组资源文件。
现在程序已经可以运行了,其界面类似下图:

其中,白色部分将出现Microsoft的主页,如果连着网的话。
接下来的部分中,我将拆开向导生成的这些源代码,并介绍其执行过程。
_xyz