TN014: Kontrol Kustom
Catatan ini menjelaskan Dukungan MFC untuk kontrol kustom dan gambar mandiri. Ini juga menjelaskan subkelas dinamis, dan menjelaskan hubungan antara objek CWnd dan HWND
s.
Aplikasi sampel MFC CTRLTEST menggambarkan cara menggunakan banyak kontrol kustom. Lihat kode sumber untuk sampel Umum MFC CTRLTEST dan bantuan online.
Windows menyediakan dukungan untuk kontrol dan menu gambar pemilik dengan menggunakan pesan Windows. Jendela induk kontrol atau menu apa pun menerima pesan dan fungsi panggilan ini sebagai respons. Anda dapat mengambil alih fungsi-fungsi ini untuk menyesuaikan tampilan visual dan perilaku kontrol atau menu gambar pemilik Anda.
MFC secara langsung mendukung gambar pemilik dengan fungsi berikut:
Anda dapat mengambil alih fungsi-fungsi ini di kelas turunan Anda CWnd
untuk menerapkan perilaku gambar kustom.
Pendekatan ini tidak menyebabkan kode yang dapat digunakan kembali. Jika Anda memiliki dua kontrol serupa di dua kelas yang berbeda CWnd
, Anda harus menerapkan perilaku kontrol kustom di dua lokasi. Arsitektur kontrol gambar mandiri yang didukung MFC memecahkan masalah ini.
MFC menyediakan implementasi default (di CWnd
kelas dan CMenu ) untuk pesan gambar pemilik standar. Implementasi default ini akan mendekode parameter gambar pemilik dan mendelegasikan pesan gambar pemilik ke kontrol atau menu. Ini disebut gambar mandiri karena kode gambar berada di kelas kontrol atau menu, bukan di jendela pemilik.
Dengan menggunakan kontrol gambar mandiri, Anda dapat membangun kelas kontrol yang dapat digunakan kembali yang menggunakan semantik gambar pemilik untuk menampilkan kontrol. Kode untuk menggambar kontrol ada di kelas kontrol, bukan induknya. Ini adalah pendekatan berorientasi objek untuk pemrograman kontrol kustom. Tambahkan daftar fungsi berikut ke kelas gambar mandiri Anda:
Untuk tombol gambar mandiri:
CButton:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw this button
Untuk menu gambar mandiri:
CMenu:MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this menu CMenu:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this menu
Untuk kotak daftar gambar mandiri:
CListBox:MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this list box CListBox:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this list box CListBox:CompareItem(LPCOMPAREITEMSTRUCT); // insert code to compare two items in this list box if LBS_SORT CListBox:DeleteItem(LPDELETEITEMSTRUCT); // insert code to delete an item from this list box
Untuk kotak kombo gambar mandiri:
CComboBox:MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this combo box CComboBox:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this combo box CComboBox:CompareItem(LPCOMPAREITEMSTRUCT); // insert code to compare two items in this combo box if CBS_SORT CComboBox:DeleteItem(LPDELETEITEMSTRUCT); // insert code to delete an item from this combo box
Untuk detail tentang struktur gambar pemilik (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT, dan DELETEITEMSTRUCT) lihat dokumentasi MFC untuk CWnd::OnDrawItem
, , CWnd::OnCompareItem
CWnd::OnMeasureItem
, dan CWnd::OnDeleteItem
masing-masing.
Untuk menu gambar mandiri, Anda harus mengambil alih OnMeasureItem
metode dan OnDrawItem
.
Untuk kotak daftar gambar mandiri dan kotak kombo, Anda harus mengambil OnMeasureItem
alih dan OnDrawItem
. Anda harus menentukan gaya LBS_OWNERDRAWVARIABLE untuk kotak daftar atau gaya CBS_OWNERDRAWVARIABLE untuk kotak kombo dalam templat dialog. Gaya OWNERDRAWFIXED tidak akan berfungsi dengan item gambar mandiri karena tinggi item tetap ditentukan sebelum kontrol gambar mandiri dilampirkan ke kotak daftar. (Anda dapat menggunakan metode CListBox::SetItemHeight dan CComboBox::SetItemHeight untuk mengatasi batasan ini.)
Beralih ke gaya OWNERDRAWVARIABLE akan memaksa sistem untuk menerapkan gaya NOINTEGRALHEIGHT ke kontrol. Karena kontrol tidak dapat menghitung tinggi integral dengan item berukuran variabel, gaya default INTEGRALHEIGHT diabaikan dan kontrol selalu NOINTEGRALHEIGHT. Jika item Anda tinggi tetap, Anda dapat mencegah item parsial digambar dengan menentukan ukuran kontrol menjadi pengali bilangan bulat dari ukuran item.
Untuk kotak daftar gambar mandiri dan kotak kombo dengan gaya LBS_SORT atau CBS_SORT, Anda harus mengambil alih OnCompareItem
metode .
Untuk kotak daftar gambar mandiri dan kotak kombo, OnDeleteItem
biasanya tidak ditimpa. Anda dapat mengambil alih OnDeleteItem
jika Anda ingin melakukan pemrosesan khusus. Satu kasus di mana ini akan berlaku adalah ketika memori tambahan atau sumber daya lain disimpan dengan setiap kotak daftar atau item kotak kombo.
Sampel Umum MFC CTRLTEST menyediakan sampel menu gambar mandiri dan kotak daftar gambar mandiri.
Contoh paling umum dari tombol menggambar sendiri adalah tombol bitmap. Tombol bitmap adalah tombol yang menunjukkan satu, dua, atau tiga gambar bitmap untuk berbagai status. Contoh ini disediakan di kelas MFC CBitmapButton.
Terkadang Anda ingin mengubah fungsionalitas objek yang sudah ada. Contoh sebelumnya mengharuskan Anda menyesuaikan kontrol sebelum dibuat. Subkelas dinamis memungkinkan Anda menyesuaikan kontrol yang telah dibuat.
Subkelas adalah istilah Windows untuk mengganti WndProc jendela dengan yang disesuaikan WndProc
dan memanggil yang lama WndProc
untuk fungsionalitas default.
Ini tidak boleh dikacaukan dengan turunan kelas C++. Untuk klarifikasi, kelas dasar istilah C++ dan kelas turunan dianalogikan dengan superkelas dan subkelas dalam model objek Windows. Derivasi C++ dengan subkelas MFC dan Windows secara fungsional mirip, kecuali C++ tidak mendukung subkelas dinamis.
Kelas CWnd
menyediakan koneksi antara objek C++ (berasal dari CWnd
) dan objek jendela Windows (dikenal sebagai HWND
).
Ada tiga cara umum ini terkait:
CWnd
HWND
membuat . Anda dapat memodifikasi perilaku di kelas turunan dengan membuat kelas yang berasal dariCWnd
.HWND
dibuat saat aplikasi Anda memanggil CWnd::Create.Aplikasi melampirkan
CWnd
keHWND
. Perilaku jendela yang ada tidak dimodifikasi. Ini adalah kasus delegasi dan dimungkinkan dengan memanggil CWnd::Lampirkan ke alias yang adaHWND
keCWnd
objek.CWnd
dilampirkan ke yang sudah adaHWND
dan Anda dapat memodifikasi perilaku di kelas turunan. Ini disebut subkelas dinamis karena kami mengubah perilaku, dan oleh karena itu kelas, objek Windows pada waktu proses.
Anda dapat mencapai subkelas dinamis dengan menggunakan metode CWnd::SubclassWindow danCWnd::SubclassDlgItem.
Kedua rutinitas melampirkan CWnd
objek ke HWND
. SubclassWindow
mengambil secara HWND
langsung. SubclassDlgItem
adalah fungsi pembantu yang mengambil ID kontrol dan jendela induk. SubclassDlgItem
dirancang untuk melampirkan objek C++ ke kontrol dialog yang dibuat dari templat dialog.
Lihat contoh CTRLTEST untuk beberapa contoh kapan harus menggunakan SubclassWindow
dan SubclassDlgItem
.
Catatan Teknis menurut Angka
Catatan Teknis menurut Kategori