自定义 MFC 窗口/对话框可以是类模板实例化吗?

2022-01-12 00:00:00 templates c++ mfc

MFC 在创建对话框时使用了一堆特殊的宏,在我的快速测试中,我在尝试编译模板对话框类时遇到了奇怪的错误.这可能是一个很大的痛苦实现吗?

这是我尝试过的:

MyDlg.h

模板类 CMyDlg:公共 CDialog{typedef CDialog 超级;DECLARE_DYNAMIC(CMyDlg <W>)上市:CMyDlg (CWnd* pParent);//标准构造函数虚拟?CMyDlg();//对话数据枚举 { IDD = IDD_MYDLG };受保护:虚拟无效 DoDataExchange(CDataExchange* pDX);//DDX/DDV 支持DECLARE_MESSAGE_MAP()私人的:W *m_pWidget;//W 永远是一个 CDialog};IMPLEMENT_DYNAMIC(CMyDlg<W>, super) <--------------------模板<W类>CMyDlg::CMyDlg(CWnd* pParent): 超级(CMyDlg::IDD, pParent){m_pWidget = new W(this);}

我收到一大堆错误,但主要错误似乎是:

<块引用>

错误 C2955: 'CMyDlg' : 使用类模板需要模板参数列表

我尝试使用一些专门的宏模板版本,但没有多大帮助,其他错误发生了变化,但这个错误仍然存??在.请注意,我的代码都在一个文件中,因为 C++ 模板不像普通的那样喜欢 .h/.cpp.

我假设过去一定有人这样做过,可能创建了自定义版本的宏,但我无法通过搜索找到它,因为模板"还有其他含义.

解决方案

这是一个可行的解决方案,虽然丑陋...在扩展现有宏并修复模板后,我没有考虑重写为宏:

p>

//IMPLEMENT_DYNAMIC(CMyDlg,super)的模板启用扩展模板<W类>CRuntimeClass* PASCAL CMyDlg::_GetBaseClass(){ return RUNTIME_CLASS(super);}模板<W类>AFX_COMDAT const CRuntimeClass CMyDlg::CMyDlg= {"CMyDlg", sizeof(CMyDlg<W>), 0xFFFF, NULL,&CMyDlg<W>::_GetBaseClass, NULL, NULL };模板<W类>CRuntimeClass* PASCAL CMyDlg::GetThisClass() { return _RUNTIME_CLASS(CMyDlg);}模板<W类>CRuntimeClass* CMyDlg::GetRuntimeClass() const { return _RUNTIME_CLASS(CMyDlg);}

There's a bunch of special macros that MFC uses when creating dialogs, and in my quick tests I'm getting weird errors trying to compile a template dialog class. Is this likely to be a big pain to achieve?

Here's what I tried:

MyDlg.h

template <class W>
class CMyDlg : public CDialog
{
    typedef CDialog super;
    DECLARE_DYNAMIC(CMyDlg <W>)

public:
    CMyDlg (CWnd* pParent);   // standard constructor
    virtual ~CMyDlg ();

// Dialog Data
    enum { IDD = IDD_MYDLG };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

    DECLARE_MESSAGE_MAP()

private:
    W *m_pWidget; //W will always be a CDialog
};



IMPLEMENT_DYNAMIC(CMyDlg<W>, super) <-------------------

template <class W>
CMyDlg<W>::CMyDlg(CWnd* pParent)
    : super(CMyDlg::IDD, pParent)
{
  m_pWidget = new W(this);
}

I get a whole bunch of errors but main one appears to be:

error C2955: 'CMyDlg' : use of class template requires template argument list

I tried using some specialised template versions of macros but it doesn't help much, other errors change but this one remains. Note my code is all in one file, since C++ templates don't like .h/.cpp like normal.

I'm assuming someone must have done this in the past, possibly creating custom versions of macros, but I can't find it by searching, since 'template' has other meanings.

解决方案

Here's a working solution, though ugly... I didn't get round to rewriting as a macro after expanding the existing one and fixing for templates:

//Template-enabled expansion of IMPLEMENT_DYNAMIC(CMyDlg,super)
template <class W> CRuntimeClass* PASCAL CMyDlg<W>::_GetBaseClass(){ return RUNTIME_CLASS(super); }
template <class W> AFX_COMDAT const CRuntimeClass CMyDlg<W>::CMyDlg= {
        "CMyDlg", sizeof(CMyDlg<W>), 0xFFFF, NULL,&CMyDlg<W>::_GetBaseClass, NULL, NULL };
template <class W> CRuntimeClass* PASCAL CMyDlg<W>::GetThisClass()  { return _RUNTIME_CLASS(CMyDlg); }
template <class W> CRuntimeClass* CMyDlg<W>::GetRuntimeClass() const { return _RUNTIME_CLASS(CMyDlg); }

相关文章