WTL学习之创建单文档程序的主要界面元素

作者:朱金灿

来源:http://blog.csdn.net/clever101

 

      WTL的安装程序提供了提供了一个类似的MFC的应用程序向导,开发环境为Win XP + sp3,VS 2005+ sp1,WTL8.0。今天就让我们使用这个向导学习一下如何使用WTL创建一个单文档程序。

 

1. 选择WTL程序项目,输入项目名,如下图:


2. 使用如下设置生成项目,如下面图:

让我们编译一下程序,看看程序的效果图:

   

        是不是和MFC的单文档程序的效果差不多呢?让我们看看生成哪些类及重要的代码。先看看主函数吧:

CAppModule _Module;

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CMainFrame wndMain;

	if(wndMain.CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!\n"));
		return 0;
	}

	wndMain.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
}

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to 
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//	HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	ATLASSERT(SUCCEEDED(hRes));

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	::DefWindowProc(NULL, 0, 0, 0L);

	AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);	// add flags to support other controls

	hRes = _Module.Init(NULL, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	int nRet = Run(lpstrCmdLine, nCmdShow);

	_Module.Term();
	::CoUninitialize();

	return nRet;
}

CAppModule _Module可以看做是MFC程序的应用程序类对象,起着初始化和建立消息循环的作用。我们再分析下WinMain函数做了哪些工作:

  1. ::CoInitialize(NULL); —— 初始化COM环境
  2. ::DefWindowProc(NULL, 0, 0, 0L); ——貌似是解决在使用微软的unicode层时ATL窗口的thunking的问题,看不明白,暂且放过。
  3. AtlInitCommonControls —— 支持ATL的其它控件的特殊属性。
  4. _Module.Init —— 应用程序初始化
  5. 调用Run函数,Run函数的主要作用是创建主框架窗口,进入消息循环。
  6. _Module.Term(); —— 销毁应用程序
  7. ::CoUninitialize();—— COM环境销毁。

 

我们再看看主框架窗口类——CMainFrame。这个类的作用类似于MFC程序的CMainFrame类,不过其类结构和MFC程序的CMainFrame类有很大不同。CMainFrame类主要派生自四个类:CFrameWindowImpl、CUpdateUI、CMessageFilter和CIdleHandler。从名字上我们可以猜得出CFrameWindowImpl是窗口基类、CUpdateUI负责界面更新、CMessageFilter负责消息截取,CIdleHandler负责空闲处理。

 

我们再看看CMainFrame类的数据成员:

CWtlToolbarView m_view;  —— 视图窗口,相当于MFC的视图类。

 

CCommandBarCtrl m_CmdBar; —— 菜单栏

 

CMainFrame类的创建顺序实际上是这样的:

1.     CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);——创建空的rebar风格的工具栏

 

   2.下面代码是创建菜单栏,并把它加到之前创建空的工具栏

   		HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
		// attach menu
		m_CmdBar.AttachMenu(GetMenu());
		// load command bar images
		m_CmdBar.LoadImages(IDR_MAINFRAME);
		// remove old menu
		SetMenu(NULL);
		AddSimpleReBarBand(hWndCmdBar);

  1. 下面代码是创建实际的工具栏,并把它加到之前创建空的工具栏:
HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
		AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
		UIAddToolBar(hWndToolBar); // 确保可以更新工具栏界面

4. 创建一个简单的状态栏,代码如下:

	CreateSimpleStatusBar();

  1. 创建视图窗口,代码如下:
		m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);

 

还有两个类:

视图类:class CWtlToolbarView : public CWindowImpl<CWtlToolbarView>

和关于对话框类:class CAboutDlg : public CDialogImpl<CAboutDlg>。因为这个类比较简单,这里就不作介绍了。

 

         比起MFC程序,你会发现WTL程序少了文档类。我觉得这倒是WTL程序设计巧妙的地方。我常常觉得MFC程序中的文档类是一个比较鸡肋的类,理由很简单:文档类主要做的是序列化方面的工作,一是没那么多程序需要序列化;二是序列化工作只是一个简单功能,你可以在视图类做,也可以在框架类做,有什么必要专门创建一个类来做这个工作?你可能觉得视图类有时也是多余的,实际上也有可能,而WTL也考虑到了,向导的最后一步允许你是否选择:Use a view window。这也是WTL库比起MFC库的优点:MFC库不管你需要不需要,一股脑给你一堆类,而WTL则是允许你自由组装和裁剪,就使用自由度WTL比MFC要好。


      如果你觉得我的博客对你有帮助,请在下面网址中博客之星评选活动投我一票:

http://vote.blog.csdn.net/item/blogstar/clever101(单击候选人介绍下面的投他一票那个按钮)

参与投票有机会获奖:

     最佳贡献奖:通过微博分享活动就有机会获得30元充值卡一张(每周抽选5名)
    幸运奖:凡参与投票用户就有机会获得精美小礼品一份。(每周抽选5名)
    积极参与奖:所有参与投票并符合条件的用户均可获得20个下载积分。







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

clever101

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值