Question

When you're using WTL, you can freely copy controls that represent built-in objects:

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

Now, if I want to make my own controls, it's easy enough to say:

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)
};

but now the problem is that I can't simply say:

void OnFooHappened(CMyControl control)
{
}

because CMyControl is more than just a handle -- it contains the data itself!

What is the correct way to make a control class that is consistent with the built-in ATL/WTL classes, with respect to this copy behavior?

Was it helpful?

Solution

You have a few custom controls right there in WTL, in \Include\atlctrlx.h:

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

Apart from this, you will find custom WTL controls made right way at http://viksoe.dk.

The "copiability" of the controls is based on the fact that standard controls are available to you via handle HWND, and you can easily copy, attach, detach etc. this handle, and while it is valid the whole control is good. Wrapper classes are thin and only have the HWND member variable in them.

Custom controls on the other hand as you noticed have additional information, and you cannot copy them as easily. You can still have this additional information allocated/released dynamically with the control, you will implement the additional control specific window messages and notifications, and then you can create a thin wrapper class that converts methods into messages, sends them to the real control, which in turn will handle them, esp. by converting messages with parameters back to real methods. This let you copy thin wrapper class, but the control itself is way more complicated and cumbersome (you don't normally need to have it that way).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top