Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Nota
Catatan teknis berikut belum diperbarui sejak pertama kali disertakan dalam dokumentasi online. Akibatnya, beberapa prosedur dan topik mungkin kedaluarsa atau salah. Untuk informasi terbaru, disarankan agar Anda mencari topik yang menarik dalam indeks dokumentasi online.
Catatan teknis ini menjelaskan refleksi pesan, fitur baru di MFC 4.0. Ini juga berisi petunjuk arah untuk membuat kontrol sederhana yang dapat digunakan kembali yang menggunakan pantulan pesan.
Catatan teknis ini tidak membahas refleksi pesan karena berlaku untuk kontrol ActiveX (sebelumnya disebut kontrol OLE). Silakan lihat artikel Kontrol ActiveX: Subkelas Kontrol Windows.
Apa itu Refleksi Pesan
Kontrol Windows sering mengirim pesan pemberitahuan ke jendela induknya. Misalnya, banyak kontrol mengirim pesan pemberitahuan warna kontrol (WM_CTLCOLOR atau salah satu variannya) ke induknya untuk memungkinkan induk menyediakan kuas untuk melukis latar belakang kontrol.
Di Windows dan di MFC sebelum versi 4.0, jendela induk, sering kali kotak dialog, bertanggung jawab untuk menangani pesan-pesan ini. Ini berarti bahwa kode untuk menangani pesan harus berada di kelas jendela induk dan harus diduplikasi di setiap kelas yang perlu menangani pesan tersebut. Dalam kasus di atas, setiap kotak dialog yang menginginkan kontrol dengan latar belakang kustom harus menangani pesan pemberitahuan warna kontrol. Akan jauh lebih mudah untuk menggunakan kembali kode jika kelas kontrol dapat ditulis yang akan menangani warna latar belakangnya sendiri.
Di MFC 4.0, mekanisme lama masih berfungsi — jendela induk dapat menangani pesan pemberitahuan. Namun, MFC 4.0 memfasilitasi penggunaan kembali dengan menyediakan fitur yang disebut "pantulan pesan" yang memungkinkan pesan pemberitahuan ini ditangani di jendela kontrol anak atau jendela induk, atau di keduanya. Dalam contoh mengenai warna latar belakang kontrol, Anda sekarang dapat menulis kelas kontrol yang menetapkan warna latar belakangnya sendiri dengan menangani pesan WM_CTLCOLOR yang direfleksikan — semuanya tanpa harus bergantung pada elemen induk. (Perhatikan bahwa karena refleksi pesan diimplementasikan oleh MFC, bukan oleh Windows, kelas jendela induk harus berasal dari CWnd
agar refleksi pesan berfungsi.)
Versi MFC yang lebih lama mempunyai fitur serupa dengan refleksi pesan dengan menyediakan fungsi virtual untuk beberapa pesan, seperti pesan untuk kotak daftar yang dibuat oleh pemilik (WM_DRAWITEM, dan sebagainya). Mekanisme refleksi pesan baru digeneralisasi dan konsisten.
Refleksi pesan kompatibel mundur dengan kode yang ditulis untuk versi MFC sebelum 4.0.
Jika Anda telah menyediakan handler untuk pesan tertentu, atau untuk rentang pesan, di kelas jendela induk Anda, itu akan mengganti handler pesan yang tercerminkan untuk pesan yang sama, dengan syarat Anda tidak memanggil fungsi handler kelas dasar di dalam handler Anda sendiri. Misalnya, jika Anda menangani WM_CTLCOLOR dalam kelas dialog Anda, penanganan Anda akan mengesampingkan pengendalian pesan yang dipantulkan.
Jika, di kelas jendela induk, Anda menyediakan handler untuk pesan WM_NOTIFY tertentu atau rentang pesan WM_NOTIFY, handler Anda akan dipanggil hanya jika kontrol anak yang mengirim pesan tersebut tidak memiliki handler pesan yang tercermin melalui ON_NOTIFY_REFLECT()
. Jika Anda menggunakan ON_NOTIFY_REFLECT_EX()
dalam peta pesan, penanganan pesan Anda mungkin atau mungkin tidak mengizinkan jendela induk untuk menangani pesan. Jika handler mengembalikan FALSE, pesan akan ditangani oleh induk juga, sementara panggilan yang mengembalikan TRUE tidak memungkinkan induk untuk menanganinya. Perhatikan bahwa pesan yang tercermin ditangani sebelum pesan pemberitahuan.
Ketika pesan WM_NOTIFY dikirim, kontrol ditawarkan kesempatan pertama untuk menanganinya. Jika ada pesan lain yang tercermin dikirim, jendela induk memiliki kesempatan pertama untuk menanganinya dan kontrol akan menerima pesan yang tercermin. Untuk melakukannya, diperlukan fungsi handler dan entri yang sesuai dalam peta pesan kelas kontrol.
Makro peta pesan untuk pesan yang direfleksikan sedikit berbeda dari untuk pemberitahuan reguler: makro tersebut telah _REFLECT ditambahkan ke nama yang biasa. Misalnya, untuk menangani pesan WM_NOTIFY di induk, Anda menggunakan makro ON_NOTIFY dalam peta pesan induk. Untuk menangani pesan yang tercermin pada kontrol anak, gunakan makro ON_NOTIFY_REFLECT di peta pesan kontrol anak. Dalam beberapa kasus, parameternya juga berbeda. Perhatikan bahwa ClassWizard biasanya dapat menambahkan entri peta pesan untuk Anda dan menyediakan implementasi fungsi kerangka dengan parameter yang benar.
Lihat TN061: pesan ON_NOTIFY dan WM_NOTIFY untuk informasi tentang pesan WM_NOTIFY baru.
EntriMessage-Map dan Prototipe Fungsi Handler untuk Pesan Refleksi
Untuk menangani pesan pemberitahuan kontrol yang tercermin, gunakan makro peta pesan dan prototipe fungsi yang tercantum dalam tabel di bawah ini.
ClassWizard biasanya dapat menambahkan entri peta pesan ini untuk Anda dan menyediakan implementasi fungsi kerangka. Lihat Menentukan Penanganan Pesan untuk Pesan Tercermin untuk informasi tentang cara menentukan penangan untuk pesan yang tercermin.
Untuk mengonversi dari nama pesan ke nama makro yang tercermin, tambahkan ON_ sebelumnya dan tambahkan _REFLECT. Misalnya, WM_CTLCOLOR menjadi ON_WM_CTLCOLOR_REFLECT. (Untuk melihat pesan mana yang dapat direfleksikan, lakukan konversi yang berlawanan pada entri makro dalam tabel di bawah ini.)
Tiga pengecualian untuk aturan di atas adalah sebagai berikut:
Makro untuk pemberitahuan WM_COMMAND adalah ON_CONTROL_REFLECT.
Makro untuk pantulan WM_NOTIFY adalah ON_NOTIFY_REFLECT.
Makro untuk refleksi ON_UPDATE_COMMAND_UI adalah ON_UPDATE_COMMAND_UI_REFLECT.
Dalam setiap kasus khusus di atas, Anda harus menentukan nama fungsi anggota handler. Dalam kasus lain, Anda harus menggunakan nama standar untuk fungsi handler Anda.
Arti-arti dari parameter dan nilai pengembalian fungsi didokumentasikan pada nama fungsi atau nama fungsi dengan On yang ditambahkan di depan. Misalnya, CtlColor
didokumenkan dalam OnCtlColor
. Beberapa penanganan pesan reflektif memerlukan lebih sedikit parameter dibandingkan dengan penanganan serupa di jendela induk. Cukup cocokkan nama dalam tabel di bawah ini dengan nama parameter formal dalam dokumentasi.
Entri peta | Prototipe fungsi |
---|---|
ON_CONTROL_REFLECT(wNotifyCode ,memberFxn ) |
afx_msg voidmemberFxn (); |
ON_NOTIFY_REFLECT(wNotifyCode ,memberFxn ) |
afx_msg voidmemberFxn ( NMHDR*pNotifyStruct , LRESULT*hasil); |
ON_UPDATE_COMMAND_UI_REFLECT(memberFxn ) |
afx_msg batalmemberFxn ( CCmdUI*pCmdUI ); |
ON_WM_CTLCOLOR_REFLECT( ) |
afx_msg HBRUSH CtlColor ( CDC*pDC , UINTnCtlColor ); |
ON_WM_DRAWITEM_REFLECT( ) |
afx_msg void DrawItem ( LPDRAWITEMSTRUCTlpDrawItemStruct ); |
ON_WM_MEASUREITEM_REFLECT( ) |
afx_msg measureItem batal ( LPMEASUREITEMSTRUCTlpMeasureItemStruct ); |
ON_WM_DELETEITEM_REFLECT( ) |
afx_msg void DeleteItem ( LPDELETEITEMSTRUCTlpDeleteItemStruct ); |
ON_WM_COMPAREITEM_REFLECT( ) |
afx_msg int CompareItem (LPCOMPAREITEMSTRUCTlpCompareItemStruct ); |
ON_WM_CHARTOITEM_REFLECT( ) |
afx_msg int CharToItem ( UINTnKey , UINTnIndex ); |
ON_WM_VKEYTOITEM_REFLECT( ) |
afx_msg int VKeyToItem ( UINTnKey , UINTnIndex ); |
ON_WM_HSCROLL_REFLECT( ) |
afx_msg void HScroll (UINTnSBCode , UINTnPos ); |
ON_WM_VSCROLL_REFLECT( ) |
afx_msg void VScroll ( UINTnSBCode , UINTnPos ); |
ON_WM_PARENTNOTIFY_REFLECT( ) |
afx_msg void ParentNotify (UINTmessage , LPARAMlParam ); |
Makro ON_NOTIFY_REFLECT dan ON_CONTROL_REFLECT memiliki variasi yang memungkinkan lebih dari satu objek (seperti kontrol dan induknya) untuk menangani pesan tertentu.
Entri peta | Prototipe fungsi |
---|---|
ON_NOTIFY_REFLECT_EX(wNotifyCode ,memberFxn ) |
afx_msg BOOLmemberFxn ( NMHDR*pNotifyStruct , LRESULT*hasil); |
ON_CONTROL_REFLECT_EX(wNotifyCode ,memberFxn ) |
afx_msg BOOLmemberFxn (); |
Menangani Pesan tercermin: Contoh kontrol yang dapat digunakan kembali
Contoh sederhana ini membuat kontrol yang dapat digunakan kembali yang disebut CYellowEdit
. Kontrol bekerja sama dengan kontrol edit reguler kecuali menampilkan teks hitam pada latar belakang kuning. Akan mudah untuk menambahkan fungsi anggota yang akan memungkinkan CYellowEdit
kontrol untuk menampilkan warna yang berbeda.
Untuk mencoba contoh yang membuat kontrol yang dapat digunakan kembali
Buat kotak dialog baru di aplikasi yang sudah ada. Untuk informasi selengkapnya, lihat topik editor dialog .
Anda harus memiliki aplikasi untuk mengembangkan kontrol yang dapat digunakan kembali. Jika Anda tidak memiliki aplikasi yang sudah ada untuk digunakan, buat aplikasi berbasis dialog menggunakan AppWizard.
Dengan proyek Anda dimuat ke Visual C++, gunakan ClassWizard untuk membuat kelas baru yang disebut
CYellowEdit
berdasarkanCEdit
.Tambahkan tiga variabel anggota ke kelas Anda
CYellowEdit
. Dua yang pertama adalah variabel COLORREF untuk menahan warna teks dan warna latar belakang. Objek ketiga adalahCBrush
yang menampung kuas yang digunakan untuk melukis latar belakang. ObjekCBrush
memungkinkan Anda untuk membuat kuas satu kali, merujuknya setelah itu, dan menghancurkannya secara otomatis ketika kontrolCYellowEdit
dihancurkan.Inisialisasi variabel anggota dengan menulis konstruktor sebagai berikut:
CYellowEdit::CYellowEdit() { m_clrText = RGB(0, 0, 0); m_clrBkgnd = RGB(255, 255, 0); m_brBkgnd.CreateSolidBrush(m_clrBkgnd); }
Dengan menggunakan ClassWizard, tambahkan handler untuk pesan WM_CTLCOLOR yang terkait ke kelas
CYellowEdit
Anda. Perhatikan bahwa tanda sama dengan sebelum nama pesan dalam daftar pesan yang dapat Anda tangani menunjukkan bahwa pesan sudah tercermin. Ini dijelaskan dalam Mendefinisikan Handler Pesan untuk Pesan Tercermin.ClassWizard menambahkan fungsi makro dan kerangka peta pesan berikut untuk Anda:
ON_WM_CTLCOLOR_REFLECT() // Note: other code will be in between.... HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here // TODO: Return a non-NULL brush if the // parent's handler should not be called return NULL; }
Ganti isi fungsi dengan kode berikut. Kode menentukan warna teks, warna latar belakang teks, dan warna latar belakang untuk kontrol lainnya.
pDC->SetTextColor(m_clrText); // text pDC->SetBkColor(m_clrBkgnd); // text bkgnd return m_brBkgnd; // ctl bkgnd
Buat kontrol edit dalam kotak dialog Anda, lalu lampirkan ke variabel anggota dengan mengklik dua kali kontrol edit sambil menahan tombol kontrol. Dalam kotak dialog Tambahkan Variabel Anggota, selesaikan nama variabel dan pilih "Kontrol" untuk kategori, lalu "CYellowEdit" untuk jenis variabel. Jangan lupa untuk mengatur urutan tab dalam kotak dialog. Selain itu, pastikan untuk menyertakan file header untuk kontrol
CYellowEdit
di dalam file header kotak dialog Anda.Buat dan jalankan aplikasi Anda. Kontrol edit akan memiliki latar belakang kuning.
Lihat juga
Catatan Teknis berdasarkan Angka
Catatan Teknis menurut kategori