Using MFC Macros with Templates

Is it possible to get and use a C ++ template template from an MFC class such as CDialog. I tried, but the implementation crashes with the MFC macros used to route messages. For instance:

template<class TYPE, class ARG_TYPE> class CMyDialogT : public CDialog { public: CMyDialogT(CMyContainerT<TYPE,ARG_TYPE> *pData,CWnd* pParent = NULL); CMyContainerT<TYPE,ARG_TYPE> *m_pData; // Generated message map functions //{{AFX_MSG(CMyDialogT) afx_msg void OnUpdateMyControl(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; template<class TYPE, class ARG_TYPE> CMyDialogT<TYPE,ARG_TYPE>::CMyDialogT(CMyContainerT<TYPE,ARG_TYPE> *pData,CWnd* pParent) : CDialog(CMyDialogT::IDD, pParent) { m_pData = pData; } BEGIN_MESSAGE_MAP(CGlobalEditT<TYPE,ARG_TYPE>, CDialog) //{{AFX_MSG_MAP(CGlobalEditT) ON_EN_UPDATE(IDC_MY_CONTROL, OnUpdateMyControl) //}}AFX_MSG_MAP END_MESSAGE_MAP() 

The above does not compile with a sequence of messages starting as follows:

  warning C4002: too many actual parameters for macro 'BEGIN_MESSAGE_MAP' error C2653: 'TYPE' : is not a class or namespace name 

Is there any workaround for this other than manually deploying MFC macros? I cannot use template specialization at the moment, as indicated in a similar question here , since I do not know all the possible values โ€‹โ€‹of TYPE and ARG_TYPE.

Another way to look at the question is: "I can embed a template class in another class without specializing in the template or creating a class-class of the class." I also can not answer this question, I suspect that the answer may be negative.

Change Partial Solution for One Type Templates on MSDN here

+4
source share
2 answers

A more general problem with macros and templates is that macros are Stupid (tm).

The preprocessor does not care about <> or [] as grouping operators, so when analyzing a macro call:

 BEGIN_MESSAGE_MAP(CGlobalEditT<TYPE,ARG_TYPE>, CDialog) 

It means:

  • Macro Name: BEGIN_MESSAGE_MAP
  • Argument 1: CGlobalEditT<TYPE
  • Argument 2: ARG_TYPE>
  • Argument 3: CDialog

He then looks at the definition of BEGIN_MESSAGE_MAP , realizes that it is a macro with two arguments and complains low.

There are two types of situations in which this can occur:

  • inside a class or function
  • to actually declare a template class or template function

In the latter case, you are more or less screwed up if no special macros are specified.

In the first case, you have two solutions:

  • Using typedef to provide a synonym for CGlobalEditT<TYPE,ARG_TYPE> , which does not contain a comma
  • Using braces around CGlobalEditT<TYPE,ARG_TYPE> to "isolate" a comma

When brackets work, this is great, but this is not always the case.

When they do not, typedef often a suitable alternative.

In any case, this is what you need to remember about macros.

+4
source

You should use BEGIN_TEMPLATE_MESSAGE_MAP instead of BEGIN_MESSAGE_MAP.

+5
source

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


All Articles