您的位置:首页 > 编程语言 > C语言/C++

[翻译]WTL开发者指南 第4章-WTL快速之旅(2)

2006-04-24 10:07 489 查看
CHyperLink允许在程序中嵌入web-links,当按下时会打开一个浏览器显示这个URL。

template <class T, class TBase = CWindow,

class TWinTraits = CControlWinTraits>

class CHyperLinkImpl

: public CWindowImpl< T, TBase, TWinTraits >

class CHyperLink : public CHyperLinkImpl<CHyperLink>

 

CWaitCursor可以根据输入参数设置光标,默认值为IDC_WAIT。

class CWaitCursor

 

CMultiPaneStatusBarCtrl 提供了一个包含了“子分割”的状态条(status bar)不同的“分割”上可以放置不同的文本。

 

template <class T, class TBase = CStatusBarCtrl>

class CMultiPaneStatusBarCtrlImpl

: public CWindowImpl< T, TBase >

class CMultiPaneStatusBarCtrl

: public CMultiPaneStatusBarCtrlImpl<CMultiPaneStatusBarCtrl>

 

Dynamic Data Exchange(altddx.h)

DDX用来在类的数据成员和对话框控件之间双向交换数据。WTL中的DDX只牵涉到一个模板类CWinDataExchange,和许多和宏,比如DDX_TEXT。

template <class T> class CWinDataExchange

要想使用DDX,你的对话框类应该从CDialogImpl和CWinDataExchange继承并有一个message map,比如

BEGIN_DDX_MAP(CMyDialogDlg)

DDX_INT(IDC_AMOUNT_INT, m_nAmount)

END_DDX_MAP()

目前这个map必须手工创建,但是很有可能在下一版的Visual C++ Wizard中支持通过向导创建(到目前为止VC7仍然不支持——译者注)。

 

System Dialogs And Property Sheets (atldlgs.h)

WTL对系统对话框提供了全面的支持

template <class T> class CFileDialogImpl

: public CDialogImplBase

WTL Developer’s Guide

class CFileDialog : public CFileDialogImpl<CFileDialog>

template <class T> class CFolderDialogImpl

class CFolderDialog : public CFolderDialogImpl<CFolderDialog>

class CCommonDialogImplBase : public CWindowImplBase

template <class T> class CFontDialogImpl

: public CCommonDialogImplBase

class CFontDialog : public CFontDialogImpl<CFontDialog>

class CRichEditFontDialogImpl : public CFontDialogImpl< T >

class CRichEditFontDialog : public

CRichEditFontDialogImpl<CRichEditFontDialog>

template <class T> class CColorDialogImpl

: public CCommonDialogImplBase

class CColorDialog : public CColorDialogImpl<CColorDialog>

template <class T> class CPrintDialogImpl

: public CCommonDialogImplBase

class CPrintDialog : public CPrintDialogImpl<CPrintDialog> template

<class T> class CPrintDialogExImpl

: public CWindow, public CMessageMap,

public IPrintDialogCallback,

public IObjectWithSiteImpl< T >

class CPrintDialogEx : public CPrintDialogExImpl<CPrintDialogEx>

template <class T> class CPageSetupDialogImpl

: public CCommonDialogImplBase

class CPageSetupDialog

: public CPageSetupDialogImpl<CPageSetupDialog>

template <class T> class CFindReplaceDialogImpl

: public CCommonDialogImplBase

class CFindReplaceDialog

: public CFindReplaceDialogImpl<CFindReplaceDialog>

 

WTL也为property sheet提供一系列的支持:

 

class CPropertySheetWindow : public CWindow

template <class T, class TBase = CPropertySheetWindow>

class CPropertySheetImpl : public CWindowImplBaseT< TBase >

class CPropertySheet : public CPropertySheetImpl<CPropertySheet>

class CPropertyPageWindow : public CWindow

template <class T, class TBase = CPropertyPageWindow>

class CPropertyPageImpl : public CDialogImplBaseT< TBase >

template <WORD t_wDlgTemplateID> class CPropertyPage

: public CPropertyPageImpl<CPropertyPage<t_wDlgTemplateID> >

 

Frames (atlframe.h)

下面的类用来支持frames

CFrameWndClassInfo 是frame window的类

class CFrameWndClassInfo

