Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Uyarı
Microsoft Foundation Sınıfları (MFC) kitaplığına destek verilmeye devam ediliyor. Ancak artık özellik eklemeyeceğiz veya belgeleri güncelleştirmeyeceğiz.
Bu not, MFC ileti eşleme özelliğini açıklar.
Sorun
Microsoft Windows, mesajlaşma tesisini kullanan pencere sınıflarında sanal işlevler uygular. Çok sayıda ileti söz konusu olduğundan, her Windows iletisi için ayrı bir sanal işlev sağlamak, aşırı büyük bir vtable oluşturur.
Sistem tanımlı Windows iletilerinin sayısı zaman içinde değiştiğinden ve uygulamalar kendi Windows iletilerini tanımlayabildiği için, ileti eşlemeleri arabirim değişikliklerinin var olan kodu bozmasını engelleyen bir dolaylılık düzeyi sağlar.
Genel Bakış
MFC, pencereye gönderilen iletileri işlemek için geleneksel Windows tabanlı programlarda kullanılan switch deyimine bir alternatif sağlar. İletilerden yöntemlere eşleme tanımlanabilir, böylece bir pencere tarafından bir ileti alındığında uygun yöntem otomatik olarak çağrılır. Bu ileti eşleme özelliği sanal işlevlere benzeyecek şekilde tasarlanmıştır, ancak C++ sanal işlevleriyle ek avantajlar sağlanmaz.
Mesaj Haritası Tanımlama
DECLARE_MESSAGE_MAP makro, bir sınıf için üç üye bildirir.
_messageEntries adlı özel AFX_MSGMAP_ENTRY girdi dizisi.
_messageEntries dizisini işaret eden messageMap adlı korumalı AFX_MSGMAP yapısı.
GetMessageMapadlı ve messageMap adresini döndüren korumalı bir sanal işlev.
Bu makro, ileti eşlemeleri kullanılarak herhangi bir sınıfın bildirimine yerleştirilmelidir. Kural gereği, sınıf bildirimleri sonunda yer alır. Örneğin:
class CMyWnd : public CMyParentWndClass
{
// my stuff...
protected:
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Bu, yeni sınıflar oluştururken AppWizard ve ClassWizard tarafından oluşturulan biçimdir. ClassWizard için //{{ ve //}} köşeli ayraçları gerekir.
İleti eşlemesinin tablosu, ileti eşlemesi girişlerine genişleten bir makro kümesi kullanılarak tanımlanır. Tablo, bu ileti eşlemesi tarafından işlenen sınıfı ve işlenmeyen iletilerin geçirildiği üst sınıfı tanımlayan bir BEGIN_MESSAGE_MAP makro çağrısıyla başlar. Tablo , END_MESSAGE_MAP makro çağrısıyla sona erer.
Bu iki makro çağrısı arasında, bu ileti eşlemesi tarafından işlenecek her ileti için bir girdi bulunur. Her standart Windows mesajının, o mesaj için bir girdi oluşturan ON_WM_MESSAGE_NAME şeklinde bir makrosu vardır.
Her Windows iletisinin parametrelerini açmak ve tür güvenliği sağlamak için standart bir işlev imzası tanımlanmıştır. Bu imzalar , CWnd bildiriminde Afxwin.h dosyasında bulunabilir. Her biri kolay tanımlama için anahtar sözcük afx_msg ile işaretlenir.
Uyarı
ClassWizard, ileti eşleme işleyici bildirimlerinizde afx_msg anahtar sözcüğünü kullanmanızı gerektirir.
Bu işlev imzaları basit bir kural kullanılarak türetilmiştir. İşlevin adı her zaman "ile "Onbaşlar. Bunu, "WM_" kaldırılmış ve her sözcüğün ilk harfi büyük harfle yazılmış olan Windows iletisinin adı izler. Parametrelerin sıralanması wParam ve ardından LOWORD(lParam) ve ardından HIWORD(lParam) olur. Kullanılmayan parametreler geçirilmez. MFC sınıfları tarafından sarmalanan tüm tutucular, uygun MFC nesnelerine işaret eden işaretçilere dönüştürülür. Aşağıdaki örnek, WM_PAINT iletisinin nasıl işleneceğini ve işlevin CMyWnd::OnPaint çağrılmasına neden olduğunu gösterir:
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ının kapsamı dışında tanımlanmalıdır. Extern "C" bloğuna konmamalıdır.
Uyarı
ClassWizard, //{{ ve //}} açıklama köşeli ayracı arasında gerçekleşen ileti eşleme girdilerini değiştirir.
Kullanıcı Tanımlı Windows İletileri
Kullanıcı tanımlı iletiler , ON_MESSAGE makro kullanılarak ileti eşlemesine eklenebilir. Bu makro bir ileti numarası ve formun yöntemini 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, kullanıcı tanımlı iletiler için standart WM_USER tabanından türetilmiş bir Windows ileti kimliğine sahip özel ileti için bir işleyici oluşturacağız. Aşağıdaki örnekte bu işleyicinin nasıl çağrılacakları gösterilmektedir:
CWnd* pWnd = ...;
pWnd->SendMessage(WM_MYMESSAGE);
WM_USER'den 0x7fff'e kadar olan aralıkta yer alan kullanıcı tanımlı mesajlar bu yaklaşımı kullanmalıdır.
Uyarı
ClassWizard, ClassWizard kullanıcı arabiriminden ON_MESSAGE işleyici yordamları girmeyi desteklemez. Bunları Visual Studio düzenleyicisinden el ile girmeniz gerekir. ClassWizard bu girdileri ayrıştıracak ve diğer ileti eşleme girdileri gibi bunlara göz atmanıza olanak sağlar.
Kayıtlı Windows İletileri
RegisterWindowMessage işlevi, sistem genelinde benzersiz olması garanti edilen yeni bir pencere iletisi tanımlamak için kullanılır. Makro ON_REGISTERED_MESSAGE bu iletileri işlemek için kullanılır. Bu makro, kayıtlı Windows ileti kimliğini içeren bir UINT NEAR değişkeninin adını kabul eder. Ö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 değişkeni (bu örnekte WM_FIND) ON_REGISTERED_MESSAGE uygulanma biçiminden dolayı NEAR değişkeni olmalıdır.
Bu yaklaşımı kullanan kullanıcı tanımlı mesajların aralığı, 0xC000 ile 0xFFFF arasında olacaktır.
Uyarı
ClassWizard, ClassWizard kullanıcı arabiriminden ON_REGISTERED_MESSAGE işleyici yordamları girmeyi desteklemez. Bunları metin düzenleyicisinden el ile girmeniz gerekir. ClassWizard bu girdileri ayrıştıracak ve diğer ileti eşleme girdileri gibi bunlara göz atmanıza olanak sağlar.
Komut İletileri
Menülerden ve hızlandırıcılardan gelen komut iletileri, ON_COMMAND makroyla ileti eşlemelerinde işlenir. Bu makro bir komut kimliği ve bir yöntem kabul eder. Yalnızca belirtilen komut kimliğine eşit bir wParam içeren belirli WM_COMMAND iletisi, ileti eşleme girdisinde belirtilen yöntem tarafından işlenir. Komut işleyicisi üye işlevleri parametre almaz ve döndürür void. Makro aşağıdaki forma sahiptir:
ON_COMMAND(id, memberFxn)
Komut güncelleştirme iletileri aynı mekanizma üzerinden yönlendirilir, ancak bunun yerine ON_UPDATE_COMMAND_UI makrosunu kullanın. Komut güncelleme işleyicisi üye işlevleri, bir CCmdUI nesnesine işaretçi olmak üzere tek bir parametre alır ve void döndürür. Makro şu şekilde biçimlendirilmiştir
ON_UPDATE_COMMAND_UI(id, memberFxn)
Gelişmiş kullanıcılar, genişletilmiş komut iletisi işleyicileri biçimi olan ON_COMMAND_EX makrosunu kullanabilir. Makro, ON_COMMAND işlevselliğinin üst kümesini sağlar. Genişletilmiş komut işleyicisi üye işlevleri tek bir parametre, komut kimliğini içeren bir UINT alır ve bir BOOL döndürür. Komutun işlendiğini belirtmek için dönüş değeri TRUE olmalıdır. Aksi takdirde yönlendirme diğer komut hedef nesnelerine devam eder.
Bu formlara örnekler:
Resource.h içinde (genellikle Visual Studio tarafından oluşturulur)
#define ID_MYCMD 100 #define ID_COMPLEX 101Sınıf tanımının içinde
afx_msg void OnMyCommand(); afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI); afx_msg BOOL OnComplexCommand(UINT nID);Mesaj haritası 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; }
Gelişmiş kullanıcılar tek bir komut işleyicisi kullanarak bir dizi komutu işleyebilir: ON_COMMAND_RANGE veya ON_COMMAND_RANGE_EX. Bu makrolar hakkında daha fazla bilgi için ürün belgelerine bakın.
Uyarı
ClassWizard, ON_COMMAND ve ON_UPDATE_COMMAND_UI işleyicileri oluşturmayı destekler, ancak ON_COMMAND_EX veya ON_COMMAND_RANGE işleyicileri oluşturmayı desteklemez. Ancak, Sınıf Sihirbazı ayrıştıracak ve dört komut işleyici varyantına göz atmanıza izin verecek.
Bildirim İletilerini Denetleme
Alt kontrol öğelerinden bir pencereye gönderilen iletiler, mesaj haritası girdisinde ek bilgi içermektedir: kontrolün kimliği. İleti eşleme girdisinde belirtilen ileti işleyicisi yalnızca aşağıdaki koşullar doğruysa çağrılır:
BN_CLICKED gibi denetim bildirim kodu ( lParam'ın yüksek sözcüğü), ileti eşleme girdisinde belirtilen bildirim koduyla eşleşir.
Denetim kimliği (wParam), ileti eşleme girdisinde belirtilen denetim kimliğiyle eşleşir.
Özel denetim bildirim iletileri, özel bildirim koduyla bir ileti eşleme girdisi tanımlamak için ON_CONTROL makrosunu kullanabilir. Bu makronun belirli bir biçimi var
ON_CONTROL(wNotificationCode, id, memberFxn)
Gelişmiş kullanım ON_CONTROL_RANGE için, aynı işleyiciye sahip bir denetim aralığından belirli bir denetim bildirimini işlemek için kullanılabilir.
Uyarı
ClassWizard, kullanıcı arabiriminde bir ON_CONTROL veya ON_CONTROL_RANGE işleyicisi oluşturmayı desteklemez. Bunları metin düzenleyicisiyle el ile girmeniz gerekir. ClassWizard bu girdileri ayrıştıracak ve diğer ileti eşleme girdileri gibi bunlara göz atmanıza olanak sağlar.
Windows Ortak Denetimleri, karmaşık denetim bildirimleri için daha güçlü WM_NOTIFY kullanır. MFC'nin bu sürümü, ON_NOTIFY ve ON_NOTIFY_RANGE makrolarını kullanarak bu yeni ileti için doğrudan desteğe sahiptir. Bu makrolar hakkında daha fazla bilgi için ürün belgelerine bakın.
Ayrıca bakınız
Numaraya Göre Teknik Notlar
Kategorilere Göre Teknik Notlar