Aracılığıyla paylaş


TN061: ON_NOTIFY ve WM_NOTIFY İletileri

Dekont

Aşağıdaki teknik not, çevrimiçi belgelere ilk kez eklendiğinden beri güncelleştirilmemiştir. Sonuç olarak, bazı yordamlar ve konular güncel olmayabilir veya yanlış olabilir. En son bilgiler için, çevrimiçi belge dizininde ilgilendiğiniz konuyu aramanız önerilir.

Bu teknik not, yeni WM_NOTIFY iletisiyle ilgili arka plan bilgileri sağlar ve MFC uygulamanızda WM_NOTIFY iletileri işlemenin önerilen (ve en yaygın) yolunu açıklar.

Windows 3.x'te Bildirim İletileri

Windows 3.x'te denetimler fare tıklamaları, içerik ve seçim değişiklikleri gibi olayları üst yöneticilere bildirir ve üst öğeye ileti göndererek arka plan boyamayı denetler. Basit bildirimler özel WM_COMMAND iletileri olarak gönderilir; bildirim kodu (BN_CLICKED gibi) ve denetim kimliği wParam'a ve denetimin lParam'daki tanıtıcısına paketlenir. wParam ve lParam dolu olduğundan ek veri geçirmenin hiçbir yolu olmadığını unutmayın; bu iletiler yalnızca basit bir bildirim olabilir. Örneğin, BN_CLICKED bildiriminde, düğmeye tıklandığında fare imlecinin konumu hakkında bilgi göndermenin hiçbir yolu yoktur.

Windows 3.x'teki denetimlerin ek veri içeren bir bildirim iletisi göndermesi gerektiğinde, WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM vb. gibi çeşitli özel amaçlı iletiler kullanır. Bu iletiler, bunları gönderen denetime geri yansıtılabilir. Daha fazla bilgi için bkz. TN062: Windows Denetimleri için ileti Düşünceler.

Win32'de Bildirim İletileri

Windows 3.1'de bulunan denetimler için, Win32 API'si Windows 3.x'te kullanılan bildirim iletilerinin çoğunu kullanır. Ancak Win32, Windows 3.x'te desteklenenlere bir dizi karmaşık denetim de ekler. Bu denetimlerin sıklıkla bildirim iletileriyle birlikte ek veri göndermesi gerekir. Win32 API'sinin tasarımcıları, ek verilere ihtiyaç duyan her yeni bildirim için yeni bir WM_* iletisi eklemek yerine, standartlaştırılmış bir şekilde herhangi bir miktarda ek veri geçirebilen tek bir ileti (WM_NOTIFY) eklemeyi tercih etti.

WM_NOTIFY iletileri, iletiyi wParam'da gönderen denetimin kimliğini ve lParam'daki bir yapıya ilişkin işaretçiyi içerir. Bu yapı bir NMHDR yapısı veya ilk üyesi olarak NMHDR yapısına sahip olan daha büyük bir yapıdır. NMHDR üyesi ilk olduğundan, bu yapıya yönelik bir işaretçinin NMHDR'ye işaretçi olarak veya nasıl yayınladığınıza bağlı olarak daha büyük bir yapıya yönelik bir işaretçi olarak kullanılabileceğini unutmayın.

Çoğu durumda, işaretçi daha büyük bir yapıya işaret eder ve kullanırken bunu atamanız gerekir. Yaygın bildirimler (adları NM_ ile başlayan) ve araç ipucu denetiminin TTN_SHOW ve TTN_POP bildirimleri gibi yalnızca birkaç bildirimde, aslında kullanılan bir NMHDR yapısıdır.

NMHDR yapısı veya ilk üye, iletiyi ve bildirim kodunu (TTN_SHOW gibi) gönderen denetimin tanıtıcısını ve kimliğini içerir. NMHDR yapısının biçimi aşağıda gösterilmiştir:

typedef struct tagNMHDR {
    HWND hwndFrom;
    UINT idFrom;
    UINT code;
} NMHDR;

