WTL實踐經驗總結(不斷更新)

學習WTL快半年了,但是實際工作中根本用不到。一是因爲公司不允許,二是有效的資源還比較少。通常情況下,自娛自樂的時候我還是選擇WTL來做界面。在這裏,我把平時學習實踐過程中的東西(思想)保留下來,供大家參考,也可以互相進步。

這篇文章可能會很長很長,但是劃分了4個模塊:

  1. 一.WTL的使用
  2. 二.WTL的結構
  3. 三.WTL的剖析
  4. 四.WTL的資源
  5. 五.WTL的項目(我自己寫的哦)

選擇WTL很大部分原因都是因爲對模板的迷戀,不知爲啥,C++的魅力盡然在模板!好,開始我們的征程吧。

 

一 WTL的使用

1.安裝:網上已經很多這樣的文章了,看這裏這裏

2.幫助插件:VisualFCWTLHelper

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: CodeprojectViksoe

 

五 WTL的項目

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章