代码运行效果图如下:
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
在此深表感谢