TTN_SHOW ileti için kod üyesi TTN_SHOW olarak ayarlanır.

Çoğu bildirim, ilk üyesi olarak NMHDR yapısını içeren daha büyük bir yapıya bir işaretçi geçirir. Örneğin, liste görünümü denetiminde bir tuşa basıldığında gönderilen liste görünümü denetiminin LVN_KEYDOWN bildirim iletisi tarafından kullanılan yapıyı göz önünde bulundurun. İşaretçi, aşağıda gösterildiği gibi tanımlanan LV_KEYDOWN bir yapıyı gösterir:

typedef struct tagLV_KEYDOWN {
    NMHDR hdr;
    WORD wVKey;
    UINT flags;
} LV_KEYDOWN;

NmHDR üyesi bu yapıda ilk olduğundan, bildirim iletisinde geçirilen işaretçinin NMHDR işaretçisine veya bir LV_KEYDOWN işaretçisine atanabileceğini unutmayın.

Tüm Yeni Windows Denetimlerinde Ortak Bildirimler

Bazı bildirimler tüm yeni Windows denetimlerinde ortaktır. Bu bildirimler NMHDR yapısına bir işaretçi geçirir.

Bildirim kodu Gönderildi çünkü
NM_CLICK Kullanıcı denetimde sol fare düğmesine tıkladı
NM_DBLCLK Kullanıcı denetimde sol fare düğmesine çift tıkladı
NM_RCLICK Kullanıcı denetimde sağ fare düğmesine tıkladı
NM_RDBLCLK Kullanıcı denetimde sağ fare düğmesine çift tıkladı
NM_RETURN Denetim giriş odağına sahipken kullanıcı ENTER tuşuna bastı
NM_SETFOCUS Denetime giriş odağı verildi
NM_KILLFOCUS Denetim giriş odağını kaybetti
NM_OUTOFMEMORY Kullanılabilir yeterli bellek olmadığından denetim bir işlemi tamamlayamadı

ON_NOTIFY: MFC Uygulamalarında WM_NOTIFY İletilerini İşleme

İşlev CWnd::OnNotify , bildirim iletilerini işler. Varsayılan uygulaması, çağrılacak bildirim işleyicileri için ileti eşlemesini denetler. Genel olarak, geçersiz kılmazsınız OnNotify. Bunun yerine bir işleyici işlevi sağlar ve sahip pencerenizin sınıfının ileti eşlemesine bu işleyici için bir ileti eşleme girdisi eklersiniz.

ClassWizard, ClassWizard özellik sayfası aracılığıyla ON_NOTIFY ileti eşleme girdisini oluşturabilir ve size bir iskelet işleyici işlevi sağlayabilir. Bunu kolaylaştırmak için ClassWizard kullanma hakkında daha fazla bilgi için bkz . İletileri İşlevlere Eşleme.

ON_NOTIFY ileti eşleme makrosunun söz dizimi aşağıdaki gibidir:

ON_NOTIFY(wNotifyCode, id, memberFxn)

burada parametreler şunlardır:

wNotifyCode
LVN_KEYDOWN gibi işlenecek bildirim iletisinin kodu.

id
Bildirimin gönderildiği denetimin alt tanımlayıcısı.

memberFxn
Bu bildirim gönderildiğinde çağrılacak üye işlevi.

Üye işlevinizin aşağıdaki prototiple bildirilmesi gerekir:

afx_msg void memberFxn(NMHDR* pNotifyStruct, LRESULT* result);

burada parametreler şunlardır:

pNotifyStruct
Yukarıdaki bölümde açıklandığı gibi bildirim yapısının işaretçisi.

Sonuç
Dönmeden önce ayarladığınız sonuç kodunun işaretçisi.

Örnek

Üye işlevinin OnKeydownList1 kimliği IDC_LIST1olan öğesinden LVN_KEYDOWN iletileri işlemesini CListCtrl istediğinizi belirtmek için ClassWizard'ı kullanarak ileti eşlemenize aşağıdakileri ekleyebilirsiniz:

ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeydownList1)

