初识WTL

代码运行效果图如下:

1.前言

虽然MFC的功能很强大,但Windows Template Library(WTL)的出现,无疑说明了MFC有一定的弊病。和MFC相比,功能并没有MFC完善。比如MFC支持doc/view架构,而WTL并不支持。同时,WTL也没有Microsoft的官方支持。但是,WTL是基于模版(template)的,其应用程序最小只有24KB,同时不象MFC,依赖DLL。但是WTL也实现了CString、CRect、CSize、CPoint等常用的类,还CStaticT、CButtonT、CListBoxT、CComboBoxT(这些在WTL库文件atlctrls.h、atlctrlw.h、atlctrlx.h中就能看到)等用起来和MFC版本也没太大不同。

2.准备工作

首先安装WTL AppWizard,现在最高版本应该是WTL7.0,直接运行setup脚本文件就可以了,这里给大家几个下载地址:

1) http://www.vckbase.com/tools/listtools.asp?tclsid=111

2) http://www.microsoft.com/downloads/details.aspx?familyid=128e26ee-2112-4cf7-b28e-7727d9a1f288&displaylang=en

3) http://www.copathway.com/vchelp/zsrc/wtlm.asp?type_id=70&class_id=1&cata_id=3&article_id=374

这样当你启动VC6.0后,File/New时,在Project属性页就能看到添加了一项ATL/WTL AppWizard。你可以直接把WTL的库文件( 共16个.h文件)拷贝到vc的安装目录VC98/Include中,也可以放到你的工程文件夹中。

3.应用实例1---SDI中状态栏的应用

(1) File/New,如图:

(2) OK后,

SDI(Single Document Interface)应用程序通常只有一个主窗口(通常是一个框架窗口,Frame Window)。框架窗口包含菜单、工具栏、状态栏和称为视(View)的客户工作区。

Multip-SDI(Multiple Threads SDI),就像IE浏览器,使用"文件/新建/窗口"命令后,会出现另一个IE窗口。

MDI(Multiple Document Interface)应用程序有一个主框架窗口,但有多个子框架窗口。每个子窗口都有自己的视(View),和MFC的相似。

Dialog应用程序是基于对话框的。

(3) Next

 

(4) 在产生的文件中可以看到WTL确实不支持Doc/View.

WTL对单界面线程的封装:WTL使用一个_Module全局变量来保存全局数据,并通过它来引用应用程序级的代码。在WTL中,该变量是CAppModule的实例,想象MFC的theApp。

●下面对MyTestWTL.cpp文件中的函数作一些说明:

Ⅰ:

01. int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
02. {
03.     HRESULT hRes = ::CoInitialize(NULL);
04.     // If you are running on NT 4.0 or higher you can use the following call instead to 
05.     // make the EXE free threaded. This means that calls come in on a random RPC thread.
06.     // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
07.   
08.     ATLASSERT(SUCCEEDED(hRes));
09.   
10.     // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
11.     ::DefWindowProc(NULL, 0, 0, 0L);
12.     AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);       // add flags to support other controls
13.     hRes = _Module.Init(NULL, hInstance);
14.     ATLASSERT(SUCCEEDED(hRes));
15.     int nRet = Run(lpstrCmdLine, nCmdShow);     //程序逻辑,调用全局函数Run()
16.     _Module.Term();     // 终止模块
17.   
18.     ::CoUninitialize();
19.   
20.     return nRet;
21. }

入口函数名为_tWinMain()。当使用UNICODE时,编译器会将它替换为wWinMain(),否则,为WinMain()。入口函数其实就是主线程(_Module)的起始点,这和SDK,MFC一个道理。一个_Module还维持一个消息循环Map。

Ⅱ: 

01. int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
02. {
03.     CMessageLoop theLoop;
04.     _Module.AddMessageLoop(&theLoop);
05.     CMainFrame wndMain;
06.     if(wndMain.CreateEx() == NULL)
07.     {
08.         ATLTRACE(_T("Main window creation failed!\n"));
09.         return 0;
10.     }
11.     wndMain.ShowWindow(nCmdShow);
12.     int nRet = theLoop.Run();
13.     _Module.RemoveMessageLoop();
14.     return nRet;
15. }

该函数创建了一个CMessageLoop实例,该实例包含了这个线程的消息循环。这些消息循环都放在模块的全局消息循环中,通过线程的ID来索引。这样,该线程的其它代码就能访问得到。每一个应用程序维护一个消息循环队列Map,应用程序中的每个线程都通过"_Module.AddMessageLoop(&theLoop)",把该线程的消息循环加入到_Module的消息循环Map中。消息循环对象包含了消息过滤和空闲处理。每个线程都可以加入空闲处理代码和消息过滤。

