How to: Create a Message Map for a Template 클래스

메시지 매핑 mfc에서 C++ 개체 인스턴스에 적절 한 Windows 메시지를 보낼 수 있는 효율적인 방법을 제공 합니다.MFC 메시지 맵 대상 몇 가지 응용 프로그램 클래스, 문서 및 뷰 클래스, 컨트롤 클래스 등 포함 됩니다.

기존의 MFC 메시지 맵을 사용 하 여 선언는 BEGIN_MESSAGE_MAP 매크로 시작 메시지 맵의 각 메시지 처리기 클래스 메서드에 대 한 매크로 항목을 선언 합니다, 마지막으로 END_MESSAGE_MAP 매크로 끝 메시지 맵 선언 합니다.

한 제한에는 BEGIN_MESSAGE_MAP 매크로 템플릿 인수를 포함 하는 클래스와 함께에서 사용 하는 경우 발생 합니다.템플릿 클래스를 사용 하면이 매크로 매크로 확장 중 대 한 템플릿 매개 변수가 없습니다 때문에 컴파일 타임 오류가 발생 합니다.BEGIN_TEMPLATE_MESSAGE_MAP 매크로 매핑합니다 자신의 메시지를 선언 하는 단일 템플릿 인수를 포함 하는 클래스를 허용 하도록 설계 되었습니다.

예제

예제를 고려 어디 MFC CListBox 입니다 클래스를 확장 하는 외부 데이터 원본과 동기화를 제공 합니다.가상의 CSyncListBox 클래스는 다음과 같이 선언 된:

// Extends the CListBox class to provide synchronization with 
// an external data source
template <typename CollectionT> 
class CSyncListBox : public CListBox
{
public:
   CSyncListBox();
   virtual ~CSyncListBox();

   afx_msg void OnPaint();
   afx_msg void OnDestroy();
   afx_msg LRESULT OnSynchronize(WPARAM wParam, LPARAM lParam);
   DECLARE_MESSAGE_MAP()

   // ...additional functionality as needed
};

CSyncListBox 클래스와 동기화 되는 데이터 원본을 설명 하는 단일 형식 템플릿 기반입니다.또한 클래스의 메시지 맵을에 참여 해야 하는 세 가지 메서드 선언: OnPaint, OnDestroy, 및 OnSynchronize.OnSynchronize 메서드는 다음과 같이 구현 됩니다.

template <class CollectionT> 
LRESULT CSyncListBox<CollectionT>::OnSynchronize(WPARAM, LPARAM lParam)
{
   CollectionT* pCollection = (CollectionT*)(lParam);

   ResetContent();

   if(pCollection != NULL)
   {
      INT nCount = (INT)pCollection->GetCount();
      for(INT n = 0; n < nCount; n++)
      {
         CString s = StringizeElement(pCollection, n);
         AddString(s);
      }
   }

   return 0L;
}

위의 구현할 수 있습니다는 CSyncListBox 클래스를 구현 하는 모든 클래스 형식에서 특수화는 GetCount 메서드 같은 CArray, CList, 및 CMap.StringizeElement 함수는 다음 프로토타입 템플릿 함수입니다.

// Template function for converting an element within a collection
// to a CString object
template<typename CollectionT>
CString StringizeElement(CollectionT* pCollection, INT iIndex);

일반적으로이 클래스의 메시지 맵을 정의 됩니다.

BEGIN_MESSAGE_MAP(CSyncListBox, CListBox)

ON_WM_PAINT()

ON_WM_DESTROY()

ON_MESSAGE(LBN_SYNCHRONIZE, OnSynchronize)

END_MESSAGE_MAP()

위치 LBN_SYNCHRONIZE 같은 응용 프로그램에서 정의한 사용자 지정 메시지입니다.

#define LBN_SYNCHRONIZE (WM_USER + 1)

위의 매크로 맵 컴파일되지 않으며 때문에 템플릿 지정에는 CSyncListBox 클래스 됩니다 누락 된 매크로 확장 중.BEGIN_TEMPLATE_MESSAGE_MAP 매크로 해결이 확장 된 매크로 맵에 지정 된 템플릿 매개 변수를 통합 하 여.이 클래스의 메시지 맵을 다음과 같이 됩니다.

BEGIN_TEMPLATE_MESSAGE_MAP(CSyncListBox, CollectionT, CListBox)
   ON_WM_PAINT()
   ON_WM_DESTROY()
   ON_MESSAGE(LBN_SYNCHRONIZE, OnSynchronize)
END_MESSAGE_MAP()

다음 예제를 사용 하는 방법을 보여 줍니다 있는 CSyncListBox 클래스를 사용 하는 CStringList 개체:

void CSyncListBox_Test(CWnd* pParentWnd)
{
   CSyncListBox<CStringList> ctlStringLB;
   ctlStringLB.Create(WS_CHILD | WS_VISIBLE | LBS_STANDARD | WS_HSCROLL, 
      CRect(10,10,200,200), pParentWnd, IDC_MYSYNCLISTBOX);

   // Create a CStringList object and add a few strings
   CStringList stringList;
   stringList.AddTail(_T("A"));
   stringList.AddTail(_T("B"));
   stringList.AddTail(_T("C"));

   // Send a message to the list box control to synchronize its
   // contents with the string list
   ctlStringLB.SendMessage(LBN_SYNCHRONIZE, 0, (LPARAM)&stringList);

   // Verify the contents of the list box by printing out its contents
   INT nCount = ctlStringLB.GetCount();
   for( INT n = 0; n < nCount; n++ )
   {
      TCHAR szText[256];
      ctlStringLB.GetText(n, szText);
      TRACE(_T("%s\n"), szText);
   }
}

테스트를 완료 하는 StringizeElement 작업에 함수를 전문화 해야는 CStringList 클래스:

template<>
CString StringizeElement(CStringList* pStringList, INT iIndex)
{
   if (pStringList != NULL && iIndex < pStringList->GetCount())
   {
      POSITION pos = pStringList->GetHeadPosition();
      for( INT i = 0; i < iIndex; i++ )
      {
         pStringList->GetNext(pos);
      }
      return pStringList->GetAt(pos);
   }
   return CString(); // or throw, depending on application requirements
}

참고 항목

참조

BEGIN_TEMPLATE_MESSAGE_MAP

개념

메시지 처리 및 매핑