科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件MFC程序员的WTL指南之WTL 界面基类

MFC程序员的WTL指南之WTL 界面基类

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这一部分我讲的内容包括生成一个基本的主窗口和WTL提供的一些的改进

作者:lithe 来源:csdnblog 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
从WTL的应用程序生成向导能得到什么

  WTL的发布版本附带一个很棒的应用程序生成向导,让我们以一个SDI 应用为例看看它有什么特性。

  使用向导的整个过程

  在VC的IDE环境下单击File|New菜单,从列表中选择ATL/WTL AppWizard,我们要重写时钟程序,所以用WTLClock作为项目的名字:


  在下一页你可以选择项目的类型,SDI,MDI或者是基于对话框的应用,当然还有其它选项,如下图所示设置这些选项,然后点击“下一步”:


  在最后一页你可以选择是否使用toolbar,rebar和status bar,为了简单起见,取消这些选项并单击“结束”。


  查看生成的代码

  向导完成后,在生成的代码中有三个类:CMainFrame, CAboutDlg, 和CWTLClockView,从名字上就可以猜出这些类的作用。虽然也有一个是视图类,但它仅仅是从CWindowImpl派生出来的一个简单的窗口类,没有象MFC那样的文档/视图结构。

  还有一个_tWinMain()函数,它先初始化COM环境,公用控件和_Module,然后调用全局函数Run()。Run()函数创建主窗口并开始消息循环,Run()调用CMessageLoop::Run(),消息泵实际上是位于CMessageLoop::Run()内,我将在下一个章节介绍CMessageLoop的更多细节。

  CAboutDlg是CDialogImpl的派生类,它对应于ID IDD_ABOUTBOX资源,我在第一部分已经介绍过对话框,所以你应该能看懂CAboutDlg的代码。

  CWTLClockView是我们的程序的视图类,它的作用和MFC的视图类一样,没有标题栏,覆盖整个主窗口的客户区。CWTLClockView类有一个PreTranslateMessage()函数,也和MFC中的同名函数作用相同,还有一个WM_PAINT的消息响应函数。这两个函数都没有什么特别之处,只是我们会填写OnPaint()函数来显示时间。

  最后是我们的CMainFrame类,它有许多有趣的新东西,这是这个类的定义缩略版本:

class CMainFrame : public CFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>,
public CMessageFilter,
public CIdleHandler
{
 public:
  DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

  CWTLClockView m_view;

  virtual BOOL PreTranslateMessage(MSG* pMsg);
  virtual BOOL OnIdle();

  BEGIN_UPDATE_UI_MAP(CMainFrame)
  END_UPDATE_UI_MAP()

  BEGIN_MSG_MAP(CMainFrame)
  // ...
  CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
  CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
  END_MSG_MAP()
};

  CMessageFilter是一个嵌入类,它提供PreTranslateMessage()函数,CIdleHandler也是一个嵌入类,它提供了OnIdle()函数。 CMessageLoop, CIdleHandler 和 CUpdateUI三个类互相协同完成界面元素的状态更新(UI update),就像MFC中的ON_UPDATE_COMMAND_UI宏一样。

  CMainFrame::OnCreate()中创建了视图窗口并保存这个窗口的句柄,当主窗口改变大小时视图窗口的大小也会随之改变。OnCreate()函数还将CMainFrame对象添加到由CAppModule维持的消息过滤器队列和空闲处理队列,我将在稍后介绍这些。

LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/,
LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
 m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL, |WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);

 // register object for message filtering and idle updates
 CMessageLoop* pLoop = _Module.GetMessageLoop();
 pLoop->AddMessageFilter(this);
 pLoop->AddIdleHandler(this);

 return 0;
}

  m_hWndClient是CFrameWindowImpl对象的一个成员变量,当主窗口大小改变时此窗口的大小也将改变。

  在生成的CMainFrame中还添加了对File|New, File|Exit, 和 Help|About菜单消息的处理。我们的时钟程序不需要这些默认的菜单项,但是现在将它们留在代码中也没有害处。现在可以编译并运行向导生成的代码,不过这个程序确实没有什么用处。如果你感兴趣的话可以深入CMainFrame::CreateEx()函数的内部看看主窗口和它的资源是如何被加载和创建得。

  我们的下一步WTL之旅是CMessageLoop,它掌管消息泵和空闲处理。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章