學習WTL快半年了,但是實際工作中根本用不到。一是因爲公司不允許,二是有效的資源還比較少。通常情況下,自娛自樂的時候我還是選擇WTL來做界面。在這裏,我把平時學習實踐過程中的東西(思想)保留下來,供大家參考,也可以互相進步。
這篇文章可能會很長很長,但是劃分了4個模塊:
- 一.WTL的使用
- 二.WTL的結構
- 三.WTL的剖析
- 四.WTL的資源
- 五.WTL的項目(我自己寫的哦)
選擇WTL很大部分原因都是因爲對模板的迷戀,不知爲啥,C++的魅力盡然在模板!好,開始我們的征程吧。
一 WTL的使用
3.教程:
二 WTL的結構
WTL的類大致分爲:
1.框架窗口:CFrameWindowImpl、CMDIFrameWindowImpl
2.控件封裝: CButtonT、CListViewCtrl
3.GDI封裝: CDCT、CMenuT
4.特殊界面封裝:CSplitterWindow、CUpdateUI、CCustomDraw
5.實用工具類:CString、CRect
6.宏:BEGIN_MSG_MAP、END_MSG_MAP
先來看看令人頭疼的“宏”介紹吧:
1.在atlcrack.h中,BEGIN_MSG_MAP_EX和END_MSG_MAP_EX用來處理窗口消息的派發
1: // Note about message maps with cracked handlers:
2: // For ATL 3.0, a message map using cracked handlers MUST use BEGIN_MSG_MAP_EX.
3: // For ATL 7.0 or higher, you can use BEGIN_MSG_MAP for CWindowImpl/CDialogImpl derived classes,
4: // but must use BEGIN_MSG_MAP_EX for classes that don't derive from CWindowImpl/CDialogImpl.
5:
6: #define BEGIN_MSG_MAP_EX(theClass) /
7: public: /
8: /* 在UI類中,聲明一個m_bMsgHandled的變量,來判斷消息是否已處理,是否需要傳給基類*/ /
9: BOOL m_bMsgHandled; /
10: /* "handled" management for cracked handlers */ /
11: BOOL IsMsgHandled() const /
12: { /
13: return m_bMsgHandled; /
14: } /
15: void SetMsgHandled(BOOL bHandled) /
16: { /
17: m_bMsgHandled = bHandled; /
18: } /
19: BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) /
20: { /
21: BOOL bOldMsgHandled = m_bMsgHandled; /
22: BOOL bRet = _ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID); /
23: m_bMsgHandled = bOldMsgHandled; /
24: return bRet; /
25: } /
26: /* 帶下劃線開頭的函數,都是本類才調用的函數,一般做法爲聲明在private區域中*/ /
27: BOOL _ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID) /
28: { /
29: BOOL bHandled = TRUE; /
30: hWnd; /
31: uMsg; /
32: wParam; /
33: lParam; /
34: lResult; /
35: bHandled; /
36: switch(dwMsgMapID) /
37: { /
38: case 0:
39:
40:
1: #define END_MSG_MAP() /
2: break; /
3: default: /
4: ATLTRACE(ATL::atlTraceWindowing, 0, _T("Invalid message map ID (%i)/n"), dwMsgMapID); /
5: ATLASSERT(FALSE); /
6: break; /
7: } /
8: return FALSE; /
9: }
10:
11: #define END_MSG_MAP_EX END_MSG_MAP
看,一個switch結構就在_ProcessWindowMessage中就完成了。而其他的消息宏不過就是根據消息裏WPARAM、LPARAM的不同意義封裝不同的參數麼?來看幾個典型代表
1: ///////////////////////////////////////////////////////////////////////////////
2: // Standard Windows message macros
3:
4: // int OnCreate(LPCREATESTRUCT lpCreateStruct)
5: #define MSG_WM_CREATE(func) /
6: if (uMsg == WM_CREATE) /
7: { /
8: SetMsgHandled(TRUE); /
9: lResult = (LRESULT)func((LPCREATESTRUCT)lParam); /
10: if(IsMsgHandled()) /
11: return TRUE; /
12: }
13:
14: // BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
15: #define MSG_WM_INITDIALOG(func) /
16: if (uMsg == WM_INITDIALOG) /
17: { /
18: SetMsgHandled(TRUE); /
19: lResult = (LRESULT)func((HWND)wParam, lParam); /
20: if(IsMsgHandled()) /
21: return TRUE; /
22: }
是吧,沒錯!消息的Crack而已。
使用WTL::CString前定義_WTL_USER_CSTRING
使用SetMsgHandle(false)讓消息流入基類
ATL的CWindow類只有一個數據成員,沒有MFC窗口中的對象鏈.當一個CWindow類超出作用域時,它關聯的窗口並不銷燬掉。
ATL中的窗口過程是CWindowImpl.CDialogImpl實現普通對話框的窗口過程、CAxDialogImpl實現ActiveX對話框
三 WTL的剖析
四 WTL的資源
1.論壇: Yahoo
2.Article: Codeproject、Viksoe
五 WTL的項目