WTL快速之旅

目标
该章的目标为
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 介绍 WTL 中的模板( templates )和类( classes
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 列举 WTL 中没有包含的特性
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 描述诸如 WTL 名称空间( namespace )、 CRT 和错误处理( error handling
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 列举 WTL 的宏( macros
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 看一下如何利用 AUTOEXP.DAT 来改进调试过程
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 回顾 CRT WTL 的使用
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 比较 MFC WTL
<!--[if !supportLists]--> Ÿ       <!--[endif]--> 涵盖 WTL CString
 
WTL 的分发
WTL 的分发包有三部分: include 目录下的 15 C++ 头文件, WTL AppWizard sample 工程,其中核心的部分在 include 目录, AppWizard 是用来生成调用定义在头文件中的模板 / 类的工程的, sample 工程是用来说明如何使用这些模板和类的。你可能会花费数小时的时间来搞清楚 AppWizard 生成的代码和哪些 sample 工程,但是你需要数周的时间来学习定义在那些头文件中的模板和类。
WTL 提供了大量的专注于用户界面( user interface )开发的模板和类,它们可以和 ATL STL VC++OLE DB Data templates 等其他模板库一起使用,并不存在竞争者关系。所有这些类加起来可以被看作是 MFC VB 的竞争者。
在大多数地方, WTL 是低层 Win32API 之上很“薄”的一层封装,在少数领域(比如, scroll-bars splitters print preview WTL 也有实质性的新功能。
除了 WTL AppWizard ,没有其他的和 DevStudio 集成的 WTL 向导了,我们可以用 ATL Windows Message Handler Wizard 来添加 handlers ,但是它们并没有对 WTL’s message crackers
 
模板和类
WTL C++ 模板和类的集合。除了若干几个类使用了继承(比如, CDC CPaintDC cWindowDC CPrintDC )这个别的情况外, WTL 的模板和类是相互独立的,并没有公共的“根”,所以没有所谓的“ WTL 继承层次图”,因为 WTL 本身就没有复杂的层次关系。在这一节中我们将对 WTL 所涉及的功能领域做一个概述,并列举出可用的模板和类。我们也将列出那些优雅地包含各自功能领域的头文件。
每一个 WTL 应用程序必须包含 atlapp.h ,它在内部又包含了 atluser.h atlgdi.h 。其他的 WTL 头文件只有在用到它们所包含的功能时才是必需的。
 
Application Services atlapp.h
这些类提供了模块( exe dll )的基本功能和消息循环( message loop )。它们也支持消息过滤( messagefiltering )和空闲处理( idle handling )。
class CAppModule : public CComModule
class CServerAppModule : public CAppModule
class CMessageLoop
class CMessageFilter
class CIdleHandler
 
标准控件(Standard Controls)和通用控件(Common Controls) (atlctrls.h)
WTL 提供了WindowsOS中每一个标准控件和通用控件的包装模板。这些模板一般是和ATL的CWindow一起使用,所以WTL也为每个控件提供了相应的typedef。在程序中我们一般使用这些typedef出来的值而不是直接使用模板。这些控件的定义如下:
template <class TBase>class CStaticT;
typedefCStaticT<CWindow> CStatic;
下面是一个完整的列表:
CButtonT           CButton           CTrackBarCtrlT         CTrackBarCtrl
CListBoxT          CListBox          CUpDownCtrlT           CUpDownCtrl
CComboBoxT         CComboBox         CProgressBarCtrlT      CProgressBarCtrl
CEditT             CEdit             CHotKeyCtrlT           CHotKeyCtrl
CScrollBarT        CScrollBar        CAnimateCtrlT          CAnimateCtrl
CToolTipCtrlT CToolTipCtrl      CRichEditCtrlT         CRichEditCtrl
CHeaderCtrlT       CHeaderCtrl       CReBarCtrlT            CReBarCtrl
CListViewCtrlT     CListViewCtrl     CMonthCalendarCtrlT    CMonthCalendarCtrl
CTreeViewCtrlT     CTreeViewCtrl     CDateTimePickerCtrlT  CDateTimePickerCtrl
CToolBarCtrlT CToolBarCtrl      CIPAddressCtrlT        CIPAddressCtrl
CStatusBarCtrlT    CStatusBarCtrl    CPagerCtrlT            CPagerCtrl
CTabCtrlT          CTabCtrl
 
这些控件可以用 Create 方法来创建,但是更多情况下我们用 ResourceView 创建对话框资源和其中的控件,这时我们可以在代码中实例化一个这些控件模板然后调用 Attach 方法来挂接到这些控件上。所以为一个对话框中的 list box 添加字符串可能使用下面的方法:
CListBox m_ListBox;
. . .
m_ListBox.Attach(GetDlgItem(IDC_LIST_DEMO));
m_ListBox.AddString(TEXT("One"));
注意 ATL 已经支持 ActiveXcontrol containment 所以 WTL 就没有提供额外的支持。 WTL 中有一些额外的控件类 / 模板来提供额外的功能。 WTL CComboboxEx Win32ComboBoxEx 控件的包装,它为标准的 combobox 提供了 Image List 支持。在 WTL 中, CComboBoxExT 是从 CComboBoxT 继承的,并根据需要添加了额外的功能:
template <class TBase> class CComboBoxExT
: public CComboBoxT< TBase >
typedef CComboBoxExT<CWindow> CComboBoxEx;
WTL 支持“平面风格的滚动条( flat scroll-bars )”,在功能上它们和普通滚动条一样,但是在外观上,就像它们的名字,它们是平面风格的,没有突起的斜面边界。
template <class T> class CFlatScrollBarImpl
template <class TBase> class CFlatScrollBarT :public TBase,
public CFlatScrollBarImpl<CFlatScrollBarT< TBase> >
typedef CFlatScrollBarT<CWindow> CFlatScrollBar;
Treeview 控件用来处理HTREEITEM(一个包含tree中各个节点的复杂结构的句柄)。为了简化对HTREEITEM的处理,WTL提供了CTreeItem类,它提供了置文本、图片、数据、状态信息和遍历树的方法。CTreeViewCtrlExT模板是基于CTreeViewCtrlT模板的
template <class TBase> class CTreeViewCtrlExT :
public CTreeViewCtrlT< TBase >
typedef CTreeViewCtrlExT<CWindow> CTreeViewCtrlEx;
class CTreeItem; // wrapper for HTREEITEM
CTreeViewCtrlExT 提供了处理CTreeItem和原始HTREEITEM句柄的方法。比如CTreeViewCtrlT提供了插入item的方法:
HTREEITEM InsertItem(LPTV_INSERTSTRUCT lpInsertStruct);
而CtreeViewCtrlExT提供这个方法:
CTreeItem InsertItem(LPTV_INSERTSTRUCT lpInsertStruct);
Edit boxes 和rich-editboxes必需处理一些通用的消息,比如ID_EDIT_COPY, ID_EDIT_CUT,ID_EDIT_PASTE和ID_EDIT_UNDO。有两个类可以用来自动处理这些消息。
template <class T> class CEditCommands;
template <class T> class CRichEditCommands
: public CEditCommands< T >
还有管理imagelist和toolinfo的工具类。
class CImageList;
class CToolInfo : public TOOLINFO
一个drag-listbox和一个普通的listbox很类似,但是提供了拖动item的功能。CDragListNotifyImpl提供了拖放过程中的消息处理。
template <class TBase> class CDragListBoxT
: public CListBoxT< TBase >
typedef CDragListBoxT<CWindow> CDragListBox;
template <class T> class CDragListNotifyImpl;
一些通用组件可以配置为custom draw来呈现自己的itmes。它们会发送NM_CUSTOMDRAW消息,下面这个WTL模板就可以为处理这个消息提供帮助:
template <class T> class CCustomDraw
 
Command Bars (atlctrlw.h)
以前我们在程序中用标准的菜单条来向终端用户提供命令,然后是工具条( toolbar ),后来又有了最初随 InternetExplorer 一起发布的 rebar 控件,它为菜单和工具条提供了统一的“容器”。 WTL 支持一种叫做 command bar 的控件,但是和 Word2000 中的有区别。
WTL 中,一个 commandbar 是一个增强版的 menu bar tool bar 仍然要使用。在 WTL 生成的程序中, command bar tool bar 被分别容纳在一个 rebar 控件的不同 band 中, band 可以在 rebar 中移动。 Command bar (和 tool bar )在 WTL 中是不可“停靠( dockable )”的。
WTL command bar 显示菜单并在菜单的旁边显示对应的工具条图标,方便了终端用户。
WTL 提供了用于 command bar 的类:
class CCommandBarCtrlBase : public CToolBarCtrl
template <class T, class TBase = CCommandBarCtrlBase,
class TWinTraits = CControlWinTraits>
class CCommandBarCtrlImpl
: public CWindowImpl< T, TBase, TWinTraits>
class CCommandBarCtrl
: public CCommandBarCtrlImpl<CCommandBarCtrl>
当使用 WTL AppWizard 的默认设置生成一个程序时,你的程序会自动使用 command bar 而无需你额外的动作。
 
高级控件( atlctrlx.h
WTL 支持更多的高级控件。
CBitmapButton 提供了可以显示 imagelist 图片的 pushbutton
template <class T, class TBase = CButton,
class TWinTraits = CControlWinTraits>
class CBitmapButtonImpl
: public CWindowImpl< T, TBase, TWinTraits>
class CBitmapButton : publicCBitmapButtonImpl<CBitmapButton>
 
CCkeckListLiew 提供了一组 checkboxes
template <DWORD t_dwStyle, DWORD t_dwExStyle,
DWORD t_dwExListViewStyle> classCCheckListViewCtrlImplTraits;
typedef CCheckListViewCtrlImplTraits<WS_CHILD |WS_VISIBLE |
LVS_REPORT | LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE,
LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT>
CCheckListViewCtrlTraits;
template <class T, class TBase = CListViewCtrl,
class TWinTraits = CCheckListViewCtrlTraits>
class CCheckListViewCtrlImpl
: public CWindowImpl<T, TBase, TWinTraits>;
class CCheckListViewCtrl
: public CCheckListViewCtrlImpl<CCheckListViewCtrl>;
 
CHyperLink 允许在程序中嵌入web-links,当按下时会打开一个浏览器显示这个URL。
template <class T, class TBase = CWindow,
class TWinTraits = CControlWinTraits>
class CHyperLinkImpl
: public CWindowImpl< T, TBase, TWinTraits >
class CHyperLink : publicCHyperLinkImpl<CHyperLink>
 
CWaitCursor 可以根据输入参数设置光标,默认值为IDC_WAIT。
class CWaitCursor
 
CMultiPaneStatusBarCtrl 提供了一个包含了“子分割”的状态条(status bar)不同的“分割”上可以放置不同的文本。
 
template <class T, class TBase = CStatusBarCtrl>
class CMultiPaneStatusBarCtrlImpl
: public CWindowImpl< T, TBase >
class CMultiPaneStatusBarCtrl
: publicCMultiPaneStatusBarCtrlImpl<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 : publicCFileDialogImpl<CFileDialog>
template <class T> class CFolderDialogImpl
class CFolderDialog : publicCFolderDialogImpl<CFolderDialog>
class CCommonDialogImplBase : public CWindowImplBase
template <class T> class CFontDialogImpl
: public CCommonDialogImplBase
class CFontDialog : publicCFontDialogImpl<CFontDialog>
class CRichEditFontDialogImpl : publicCFontDialogImpl< T >
class CRichEditFontDialog : public
CRichEditFontDialogImpl<CRichEditFontDialog>
template <class T> class CColorDialogImpl
: public CCommonDialogImplBase
class CColorDialog : publicCColorDialogImpl<CColorDialog>
template <class T> class CPrintDialogImpl
: public CCommonDialogImplBase
class CPrintDialog : publicCPrintDialogImpl<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 也为propertysheet提供一系列的支持:
 
class CPropertySheetWindow : public CWindow
template <class T, class TBase =CPropertySheetWindow>
class CPropertySheetImpl : public CWindowImplBaseT<TBase >
class CPropertySheet : publicCPropertySheetImpl<CPropertySheet>
class CPropertyPageWindow : public CWindow
template <class T, class TBase =CPropertyPageWindow>
class CPropertyPageImpl : public CDialogImplBaseT<TBase >
template <WORD t_wDlgTemplateID> classCPropertyPage
: 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, classTWinTraits =
CFrameWinTraits> class CFrameWindowImpl
: public CFrameWindowImplBase< TBase, TWinTraits >
 
为了支持MDI,WTL提供了这些类:
class CMDIWindow : public CWindow
template <class T, class TBase = CMDIWindow, classTWinTraits =
CFrameWinTraits>
class CMDIFrameWindowImpl : publicCFrameWindowImplBase<TBase,
TWinTraits >
template <class T, class TBase = CMDIWindow, classTWinTraits =
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还继承出来一些工具类(helperclasses)用来提供额外的功能。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是MFCCString的完美模仿和代替品。还有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, classTWinTraits =
CControlWinTraits>
class CPrintPreviewWindowImpl
:public CWindowImpl<T, TBase, TWinTraits>, publicCPrintPreview
class CPrintPreviewWindow
: publicCPrintPreviewWindowImpl<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>,publicCScrollImpl< T >
template <class T> class CMapScrollImpl: publicCScrollImpl< 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> classCSplitterImpl;
template <class T, bool t_bVertical = true, classTBase =
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> classCSplitterWindowT
: 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) 而这个库有多个版本,这也可能成为麻烦的根源。
WTLAppWizard 生成的工程的设置使得CRT在debugbuild是可用(为了调用ATLASSERT),而在releasebuild时并不包含进来(预处理指令中的 _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来实现。
 
待续……
 

你可能感兴趣的:(WTL快速之旅)