Can a custom MFC window / dialog be an instance of a class template?

There are a bunch of special macros that MFC uses when creating dialogs, and in my quick tests I get weird errors trying to compile the template dialog class. Perhaps this will be a big pain?

Here is 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 the main one looks like:

error C2955: 'CMyDlg': using class template requires template argument list

I tried to use some specialized template versions of macros, but it doesn’t help much, other errors change, but this one remains. Please note that my code is in a single file, since C ++ templates do not like .h / .cpp, as usual.

I assume that someone should have done this in the past, perhaps by creating custom versions of macros, but I cannot find it by searching, since the "template" has different meanings.

+1
source share
3 answers

Here's a working solution, albeit ugly ... I did not rewrite it as a macro after expanding the existing one and fixing it for the 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); } 
+2
source

You may have other problems, but one thing should be your help super . This is a Java thing, not C ++. Instead of super you need to use CDialog .

After viewing IMPLEMENT_DYNAMIC , the macro definition is incompatible with templates; it does not use the template <class T> syntax before function definitions. What you need to do is determine the specialized specializations of your template, and then use the macro on them. So you can do this:

 class MyDlgA : public CMyDlg<A> { }; IMPLEMENT_DYNAMIC(MyDlgA, CDialog); 

And then do it for all specialization desires. If this is not possible, look at the macro and make your own templatized version.

Edit: Following my comment, you can make a macro like this:

 #define INSTANTIATE_DLG_TEMPLATE(T) \ class MyDlg##T : public CMyDlg<T> \ { \ }; \ \ IMPLEMENT_DYNAMIC(MyDlg##T, CDialog); 

And then just use it wherever you usually defined the specialization of the template in the header file using typedef.

+3
source

I did not do this for dialogue, only for some user controls, but I see no reason why this will not work.
I know that there is at least a version of the template for defining message cards, BEGIN_TEMPLATE_MESSAGE_MAP. Check out http://msdn.microsoft.com/en-us/library/aa991537(VS.80).aspx

+1
source

Source: https://habr.com/ru/post/1389290/


All Articles