2012-08-07 30 views
1

當你使用WTL,您可以自由複製表示內置對象控件:如何用ATL/WTL製作自己的原生類(可複製)控件?

// Notice that CWindow is passed by _copy_, because it only wraps the HWND 
int OnNotifyFormat(CWindow wndFrom, int nCommand) { ... } 

現在,如果我想我自己控制,它很容易地說:

template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits> 
struct CMyControlImpl: public CWindowImpl<T, TBase, TWinTraits> 
{ 
    std::vector<int> internal_info; 

    BEGIN_MSG_MAP_EX(...) 
     ... 
    END_MSG_MAP() 
}; 

struct CMyControl : public CMyControlImpl<CMyControl> 
{ 
    DECLARE_WND_CLASS_EX(TEXT("MyControl"), 0, COLOR_WINDOW) 
}; 

但現在的問題是,我不能簡單地說:

void OnFooHappened(CMyControl control) 
{ 
} 

因爲CMyControl不僅僅是一個句柄 - 它包含數據本身!

對於這種複製行爲,使用內置的ATL/WTL類創建一個控制類一致的的正確方法是什麼?

回答

3

您在WTL有幾個自定義控件在那裏,在\Include\atlctrlx.h

/////////////////////////////////////////////////////////////////////////////// 
// Classes in this file: 
// 
// CBitmapButtonImpl<T, TBase, TWinTraits> 
// CBitmapButton 
// CCheckListViewCtrlImpl<T, TBase, TWinTraits> 
// CCheckListViewCtrl 
// CHyperLinkImpl<T, TBase, TWinTraits> 
// CHyperLink 

除此之外,你會發現自定義的WTL控制在http://viksoe.dk做出正確的方式。

控件的「可複製性」基於這樣一個事實,即標準控件通過句柄HWND可用,並且您可以輕鬆地複製,附加,分離等句柄,並且當它有效時,整個控件是好。包裝類很薄,只有其中的HWND成員變量。

另一方面,如您注意到的自定義控件有附加信息,並且無法輕鬆複製它們。您仍然可以通過控件動態分配/釋放此附加信息,您將實現附加控件特定的窗口消息和通知,然後可以創建一個瘦方法包裝器類,將方法轉換爲消息,並將它們發送給實際控件,反過來將處理他們,尤其是,通過將帶參數的消息轉換回真正的方法。這可以讓你複製薄包裝類,但是控制本身更復雜和麻煩(通常你不需要這樣做)。

+0

哇,有趣的是,我沒有注意到。所以「自定義」內置控件不會以這種方式工作?! (例如,我沒有看到'CBitmapButton'的構造函數接受'HWND';它似乎持有所有的信息本身。) – Mehrdad 2012-08-07 06:23:34

+0

是的,WTL控件持有類的信息。但它們相對簡單。正如我所說,可以按照你想要的方式來做,而且這不是最簡單的方法。如果您從標準控件派生自定義控件,則可能還會發現創建基本窗口/控件(例如使用對話框模板)很有用,然後在您的代碼中通過繼承現有原始控件窗口來初始化您的自定義控件。這是使用資源中的模板進行控制的一種很酷的方式。 – 2012-08-07 09:04:58