CFrameWindowImpl 是程序级用来管理frames的基本C++类

template <class TBase = CWindow, class TWinTraits =

CFrameWinTraits> class CFrameWindowImplBase

: public CWindowImplBaseT< TBase, TWinTraits >

template <class T, class TBase = CWindow, class TWinTraits =

CFrameWinTraits> class CFrameWindowImpl

: public CFrameWindowImplBase< TBase, TWinTraits >

 

为了支持MDI,WTL提供了这些类:

class CMDIWindow : public CWindow

template <class T, class TBase = CMDIWindow, class TWinTraits =

CFrameWinTraits>

class CMDIFrameWindowImpl : public CFrameWindowImplBase<TBase,

TWinTraits >

template <class T, class TBase = CMDIWindow, class TWinTraits =

CMDIChildWinTraits> class CMDIChildWindowImpl

: public CFrameWindowImplBase<TBase, TWinTraits >

 

COwnerDraw模板为实现owner draw功能提供帮助。它通常通过多重继承来添加到类中的。COwnerDraw和CCustomDraw是有区别的,CCustomDraw处理通过WM_NOTIFY发送的NM_CUSTOMDRAW通知消息。支持这个通知的有下面的通用控件:

Headers,list view, rebar,tooltip,trackbar和tree view控件。COwnerDraw处理WM_DRAWITEM,WM_MEASUREITEM,WM_COMPAREITEM和WM_DELETEITEM消息,这些消息一般是发送给owner-draw button,combobox,list view控件或菜单项目(itmes)。

template <class T> class COwnerDraw

 

CUpdateUI可以用来动态更新UI元素。菜单项目(items)和toolbar按钮可以用它来实现“可用”和“不可用(禁止)”状态。

class CUpdateUIBase;

template <class T> class CUpdateUI : public CUpdateUIBase

 

GDI(atlgdi.h)

WTL提供了管理所有GDI对象的模板。每个模板的逻辑型参数t_bManaged指定这个GDI对象是否在模板的析构函数里被删除(delete)。每个模板有两个typedefs,其中一个t_bManaged置true,另一个置false。这些模板包含了所有的win32 GDI APIs,为它们提供了类型安全的(typesafe)C++接口。

template <bool t_bManaged> class CPenT

typedef CPenT<false> CPenHandle;

typedef CPenT<true> CPen;

template <bool t_bManaged> class CBrushT

typedef CBrushT<false> CBrushHandle;

typedef CBrushT<true> CBrush;

template <bool t_bManaged> class CFontT

typedef CFontT<false> CFontHandle;

typedef CFontT<true> CFont;

template <bool t_bManaged> class CBitmapT

typedef CBitmapT<false> CBitmapHandle;

typedef CBitmapT<true> CBitmap;

template <bool t_bManaged> class CPaletteT

typedef CPaletteT<false> CPaletteHandle;

typedef CPaletteT<true> CPalette;

template <bool t_bManaged> class CRgnT

typedef CRgnT<false> CRgnHandle;

typedef CRgnT<true> CRgn;

template <bool t_bManaged> class CDCT

typedef CDCT<false> CDCHandle;

typedef CDCT<true> CDC;

 

从CDC还继承出来一些工具类(helper classes)用来提供额外的功能。CPaintDC用来处理WM_PAINT消息,它在构造函数里调用了Win32的BeginPaint,在析构函数里调用EndPaint。CClientDC和CWindowDC用来取得一个HWND的客户区和窗口DC。CEnhMetaFileDC用来在一个“增强元文件(enhanced metafile)中绘画,它的构造函数调用了Win32的CreateEnhMetaFile,析构函数调用了CloseEnhMetaFile。

class CPaintDC : public CDC

class CClientDC : public CDC

class CWindowDC : public CDC

class CEnhMetaFileDC : public CDC

 

WTL还为enhanced metafile提供了额外的支持。CEnhMetaFileT是对一个enhanced metafile句柄的包装。CEnhMetaFileInfo提供了对win32的GetEnhMetaFileBits、GetEnhMetaFileDescription,

GetEnhMetaFileHeader 和 GetEnhMetaFilePixelFormat的调用

template <bool t_bManaged> class CEnhMetaFileT

typedef CEnhMetaFileT<false> CEnhMetaFileHandle;

typedef CEnhMetaFileT<true> CEnhMetaFile;

