ATL-style 模板。
#include <iostream>
using namespace std;
template <class T>
class B1
{
public:
void SayHi()
{
T *pT = static_cast<T*>(this);
pT->PrintClassName();
}
protected:
void PrintClassName()
{
cout << "This is B1" << endl;
}
};
class D1 : public B1<D1>
{
//No overridden functions at all
};
class D2 : public B1<D2>
{
public:
void PrintClassName()
{
cout << "This is D2" << endl;
}
};
int _tmain(int argc, _TCHAR *argv[])
{
D1 d1;
D2 d2;
d1.SayHi(); //This is B1
d2.SayHi(); //This is D2
getchar();
return 0;
}
ATL 窗口類
ATL在設計時接口定義和實現是嚴格區分開的,這在窗口類的設計中是最明顯的,這一點類似於COM,COM的接口定義和實現是完全分開的(或者可能有多個實現)。
ATL有一個專門爲窗口設計的接口,可以做全部的窗口操作,這就是CWindow。它實際上就是對HWND操作的包裝類,
對幾乎所有以HWND句柄爲第一個參數的窗口API的進行了封裝,例如:SetWindowText() 和 DestroyWindow()。CWindow類有一個公有成員m_hWnd,使你可以直接對窗口的句柄操作,CWindow還有一個操作符HWND,你可以講CWindow對象傳遞給以HWND爲參數的函數,但這與CWnd::GetSafeHwnd()沒有任何等同之處。
CWindow 與 MFC 的CWnd類有很大的不同,創建一個CWindow對象佔用很少的資源,因爲只有一個數據成員,沒有MFC窗口中的對象鏈,MFC內部維持這一個對象鏈,此對象鏈將HWND映射到CWnd對象。還有一點與MFC的CWnd類不同的是當一個CWindow對象超出了作用域,它關聯的窗口並不被銷燬掉,這意味着你並不需要隨時記得分離你所創建的臨時CWindow對象。
在ATL類中對窗口過程的實現是CWindowImpl。CWindowImpl 含有所有窗口實現代碼,例如:窗口類的註冊,窗口的子類化,消息映射以及基本的WindowProc()函數,可以看出這與MFC的設計有很大的不同,MFC將所有的代碼都放在一個CWnd類中。
還有兩個獨立的類包含對話框的實現,它們分別是CDialogImpl 和 CAxDialogImpl,CDialogImpl 用於實現普通的對話框而CAxDialogImpl實現含有ActiveX控件的對話框。
定義一個窗口的實現
任何非對話框窗口都是從CWindowImpl 派生的,你的新類需要包含三件事情:
1、一個窗口類的定義
2、一個消息映射鏈
3、窗口使用的默認窗口類型,稱爲window traits
窗口類的定義通過DECLARE_WND_CLASS宏或DECLARE_WND_CLASS_EX宏來實現。這輛個宏定義了一個CWndClassInfo結構,這個結構封裝了WNDCLASSEX結構。DECLARE_WND_CLASS宏讓你指定窗口類的類名,其他參數使用默認設置,而DECLARE_WND_CLASS_EX宏還允許你指定窗口類的類型和窗口的背景顏色,你也可以用NULL作爲類名,ATL會自動爲你生成一個類名。
讓我們開始定義一個新類,在後面的章節我會逐步的完成這個類的定義。