Aracılığıyla paylaş


Nasıl yapılır: şablon sınıfı için bir ileti harita oluşturma

mfc ileti eşleme uygun C++ nesnesi örneğine Windows iletileri yönlendirmek için etkili bir yöntem sağlar.mfc ileti eşleme hedefleri uygulama sınıfları, belge ve view sınıfları, Denetim sınıfları ve benzeri örnekler.

Geleneksel mfc ileti eşlemeleri kullanarak bildirilmiş BEGIN_MESSAGE_MAP her ileti işleyicisi sınıf yöntemi için bir makro giriş iletisi haritanın başlangıç bildirmek için makro ve son END_MESSAGE_MAP sonuna kadar ileti eşleme bildirmek için makro.

Bir sınırlama ile BEGIN_MESSAGE_MAP makro şablon değişkenlerini içeren bir sınıf ile birlikte kullanıldığında oluşur.Şablon sınıfıyla kullanıldığında, bu makroyu Makro genişleme sırasında derleme zamanı hatası yüzünden eksik şablon parametreleri neden olur.BEGIN_TEMPLATE_MESSAGE_MAP Makro kendi ileti bildirmek için tek bir şablon değişkeni içeren sınıflar eşler izin vermek için tasarlanmıştır.

Örnek

Bir örneği inceleyin nerede mfc CListBox sınıfı bir dış veri kaynağıyla eşitleme sağlamak için genişletilmiş.Hayal CSyncListBox sınıfının şöyle bildirilmiştir:

// 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 sınıfı eşitleme ile veri kaynağını tanımlayan tek bir tür şablonu esas alan.Sınıf ileti haritasını katılacak üç yöntem de bildirir: OnPaint, OnDestroy, ve OnSynchronize.OnSynchronize yöntemi aşağıdaki gibi gerçekleştirilir:

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;
}

Yukarıdaki uygulama verir CSyncListBox uygulayan herhangi bir sınıf türü özelleştirilmesi sınıf GetCount yöntemi gibi CArray, CList, ve CMap.StringizeElement işlevidir şablon işlevi tarafından aşağıdaki prototyped:

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

Normalde, bu sınıf için ileti eşleme olarak tanımlanır:

BEGIN_MESSAGE_MAP(CSyncListBox, CListBox)

ON_WM_PAINT()

ON_WM_DESTROY()

ON_MESSAGE(LBN_SYNCHRONIZE, OnSynchronize)

END_MESSAGE_MAP()

Burada LBN_SYNCHRONIZE gibi uygulama tarafından tanımlanan özel kullanıcı iletisi:

#define LBN_SYNCHRONIZE (WM_USER + 1)

Yukarıdaki makroyu haritası derlenmez, nedeni için gerçeğine, şablon belirtimi için CSyncListBox sınıf olacaktır eksik makro genişleme sırasında.BEGIN_TEMPLATE_MESSAGE_MAP makro çözdü bu Genişletilmiş makro eşlemeye belirtilen şablon parametre ekleyerek.Bu sınıf için ileti eşleme olur:

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

Aşağıdaki örnek kullanımını göstermektedir CSyncListBox sınıfını kullanarak bir CStringList nesne:

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);
   }
}

Sınama işlemini tamamlamak için StringizeElement işlevi özelleştirilmiş, çalışmak için CStringList sınıfı:

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
}

Ayrıca bkz.

Başvuru

BEGIN_TEMPLATE_MESSAGE_MAP

Kavramlar

İleti işleme ve eşleme