Aracılığıyla paylaş


TN006: İleti eşlemeleri

Bu not, mfc ileti eşleme olanağını açıklar.

Sorunu

Microsoft Windows, ileti hizmetini kullanan pencere sınıflarına sanal fonksiyonlar uygular. İletileri dahil çok sayıda nedeniyle, her Windows ileti için ayrı bir sanal işlevi sağlayan bir şekilde basımı karşılamayacak kadar büyük vtable oluşturacak.

Çünkü sistem tanımlı Windows ileti sayısı zamanla değişen ve ileti uygulamaları, kendi Windows iletilerini tanımlayabilirsiniz çünkü eşler arabirimi değişiklikleri varolan kodu bölünmesini önler gerekebilen düzeyini sağlar.

Genel Bakış

mfc switch deyimi, geleneksel Windows tabanlı programların bir pencere gönderilen iletileri işlemek için kullanılan bir alternatif sağlar. Pencere tarafından bir ileti alındığında otomatik olarak uygun yöntemi çağrılır, iletileri bir eşleme yöntemlerini tanımlanabilir. Bu ileti eşleme olanağı sanal işlevler benzeyecek şekilde tasarlanmıştır ancak sanal C++ işlevleri ile mümkün değil ek faydaları vardır.

İleti eşleme tanımlama

DECLARE_MESSAGE_MAP Makro üç sınıf üyelerini bildirir.

  • Özel bir dizi AFX_MSGMAP_ENTRY adı verilen girdiler _messageEntries.

  • Korumalı bir AFX_MSGMAP adı verilen yapı messageMap , işaret _messageEntries dizi.

  • A korunan adlı sanal işlevi GetMessageMap adresini verir messageMap.

Bu makro, ileti eşlemeleri kullanarak herhangi bir sınıf bildiriminde koymanız gerekir. Kural gereği sınıf bildirimi sonuna kadar. Örne?in:

class CMyWnd : public CMyParentWndClass
{
    // my stuff...

protected:
    //{{AFX_MSG(CMyWnd)
    afx_msg void OnPaint();
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

Yeni sınıflar oluşturduğunuzda, AppWizard ve ClassWizard tarafından üretilen biçimidir. / / {{Ve / /}} ayraçlar ClassWizard için gerekli.

İleti eşleme kullanıcının tablo kümesini genişletmek için ileti eşleme girdilerini makro kullanarak tanımlanır. Bir tablo ile başlayan bir BEGIN_MESSAGE_MAP bu ileti eşleme tarafından işlenen sınıfı ve işlenemeyen iletileri geçirilir üst sınıfı tanımlayan makro çağrısı. Tablo ile biten END_MESSAGE_MAP makro çağrısı.

Bu iki makro aramalar arasında bu ileti eşleme tarafından işlenecek her ileti için bir girdidir. Tüm standart Windows ileti formu on_wm_ makro sahipmessage_name , bu ileti için bir giriş oluşturur.

Windows her iletinin parametreleri açmak ve tür güvenliği sağlayan standart bir işlev imzası tanımlandı. Bu imzaları bildirim Afxwin.h dosyasında bulunabilir, CWnd. Her biri, anahtar sözcüğü ile işaretlenmiş afx_msg kolay tanımlanması için.

Not

ClassWizard gerektirir, kullandığınız afx_msg ileti eşleme işleyici bildirimleri bir anahtar sözcük.

Bu işlev imzaları basit kuralı kullanarak türetilmiş. İşlevin adını her zaman başlar ile "On". Bu baş her sözcüğün ilk harfini ve Windows ileti kaldırıldı "wm_" adını izler. Sıralama parametreleri olan wParam ardından LOWORD(lParam) sonra HIWORD(lParam). Kullanılmayan Parametreler geçmedi. mfc sınıfları tarafından kaydırılan tutamaçları işaretçiler uygun mfc nesnelerine dönüştürülür. Aşağıdaki örnek, nasıl işleneceğini gösterir WM_PAINT iletisi ve neden CMyWnd::OnPaint işlevinin çağrılması:

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
    //{{AFX_MSG_MAP(CMyWnd)
    ON_WM_PAINT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

İleti eşleme tablosu herhangi bir işlev veya sınıf tanımı kapsamı dışında tanımlanmış olmalıdır. Onu extern "c" bloğunda yerleştirmemeniz gerekir.

Not

ClassWizard arasında oluşan ileti eşleme girdilerini değiştirmek / / {{ve / /}} yorum ayraç.

Windows ileti kullanıcı tanımlı

Kullanıcı tanımlı iletileri eklenebilir ileti haritada kullanarak ON_MESSAGE makro. Bu makro, bir ileti numarası ve form yöntemi kabul eder:

    // inside the class declaration
    afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

    #define WM_MYMESSAGE (WM_USER + 100)

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
    ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()

Bu örnekte biz standart türetilen Windows ileti kimliği olan özel bir ileti için bir işleyici oluşturmak WM_USER kullanıcı tanımlı iletileri temel. Aşağıdaki örnekte bu işleyicisi çağırmak gösterilmiştir:

CWnd* pWnd = ...;
pWnd->SendMessage(WM_MYMESSAGE);

Bu yaklaşımı kullanan kullanıcı tanımlı iletileri aralığını aralığında olmalı WM_USER 0x7fff için.

Not

ClassWizard girme desteklemez ON_MESSAGE ClassWizard kullanıcı arabirimi işleyicisi yordamlarından.Ayrıca Visual C++ Düzenleyicisi'nden bunları el ile girmeniz gerekir.ClassWizard, bu girişler ayrıştırmak ve bunları hemen tüm diğer ileti eşleme girdileri gibi göz olanak verir.

Kayıtlı Windows iletileri

RegisterWindowMessage işlevi sistem benzersiz olması sağlanır yeni bir pencerede ileti tanımlamak için kullanılır. Makro ON_REGISTERED_MESSAGE bu iletileri işlemek için kullanılır. Bu makro adını kabul eden bir UINT NEAR kayıtlı windows ileti kimliği içeren değişken Örneğin

class CMyWnd : public CMyParentWndClass
{
public:
    CMyWnd();

    //{{AFX_MSG(CMyWnd)
    afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

static UINT NEAR WM_FIND = RegisterWindowMessage("COMMDLG_FIND");

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
    //{{AFX_MSG_MAP(CMyWnd)
    ON_REGISTERED_MESSAGE(WM_FIND, OnFind)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Kayıtlı Windows ileti kimliği (Bu örnekte WM_FIND) değişken olmalıdır bir NEAR biçimi nedeniyle değişken ON_REGISTERED_MESSAGE uygulanır.

Bu yaklaşımı kullanan kullanıcı tanımlı iletileri aralık, aralık 0xC000-0xFFFF olacaktır.

Not

ClassWizard girme desteklemez ON_REGISTERED_MESSAGE ClassWizard kullanıcı arabirimi işleyicisi yordamlarından.Ayrıca metin Düzenleyicisi'nden bunları el ile girmeniz gerekir.ClassWizard, bu girişler ayrıştırmak ve bunları hemen tüm diğer ileti eşleme girdileri gibi göz olanak verir.

Komutu iletileri

Menüler ve Hızlandırıcılar komutu iletileri ileti haritalarını işlenen ON_COMMAND makro. Bu makro komutu kimliği ve yöntemi kabul eder. Özel WM_COMMAND olan ileti bir wParam eşit belirtilen komut kimliği ileti Eşleme girdisinde Belirtilen yöntem tarafından gerçekleştirilir. Komut işleyici üye işlevler hiçbir parametre ve dönüş void. Makro aşağıdaki biçime sahiptir:

ON_COMMAND(id, memberFxn)

Komut güncelleştirme iletileri aynı mekanizma yönlendirilir, ancak kullanmak ON_UPDATE_COMMAND_UI makro yerine. Komut update işleyicisi üye işlevler ele tek bir parametre işaretçisi bir CCmdUI nesne ve iade void. Makro formu vardır.

ON_UPDATE_COMMAND_UI(id, memberFxn)

Gelişmiş kullanıcılar ON_COMMAND_EX makro komutu ileti işleyicileri genişletilmiş biçimidir. Makro bir üst sağlar ON_COMMAND işlevi. Genişletilmiş komut işleyicisi üye işlevlerini tek bir parametre alır bir UINT , komut kimliği içerir ve dönüş bir BOOL. Dönüş değeri olmalıdır TRUE komutu işlenen belirtmek için. Aksi takdirde yönlendirme diğer komut hedef nesnelere devam edecektir.

Bu form örnekleri:

  • İç Resource.h (genellikle Visual C++ tarafından üretilen)

    #define    ID_MYCMD      100
    #define    ID_COMPLEX    101
    
  • Sınıf bildiriminde

    afx_msg void OnMyCommand();
    afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI);
    afx_msg BOOL OnComplexCommand(UINT nID);
    
  • İleti eşleme tanımının içinde

    ON_COMMAND(ID_MYCMD, OnMyCommand)
    ON_UPDATE_COMMAND_UI(ID_MYCMD, OnUpdateMyCommand)
    ON_COMMAND_EX(ID_MYCMD, OnComplexCommand)
    
  • Uygulama dosyasında

    void CMyClass::OnMyCommand()
    {
        // handle the command
    }
    
    void CMyClass::OnUpdateMyCommand(CCmdUI* pCmdUI)
    {
        // set the UI state with pCmdUI
    }
    
    BOOL CMyClass::OnComplexCommand(UINT nID)
    {
        // handle the command
        return TRUE;
    }
    

İleri düzey kullanıcılar tek bir komut işleyicisi kullanarak komutları bir dizi işlemek: on_command_range veya ON_COMMAND_RANGE_EX. Bu makrolar hakkında daha fazla bilgi için ürün belgelerine bakın.

Not

ClassWizard destekleyen oluşturma ON_COMMAND ve ON_UPDATE_COMMAND_UI işleyicileri, ancak desteklemez oluşturma ON_COMMAND_EX veya ON_COMMAND_RANGE işleyicileri.Ancak, sınıf Sihirbazı ayrıştırmak ve tüm dört komut işleyicisi çeşitleri göz olanak verir.

Denetim bildirim iletileri

Karşı pencere alt denetimlerine sahip fazladan bit bilgileri kendi ileti gönderilen iletiler eşleme girişi: denetimin kimliği. Yalnızca aşağıdaki koşullar geçerli olursa ileti Eşleme girdisinde belirtilen ileti işleyicisi çağrılır:

  • Denetim bildirim kodu (üst sınırı lParam), BN_CLICKED gibi ileti Eşleme girdisinde belirtilen bildirim kodu ile eşleşir.

  • Denetim Kimliği (wParam) ileti Eşleme girdisinde belirtilen denetim kimliği ile eşleşir.

Özel Denetim bildirim iletilerini kullanabilir ON_CONTROL özel bildirim kodu ile ileti eşleme girdisini tanımlayan makro. Bu makro formu vardır.

ON_CONTROL(wNotificationCode, id, memberFxn)

Gelişmiş kullanım için ON_CONTROL_RANGE denetimleri aynı işleyicisiyle aralığından özel denetim Bilgilendirmeyi yönetmek için kullanılır.

Not

ClassWizard oluşturma desteklemeyen bir ON_CONTROL veya ON_CONTROL_RANGE kullanıcı arabirimi işleyicisi.Ayrıca metin düzenleyici kullanarak bunları el ile girmeniz gerekir.ClassWizard, bu girişler ayrıştırmak ve bunları hemen tüm diğer ileti eşleme girdileri gibi göz olanak verir.

Daha güçlü Windows ortak denetimleri kullanmak WM_NOTIFY karmaşık denetimi bildirimleri için. mfc bu sürümünü kullanarak bu yeni ileti için doğrudan destek olan ON_NOTIFY ve ON_NOTIFY_RANGE makrolar. Bu makrolar hakkında daha fazla bilgi için ürün belgelerine bakın.

Ayrıca bkz.

Diğer Kaynaklar

Teknik notlar numarasına göre

Kategoriye göre teknik notlar