class CEnhMetaFileInfo

 

其他(atlmisch)

WTL还为常用数据类型提供了包装类。WTL的CString是MFC CString的完美模仿和代替品。还有CSize,CPoint和CRect

class CSize : public tagSIZE

class CPoint : public tagPOINT

class CRect : public tagRECT

class CString;

 

处理最近文件列表(recent file list)和文件搜索

class CRecentDocumentList;

class CFindFile;

 

打印(atlprint.h)

WTL为打印提供了很好的支持。

PrinterInfo数据被template <unsigned int t_nInfo> class CPrinterInfo的支持。下面的模板有来处理打印机句柄:

template <bool t_bManaged> class CPrinterT

typedef CPrinterT<false> CPrinterHandle;

typedef CPrinterT<true> CPrinter;

 

处理 DEVMODE的模板

template <bool t_bManaged> class CDevModeT;

typedef CDevModeT<false> CDevModeHandle;

typedef CDevModeT<true> CDevMode;

 

向打印机绘画是使用这个DC类:

class CPrinterDC : public CDC

 

要获得打印任务(job)的信息,使用

class IPrintJobInfo

class CPrintJobInfo : public IPrintJobInfo

class CPrintJob;

 

打印预览窗口

class CPrintPreview;

template <class T, class TBase = CWindow, class TWinTraits =

CControlWinTraits>

class CPrintPreviewWindowImpl

:public CWindowImpl<T, TBase, TWinTraits>, public CPrintPreview

class CPrintPreviewWindow

: public CPrintPreviewWindowImpl<CPrintPreviewWindow>

 

滚动(Scrolling)(atlscrl.h)

窗口滚动是被下面这些类和模板支持的:

template <class T> class CScrollImpl

template <class T, class TBase = CWindow,

class TWinTraits = CControlWinTraits>

class CScrollWindowImpl

:public CWindowImpl<T,TBase,TWinTraits>,public CScrollImpl< T >

template <class T> class CMapScrollImpl: public CScrollImpl< T >

template <class T, class TBase = CWindow,

class TWinTraits = CControlWinTraits>

class CMapScrollWindowImpl : public CWindowImpl< T, TBase,

TWinTraits >, public CMapScrollImpl< T >

 

平面分割的滚动条:

template <class TBase = CWindow> class CFSBWindowT

:public TBase, public CFlatScrollBarImpl<CFSBWindowT< TBase > >

typedef CFSBWindowT<CWindow> CFSBWindow;

 

