如何使用ATL / WTL制作自己的原生(可复制)控件?

时间:2012-08-07 06:18:22

标签: c++ winapi visual-c++ atl wtl

当您使用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类创建一致的控件类的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

您在\Include\atlctrlx.h

中的WTL中有一些自定义控件
///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CBitmapButtonImpl<T, TBase, TWinTraits>
// CBitmapButton
// CCheckListViewCtrlImpl<T, TBase, TWinTraits>
// CCheckListViewCtrl
// CHyperLinkImpl<T, TBase, TWinTraits>
// CHyperLink

除此之外,您还可以在http://viksoe.dk找到正确的自定义WTL控件。

控件的“可复制性”基于以下事实:您可以通过句柄HWND使用标准控件,并且您可以轻松地复制,附加,分离此句柄,并且有效时整体控制很好。包装器类很薄,只有HWND成员变量。

另一方面,

自定义控件具有其他信息,您无法轻松复制它们。您仍然可以使用控件动态分配/释放此附加信息,您将实现其他控件特定窗口消息和通知,然后您可以创建一个瘦包装类,将方法转换为消息,将它们发送到实际控件,反过来会处理它们,尤其是通过将带有参数的消息转换回实际方法。这让你可以复制瘦包装类,但控件本身更复杂,更麻烦(你通常不需要那样)。