● 添加代码:

Ⅰ:在stdafx.h中添加: 

1. #include < atlctrls.h >
2. #include < atlctrlx.h >
3. #include < atlctrlw.h >   //这三个是WTL 中实现常用控件类
4. #include < atldlgs.h >
5. #include < atlmisc.h >    //WTL 使用类像 CString等
6. #include < atlddx.h > //WTL 使用像MFC中DDX/DDV 机制

Ⅱ:添加3个图标资源:IDR_DEFAULT, IDR_DATE, IDR_TIME

Ⅲ:在MainFrm.h中添加 CMultiPaneStatusBarCtrl m_Mstatus;

Ⅳ:在MainFrm.cpp中添加

在函数最前面声明两个数组: 

1. static int arrPanes[] = { IDR_DEFAULT, IDR_DATE, IDR_TIME };
2. static int arrWidths[] = { 450,200, 600 }; //你自己修改一下值看看有什么不同

在OnCreate函数中添加: 

01. CreateSimpleStatusBar();
02. m_Mstatus.SubclassWindow(m_hWndStatusBar);
03. m_Mstatus.SetPanes(arrPanes,sizeof(arrPanes)/sizeof(int), false);
04. m_Mstatus.SetPaneWidth(IDR_DEFAULT,400);
05. m_Mstatus.SetPaneWidth(IDR_DATE,200);
06. m_Mstatus.SetPaneWidth(IDR_TIME,900);
07. m_Mstatus.SetPaneIcon(IDR_DEFAULT,AtlLoadIconImage(IDR_DEFAULT, LR_DEFAULTCOLOR));
08. m_Mstatus.SetPaneIcon(IDR_DATE, AtlLoadIconImage(IDR_DATE, LR_DEFAULTCOLOR));
09. m_Mstatus.SetPaneIcon(IDR_TIME, AtlLoadIconImage(IDR_TIME, LR_DEFAULTCOLOR));
10. m_Mstatus.SetPaneText(IDR_DATE,"WTL is very wonderful!",0);
11. m_Mstatus.SetPaneText(IDR_TIME,"WWW.VCKBASE.COM",0);

这些代码相信大家一看就会明白!

参考资料:

深入剖析WTL――Win32模型,作者:建新

WTL for MFC Programmers 作者:Michael Dunn

在此深表感谢

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
WTL 具有两面性,确实是这样的。它没有MFC的界面(GUI)类库那样功能强大,但是能够生成很小的可执行文件。如果你象我一样使用MFC进行界面编程,你会觉得MFC提供的界面控件封装使用起来非常舒服,更不用说MFC内置的消息处理机制。当然,如果你也象我一样不希望自己的程序仅仅因为使用了MFC的框架就增加几百K的大小的话,WTL就是你的选择。当然,我们还要克服一些障碍: ATL样式的模板类初看起来有点怪异 没有类向导的支持,所以要手工处理所有的消息映射。 MSDN没有正式的文档支持,你需要到处去收集有关的文档,甚至是查看WTL的源代码。 买不到参考书籍 没有微软的官方支持 ATL/WTL的窗口与MFC的窗口有很大的不同,你所了解的有关MFC的知识并不全部适用与WTL。 从另一方面讲,WTL也有它自身的优势: 不需要学习或掌握复杂的文档/视图框架。 具有MFC的基本的界面特色,比如DDX/DDV和命令状态的自动更新功能(译者加:比如菜单的Check标记和Enable标记)。 增强了一些MFC的特性(比如更加易用的分隔窗口)。 可生成比静态链接的MFC程序更小的可执行文件(译者加:WTL的所有源代码都是静态链接到你的程序中的)。 你可以修正自己使用的WTL中的错误(BUG)而不会影响其他的应用程序(相比之下,如果你修正了有BUG的MFC/CRT动态库就可能会引起其它应用程序的崩溃。 如果你仍然需要使用MFCMFC的窗口和ATL/WTL的窗口可以“和平共处”。(例如我工作中的一个原型就使用了了MFC的 CFrameWnd,并在其内包含了WTL的CSplitterWindow,在CSplitterWindow中又使用了MFC的CDialogs -- 我并不是为了炫耀什么,只是修改了MFC的代码使之能够使用WTL的分割窗口,它比MFC的分割窗口好的多)。 在这一系列文章中,我将首先介绍ATL的窗口类,毕竟WTL是构建与ATL之上的一系列附加类,所以需要很好的了解ATL的窗口类。介绍完ATL之后我将介绍WTL的特性以并展示它是如何使界面编程变得轻而易举。 对第一章的简单介绍
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值