您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
MFC程序员的WTL开发指南之ATL界面类
[文章信息]
作者:lithe
时间:2005-01-17
出处:CSDN BLOG
责任编辑:方舟
[文章导读]
本文给出ATL的背景知识,包括编写ATL代码必须知道的基本知识,快速的解释一些ATL模板类和基本窗口类。
advertisement
热点推荐
· 迷你迅雷给IE下载加足马力
· 《大话李白》主题曲 Flash
· Windows操作系统小技巧荟萃(上)
· 新浪UC2005使用技巧四则
· Google 2秒钟搜索100G硬盘
[正文]

上一页  1 2 3 4  下一页

  ATL 窗口类

  好了,关于ATL的背景知识已经讲的构多了,到了该正式讲ATL的时候了。ATL在设计时接口定义和实现是严格区分开的,这在窗口类的设计中是最明显的,这一点类似于COM,COM的接口定义和实现是完全分开的(或者可能有多个实现)。

  ATL有一个专门为窗口设计的接口,可以做全部的窗口操作,这就是CWindow。它实际上就是对HWND操作的包装类,对几乎所有以HWND句柄为第一个参数的窗口API的进行了封装,例如:SetWindowText() 和 DestroyWindow()。CWindow类有一个公有成员m_hWnd,使你可以直接对窗口的句柄操作,CWindow还有一个操作符HWND,你可以讲CWindow对象传递给以HWND为参数的函数,但这与CWnd::GetSafeHwnd()(译者加:MFC的方法)没有任何等同之处。

  CWindow 与 MFC 的CWnd类有很大的不同,创建一个CWindow对象占用很少的资源,因为只有一个数据成员,没有MFC窗口中的对象链,MFC内部维持这一个对象链,此对象链将HWND映射到CWnd对象。还有一点与MFC的CWnd类不同的是当一个CWindow对象超出了作用域,它关联的窗口并不被销毁掉,这意味着你并不需要随时记得分离你所创建的临时CWindow对象。

  在ATL类中对窗口过程的实现是CWindowImpl。CWindowImpl 含有所有窗口实现代码,例如:窗口类的注册,窗口的子类化,消息映射以及基本的WindowProc()函数,可以看出这与MFC的设计有很大的不同,MFC将所有的代码都放在一个CWnd类中。

  还有两个独立的类包含对话框的实现,它们分别是CDialogImpl 和 CAxDialogImpl,CDialogImpl 用于实现普通的对话框而CAxDialogImpl实现含有ActiveX控件的对话框。

  定义一个窗口的实现

  任何非对话框窗口都是从CWindowImpl 派生的,你的新类需要包含三件事情:

  1、一个窗口类的定义
  2、一个消息映射链
  3、窗口使用的默认窗口类型,称为window traits
   
  窗口类的定义通过DECLARE_WND_CLASS宏或DECLARE_WND_CLASS_EX宏来实现。这辆个宏定义了一个CWndClassInfo结构,这个结构封装了WNDCLASSEX结构。DECLARE_WND_CLASS宏让你指定窗口类的类名,其他参数使用默认设置,而DECLARE_WND_CLASS_EX宏还允许你指定窗口类的类型和窗口的背景颜色,你也可以用NULL作为类名,ATL会自动为你生成一个类名。

  让我们开始定义一个新类,在后面的章节我会逐步的完成这个类的定义。

class CMyWindow : public CWindowImpl<CMyWindow>
{
 public:
  DECLARE_WND_CLASS(_T("My Window Class"))
};

  接下来是消息映射链,ATL的消息映射链比MFC的简单的多,ATL的消息映射链被展开为switch语句,switch语句正确的消息处理者并调用相应的函数。使用消息映射链的宏是BEGIN_MSG_MAP 和 END_MSG_MAP,让我们为我们的窗口添加一个空的消息映射链。

