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++