随笔-156  评论-223  文章-30  trackbacks-0
   WTL是窗口模板库(Windows Library Template)的简称,是一套轻量级C++ GUI库,因为它使用了C++模板封装了窗口界面操作API和消息映射处理,它扩展了ATL中的UI窗口部分,并支持如下更多的功能特性:
    (1)   对话框和通用控件:包括对话框数据交换(DDX),子类化,控件消息通知与反射等
    (2)   工具栏和状态栏:包括工具条UI状态更新,多窗格状态条及UI状态更新等
    (3)   分隔窗口:包括窗格容器,嵌套分隔,特殊绘制等
    (4)   属性页和向导:包括属性表,普通属性页,向导属性页等
    (5)   GDI类等:包括GDI封装类,通用对话框等
    (6)   使用ActiveX控件:包括使用控件类,调用控件的方法,控件事件映射处理等
    (7)   高级对话框UI类:包括自绘和外观定制类,新控件类,控件UI状态更新,对话框数据验证DDV等
    (8)   支持拖放操作:包括拖放接口实现类,最近使用文件列表等
   综上所述,使用WTL几乎可以实现MFC所能实现的功能与界面,而且生成的执行文件体积更小,不需要动态链接库就可直接快速地执行。

   根据WIN32窗口原理,当事件发生的时候,一般由父窗口接收其子窗口或控件的通知或命令消息,在这里父窗口是消息接收者,子窗口或控件是消息发送者,那么谁是消息处理者呢?实际上由谁来处理消息只是代码上的逻辑,既可以在父窗口的窗口过程回调内处理,也可以在子窗口或控件的窗口过程回调内处理,在哪处理更方便合理就在哪处理,如果是在子窗口或控件窗口过程回调内处理,那么就需要作额外的处理了,也就是在父窗口中将消息反射给发送者,进而再由发送者处理。下面以父窗口为打开文件对话框,双击它的列表视图控件为例,给出运用上面(1)中的控件消息通知与反射来处理NM_DBLCLK消息的两种实现方式。

   继承方式:由控件处理消息
   从CWindowImpl模板基类派生一个子窗口或控件子类即listview子类,添加消息映射项和消息处理函数,消息映射项用REFLECTED_NOTIFY_XXX或REFLECTED_COMMAND_XXX系列反射宏实现,具体使用哪个宏,决定于是否通知或命令消息,及消息对应的ID和通知码。
1class CFileListViewCtrl : public CWindowImpl<CFileListViewCtrl, CListViewCtrl>
2{
3 protected:
4      BEGIN_MSG_MAP(CFileListViewCtrl)
5          REFLECTED_NOTIFY_CODE_HANDLER_EX(NM_DBLCLK,OnListViewDblclk)   //反射通知消息处理宏
6          CHAIN_MSG_MAP(CListViewCtrl)
7     END_MSG_MAP()
8    LRESULT OnListViewDblclk(NMHDR* pNMHDR);   //消息响应处理函数
9}
;
   
   在父窗口类消息映射链中最后添加反射通知宏REFLECT_NOTIFICATIONS()项。                                           
 1class COpenFileDlg : public CDialogImpl<COpenFileDlg>  ,  public CWinDataExchange<COpenFileDlg>
 2{
 3public:
 4   COpenFileDlg();
 5   ~COpenFileDlg();
 6  enum  { IDD = IDD_OPEN_FILE_DLG };
 7
 8protected:
 9     BEGIN_MSG_MAP(COpenFileDlg)
10            MESSAGE_HANDLER(WM_INITDIALOG,OnInitDialog) 
11            REFLECT_NOTIFICATIONS()      //消息反射通知宏
12     END_MSG_MAP()
13    
14     BEGIN_DDX_MAP(COpenFileDlg)
15           DDX_CONTROL(IDC_LIST_FILE,m_list_File)
16     END_DDX_MAP()
17
18     LRESULT OnInitDialog(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandle);
19     
20private:
21    CFileListViewCtrl  m_list_File;    //使用派生类实例作为成员变量
22}
;

 成员方式:由父窗口处理消息 
   直接使用ATL中的包含窗口模板类CContainedWindowT,参数为子控件的类名即listviewctrl,实例化为父窗口类的一个成员变量,在父窗口类消息映射链中添加ALT_MSG_MAP宏来实现消息分派,其参数为分派ID,这个ID为成员变量初始化时指定的常量;添加反射通知宏REFLECT_NOTIFICATIONS(),注意ALT_MSG_MAP宏必须在反射通知宏REFLECT_NOTIFICATIONS之后。  
 1class COpenFileDlg : public CDialogImpl<COpenFileDlg> ,  public CWinDataExchange<COpenFileDlg>
 2{
 3    public:
 4        COpenFileDlg();
 5       ~COpenFileDlg();
 6  enum  { IDD = IDD_OPEN_FILE_DLG };
 7 
 8  protected:
 9     BEGIN_MSG_MAP(COpenFileDlg)
10          MESSAGE_HANDLER(WM_INITDIALOG,OnInitDialog) 
11          REFLECT_NOTIFICATIONS()           //  消息反射通知宏
12          ALT_MSG_MAP(1)                             //  消息分派宏
13          REFLECTED_NOTIFY_CODE_HANDLER_EX(NM_DBLCLK,OnListViewDblclk)     //  反射通知消息处理宏
14     END_MSG_MAP()
15
16     BEGIN_DDX_MAP(COpenFileDlg)
17           DDX_CONTROL(IDC_LIST_FILE,m_list_File)
18     END_DDX_MAP()
19
20     LRESULT OnInitDialog(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandle);
21     LRESULT OnListViewDblclk(NMHDR* pNMHDR);            //消息响应处理函数
22  private:
23    CContainedWindowT<CListViewCtrl>   m_list_File;    //  实例化包含窗口模板类作为成员变量
24 }
;

   在父窗口内需要初始化m_list_File以指定分派ID号。                                                               
1COpenFileDlg:: COpenFileDlg():
2m_list_File(this,1)     // 指定消息分派ID为1
3{  
4}
posted on 2010-06-14 17:50 春秋十二月 阅读(5962) 评论(0)  编辑 收藏 引用 所属分类: C/C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理