Yukarıdaki örnekte ClassWizard tarafından sağlanan işlev:

void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;

    // TODO: Add your control notification handler
    //       code here

    *pResult = 0;
}

ClassWizard'ın uygun türün işaretçisini otomatik olarak sağladığını unutmayın. Bildirim yapısına pNMHDR veya pLVKeyDow aracılığıyla erişebilirsiniz.

ON_NOTIFY_RANGE

Bir denetim kümesi için aynı WM_NOTIFY iletisini işlemeniz gerekiyorsa, ON_NOTIFY yerine ON_NOTIFY_RANGE kullanabilirsiniz. Örneğin, belirli bir bildirim iletisi için aynı eylemi gerçekleştirmek istediğiniz bir dizi düğmeniz olabilir.

ON_NOTIFY_RANGE kullandığınızda, aralığın başlangıç ve bitiş alt tanımlayıcılarını belirterek bildirim iletisinin işlendiği bitişik bir alt tanımlayıcı aralığı belirtirsiniz.

ClassWizard ON_NOTIFY_RANGE işlemez; kullanmak için ileti haritanızı kendiniz düzenlemeniz gerekir.

ON_NOTIFY_RANGE için ileti haritası girişi ve işlev prototipi aşağıdaki gibidir:

ON_NOTIFY_RANGE(wNotifyCode, id, idLast, memberFxn)

burada parametreler şunlardır:

wNotifyCode
LVN_KEYDOWN gibi işlenecek bildirim iletisinin kodu.

id
Bitişik tanımlayıcı aralığındaki ilk tanımlayıcı.

idLast
Bitişik tanımlayıcı aralığındaki son tanımlayıcı.

memberFxn
Bu bildirim gönderildiğinde çağrılacak üye işlevi.

Üye işlevinizin aşağıdaki prototiple bildirilmesi gerekir:

afx_msg void memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);

burada parametreler şunlardır:

id
Bildirimi gönderen denetimin alt tanımlayıcısı.

pNotifyStruct
Yukarıda açıklandığı gibi bildirim yapısının işaretçisi.

Sonuç
Dönmeden önce ayarladığınız sonuç kodunun işaretçisi.

ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE

Bildirim yönlendirmesinde bir iletiyi işlemek için birden fazla nesne istiyorsanız, ON_NOTIFY (veya ON_NOTIFY_RANGE) yerine ON_NOTIFY_EX (veya ON_NOTIFY_EX_RANGE) kullanabilirsiniz. EX sürümü ile normal sürüm arasındaki tek fark, EX sürümü için çağrılan üye işlevinin ileti işlemenin devam edip etmeyeceğini belirten bir BOOL döndürmesidir. Bu işlevden FALSE döndürerek aynı iletiyi birden çok nesnede işleyebilirsiniz.

ClassWizard ON_NOTIFY_EX veya ON_NOTIFY_EX_RANGE işlemez; bunlardan birini kullanmak istiyorsanız, ileti haritanızı kendiniz düzenlemeniz gerekir.

ON_NOTIFY_EX ve ON_NOTIFY_EX_RANGE için ileti haritası girişi ve işlev prototipi aşağıdaki gibidir. Parametrelerin anlamları, EX olmayan sürümlerle aynıdır.

ON_NOTIFY_EX(nCode, id, memberFxn)
ON_NOTIFY_EX_RANGE(wNotifyCode, id, idLast, memberFxn)

Yukarıdakilerin her ikisi için de prototip aynıdır:

afx_msg BOOL memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);

Her iki durumda da id, bildirimi gönderen denetimin alt tanımlayıcısını tutar.

Bildirim iletisi tamamen işlendiyse işlevinizin TRUE veya komut yönlendirmesindeki diğer nesnelerin iletiyi işleme şansı olması gerekiyorsa YANLIŞ döndürmelidir.

Ayrıca bkz.

Sayıya Göre Teknik Notlar
Kategoriye Göre Teknik Notlar