class CMyWindow : public CWindowImpl<CMyWindow>
{
 public:
  DECLARE_WND_CLASS(_T("My Window Class"))
  BEGIN_MSG_MAP(CMyWindow)
  END_MSG_MAP()
};

  我将在下一节展开讲如何如何添加消息处理到消息映射链。最后,我们需要为我们的窗口类定义窗口的特征,窗口的特征就是窗口类型和扩展窗口类型的联合体,用于创建窗口时指定窗口的类型。窗口类型被指定为参数模板,所以窗口的调用者不需要为指定窗口的正确类型而烦心,下面是是同ATL类CWinTraits定义窗口类型的例子:

typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,WS_EX_APPWINDOW> CMyWindowTraits;

class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CMyWindowTraits>
{
 public:
  DECLARE_WND_CLASS(_T("My Window Class"))

  BEGIN_MSG_MAP(CMyWindow)
  END_MSG_MAP()
};

  调用者可以重载CMyWindowTraits的类型定义,但是一般情况下这是没有必要的,ATL提供了几个预先定义的特殊的类型,其中之一就是CFrameWinTraits,一个非常棒的框架窗口:

typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits;

  填写消息映射链

  ATL的消息映射链是对开发者不太友好的部分,也是WTL对其改进最大的部分。类向导至少可以让你添加消息响应,然而ATL没有消息相关的宏和象MFC那样的参数自动展开功能,在ATL中只有三种类型的消息处理,一个是WM_NOTIFY,一个是WM_COMMAND,第三类是其他窗口消息,让我们开始为我们的窗口添加WM_CLOSE 和 WM_DESTROY的消息相应函数。

class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CFrameWinTraits>
{
 public:
  DECLARE_WND_CLASS(_T("My Window Class"))

  BEGIN_MSG_MAP(CMyWindow)
  MESSAGE_HANDLER(WM_CLOSE, OnClose)
  MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  END_MSG_MAP()

  LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
   DestroyWindow();
   return 0;
  }

  LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
   PostQuitMessage(0);
   return 0;
  }
};

  你可能注意到消息响应函数的到的是原始的WPARAM 和 LPARAM值,你需要自己将其展开为相应的消息所需要的参数。还有第四个参数bHandled,这个参数在消息相应函数调用被ATL设置为TRUE,如果在你的消息响应处理完之后需要ATL调用默认的WindowProc()处理该消息,你可以讲bHandled设置为FALSE。这与MFC不同,MFC是显示的调用基类的响应函数来实现的默认的消息处理的。

  让我们也添加一个对WM_COMMAND消息的处理,假设我们的窗口有一个ID为IDC_ABOUT的About菜单:

class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CFrameWinTraits>
{
 public:
  DECLARE_WND_CLASS(_T("My Window Class"))
  BEGIN_MSG_MAP(CMyWindow)
  MESSAGE_HANDLER(WM_CLOSE, OnClose)
  MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  COMMAND_ID_HANDLER(IDC_ABOUT, OnAbout)
  END_MSG_MAP()

  LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
   DestroyWindow();
   return 0;
  }

  LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
   PostQuitMessage(0);
   return 0;
  }

  LRESULT OnAbout(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  {
   MessageBox ( _T("Sample ATL window"), _T("About MyWindow") );
   return 0;
  }
};

  需要注意得是COMMAND_HANDLER宏已经将消息的参数展开了,同样,NOTIFY_HANDLER宏也将WM_NOTIFY消息的参数展开了。


上一页  1 2 3 4  下一页

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • ATL布幔下的秘密之窗口类的秘密
  • ATL布幔下的秘密之底层技术和汇编
  • Windows 中不规则窗体的编程实现
  • ATL布幔下的秘密之模板技术
  • ATL布幔下的秘密之虚函数背后的东西
  • 寄出钱易趣说没收到 网上购物“优惠”遭质疑
  • 内地C2C网站集体对接海外 扩展两岸三地市场
  • 企业信息化时代的新兴职业:客户关系管理师
  • 诺基亚光辉岂止区区15年 CEO奥利拉不信邪
  • CN域名注册价格大跳水 将与.COM域名持平
  • 中国将制定首个国家信息化战略 年底前发布
  • 04年中国企业十大新闻揭晓 联想收购列第一
  • 跨国公司在华兴独资浪潮 欧盟与日本打头阵
  • Advertisement