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和通知碼。
1
class 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()項。
1
class 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
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
20
private:
21
CFileListViewCtrl m_list_File; //使用派生類實例作為成員變量
22
};
成員方式:由父窗口處理消息
直接使用ATL中的包含窗口模板類CContainedWindowT,參數為子控件的類名即listviewctrl,實例化為父窗口類的一個成員變量,在父窗口類消息映射鏈中添加ALT_MSG_MAP宏來實現消息分派,其參數為分派ID,這個ID為成員變量初始化時指定的常量;添加反射通知宏REFLECT_NOTIFICATIONS(),注意ALT_MSG_MAP宏必須在反射通知宏REFLECT_NOTIFICATIONS之后。
1
class 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號。
1
COpenFileDlg:: COpenFileDlg():2
m_list_File(this,1) // 指定消息分派ID為1
3

{
4
}
posted on 2010-06-14 17:50
春秋十二月 閱讀(6028)
評論(0) 編輯 收藏 引用 所屬分類:
C/C++