分割条(splitters)(atlsplit.h

水平和垂直的分割条可以用下面的三个模板实现:

template <class T, bool t_bVertical = true> class CSplitterImpl;

template <class T, bool t_bVertical = true, class TBase =

CWindow, class TWinTraits = CControlWinTraits>

class CSplitterWindowImpl : public CWindowImpl< T, TBase, TWinTraits

>, public CSplitterImpl<CSplitterWindowImpl< T , t_bVertical, TBase,

TWinTraits >, t_bVertical>

template <bool t_bVertical = true> class CSplitterWindowT

: public CSplitterWindowImpl<

CSplitterWindowT<t_bVertical>, t_bVertical>

typedef CSplitterWindowT<true> CSplitterWindow;

typedef CSplitterWindowT<false> CHorSplitterWindow;

 

菜单(atluser.h)

CMenuItemInfo类是Win32中MENUITEMINFO结果的包装,CMenuT可以用来管理菜单,它提供了对菜单所有属性的类型安全的访问。

class CMenuItemInfo : public MENUITEMINFO

template <bool t_bManaged> class CMenuT

 

WTL中没有什么?

 

(本节翻译内容并没有完全照搬原文,和原文相比有所删略。——译者注)

在看了WTL中的主要功能后,我们来看看WTL不支持的东西。

WTL的唯一目标是为开发人员提供用户界面,在这方面它已经做得非常好了。它并没有偏离该目标而设计其他领域。

 

没有Document支持

WTL提供了frame和view,但是没有document。WTL所关注的是用户界面,而document是不可见的,所以它不是WTL关心的范围。

 

没有Active Document支持

……

没有ISAPI支持

……

没有WinInet支持

……

没有对线程和同步进行包装

……

没有数据库支持

……

 

开发的问题

要开始使用WTL,还有下面几个问题需要理解。

最终产品

使用WTL建立的程序体积是很小的,AppWizard生成的默认SDI程序编译后的exe文件大小只有64K,TinyWTL例程由于去掉了多余的功能,编译后只有24K大小。一个真实的商业级程序应该不会超过250K。并且这些文件经过压缩后将会再减少2/3的体积,可以在Internet上快速下载。

在Build完成后,如果你没有使用CRT和其他的DirectX之类的库,那么WTL工程编译后的exe或dll就是你唯一需要发送给最终用户的文件了。WTL程序没有额外的依赖。文件少,出现问题的几率就少。

 

CRT

C-Runtime library上Win32 API之上的一组C函数,通常被称作CRT。CRT的源代码是VC++的一部分(在src目录),如果你仔细看一下的话,就会发现这些CRT的函数是用ANSI C实现的,一些直接调用了APIs,一些通过调用中间函数间接调用了APIs。CRT大部分是来自ANSI C标准库的一些函数(printf,strok等),但是也有一些Win32平台相关的函数(比如(beginthreadex在做了一些CRT初始化后调用了CreateThread API)

如果你的程序只使用ANSI C标准库,你的代码就是可移植的。有许多百万行代码级的工程在经过不到2%的更改后就可以在Windows和UNIX上顺利通过编译和正常运行。CRT确实在某些领域提供了Win32所没有的功能,比如string形式的浮点数、C++异常和为全局变量调用构造/析构函数。

如果你使用ATL和WTL进行编程,你的代码绝对不可能移植到UNIX/LINUX之上,这样有个问题就产生了,我到底有必要连接到CRT吗?CRT在很大程度上是Win32 APIs的重复,所以大部分情况下,大案是“No”。离开了C++异常处理和全局变量的构造/析构函数,也可以生存,而使用了CRT,你的程序体积将增大,并有了额外的外部依赖(MSVCRT.dll)而这个库有多个版本,这也可能成为麻烦的根源。

WTL AppWizard生成的工程的设置使得CRT在debug build是可用(为了调用ATLASSERT),而在release build时并不包含进来(预处理指令中的_ATL_MIN_CRT)。如果你没有注意到这个细节,可能会对“使用了CRT的WTL工程怎么也无法在release模式下编译通过”的问题束手无策。注意:CRT在Release模式下默认是不被包含的。

 

如果你真的打算使用CRT,只要去掉_ATL_MIN_CRT宏就可以了,(VC7中是把“项目”->“属性”对话框中的“在ATL中最小使用CRT”选项置“否”)。

 

如果使用了CRT,关于多线程的一个有趣的问题就产生了。CRT有多个版本,一些是静态连接的,一些的动态加载的,一些是用于单线程应用程序的,一些是用于多线程程序的。如果你在不止一个线程中使用CRT,你就必须使用多线程版本的CRT。同一个工程中的所有EXE和DLL也必须使用一致的设置(在DevStudio的 Project settings对话框的Generation类别里)。

 

错误处理

(本段翻译有删略——译者注)

在WTL程序中要使用C++异常处理,就必须依赖CRT(当然,如果你愿意可以使用)。另外对API可以使用GetLastError和ATLASSERT

 

WTL名称空间(namespace)

新的ISO C++标准引入了名称空间的概念,WTL为了避免和其他类库产生名称冲突,它的每一个头文件都是以下面的代码开始:

namespace WTL

{

并以:

}; //namespace WTL

结束

……

……

(省略关于名称空间的使用的说明——译者)

 

模板/类/方法名

 

WTL的命名管理沿用MFC的,由于它们两个都是基于Win32 API的,所以这么做是有意义的。并且多数的WTL程序员是来自MFC程序员。

WTL的类名是这样的,CEdit,CStatic和CDC。窗口消息的处理程序名称为OnInitDialog and OnOK。数据交换使用DDX,方法名为DoDataExchange。

WTL和MFC不同的地方是,在有些地方,WTL明智地遵循了Win32的名称,比如Win32的UpDown控件在WTL中为CUpDownCtrlT,而在MFC中为CSpinButtonCtrl。

 

Windows的版本

WTL全面支持Win2000和WinMe(以及Windows XP——译者)中的新UI特性,但也可以用于旧版本的Windows,这个可以通过#define一个WINVER来实现。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息