问题描述
假设您想拥有一个CContainedWindow
,但是您希望从一开始就工作-即,您希望它拥有自己的新消息映射,而没有任何上级或子类。因此,换句话说,您希望在单个类声明中拥有所有处理程序方法的便利,但是您不必处理预定义窗口类的任何特质。有没有一种优雅的方法可以做到这一点?我唯一想到的就是这样的事情(它是外部CWindowImpl
派生的类中嵌套CWindowImpl
派生的类):
class COuterWindow :
public CWindowImpl<COuterWindow>
{
public:
COuterWindow() : m_wndInner(this)
{
}
BEGIN_MSG_MAP(COuterWindow)
// ...
END_MSG_MAP()
private:
class CInnerWindow :
public CWindowImpl<CInnerWindow>
{
public:
CInnerWindow(COuterWindow* pwndOuter) : m_pwndOuter(pwndOuter)
{
}
private:
COuterWindow* m_pwndOuter;
BEGIN_MSG_MAP(CInnerWindow)
MESSAGE_HANDLER(WM_PAINT,m_pwndOuter->OnInnerPaint)
// ...
END_MSG_MAP()
};
LRESULT OnInnerPaint(UINT,WParaM,LParaM,BOOL&);
CInnerWindow m_wndInner;
};
这行得通,但是我想知道ATL中是否有我正在忽略的东西(例如消息映射宏之类的东西)可以完成此任务或使其变得整洁或允许使用单个消息映射。感谢您的指导。
解决方法
根据Igor的评论,我认为您可以执行以下操作来实现某种“空白” CContainedWindow
:
class CContainedWindowBlank : public CWindowImpl<CContainedWindowBlank>,public CDynamicChain
{
public:
CContainedWindowBlank(CMessageMap* pObject,DWORD dwMsgMapId = 0)
{
SetChainEntry(1,pObject,dwMsgMapId);
}
BEGIN_MSG_MAP()
CHAIN_MSG_MAP_DYNAMIC(1)
END_MSG_MAP()
};
尽管我不确定如何将其转换为接受CWinTraits
之类的模板。如果有人知道该怎么做,我将不胜感激。谢谢。
实际上,我似乎已经实现了模板化版本,尽管我不确定它为什么能工作或是否可以简化:
template <class TBase = CWindow,class TWinTraits = CControlWinTraits>
class CContainedWindowBlankT : public CWindowImpl<CContainedWindowBlankT<TBase,TWinTraits>,TBase,public CDynamicChain
{
public:
CContainedWindowBlankT(CMessageMap* pObject,dwMsgMapId);
}
BEGIN_MSG_MAP()
CHAIN_MSG_MAP_DYNAMIC(1)
END_MSG_MAP()
};