Tentang Prosedur Jendela
Setiap jendela adalah anggota kelas jendela tertentu. Kelas jendela menentukan prosedur jendela default yang digunakan jendela individual untuk memproses pesannya. Semua jendela milik kelas yang sama menggunakan prosedur jendela default yang sama. Misalnya, sistem menentukan prosedur jendela untuk kelas kotak kombo (COMBOBOX); semua kotak kombo kemudian menggunakan prosedur jendela tersebut.
Aplikasi biasanya mendaftarkan setidaknya satu kelas jendela baru dan prosedur jendela terkait. Setelah mendaftarkan kelas, aplikasi dapat membuat banyak jendela kelas tersebut, yang semuanya menggunakan prosedur jendela yang sama. Karena ini berarti beberapa sumber dapat secara bersamaan memanggil bagian kode yang sama, Anda harus berhati-hati saat memodifikasi sumber daya bersama dari prosedur jendela. Untuk informasi selengkapnya, lihat Kelas Jendela.
Prosedur jendela untuk kotak dialog (disebut prosedur kotak dialog) memiliki struktur dan fungsi yang sama seperti prosedur jendela reguler. Semua poin yang mengacu pada prosedur jendela di bagian ini juga berlaku untuk prosedur kotak dialog. Untuk informasi selengkapnya, lihat Kotak Dialog.
Bagian ini membahas topik berikut.
- Struktur Prosedur Jendela
- Prosedur Jendela Default
- Subkelas Prosedur Jendela
- Superclassing Prosedur Jendela
Struktur Prosedur Jendela
Prosedur jendela adalah fungsi yang memiliki empat parameter dan mengembalikan nilai yang ditandatangani. Parameter terdiri dari handel jendela, pengidentifikasi pesan UINT , dan dua parameter pesan yang dideklarasikan dengan jenis data WPARAM dan LPARAM . Untuk informasi selengkapnya, lihat WindowProc.
Parameter pesan sering berisi informasi dalam kata-kata berurutan rendah dan berurutan tinggi. Ada beberapa makro yang dapat digunakan aplikasi untuk mengekstrak informasi dari parameter pesan. Makro LOWORD , misalnya, mengekstrak kata urutan rendah (bit 0 hingga 15) dari parameter pesan. Makro lainnya termasuk makro HIWORD, LOBYTE, dan HIBYTE.
Interpretasi nilai pengembalian tergantung pada pesan tertentu. Lihat deskripsi setiap pesan untuk menentukan nilai pengembalian yang sesuai.
Karena dimungkinkan untuk memanggil prosedur jendela secara rekursif, penting untuk meminimalkan jumlah variabel lokal yang digunakannya. Saat memproses pesan individual, aplikasi harus memanggil fungsi di luar prosedur jendela untuk menghindari penggunaan variabel lokal yang berlebihan, mungkin menyebabkan tumpukan meluap selama rekursi mendalam.
Prosedur Jendela Default
Fungsi prosedur jendela default, DefWindowProc menentukan perilaku dasar tertentu yang dibagikan oleh semua jendela. Prosedur jendela default menyediakan fungsionalitas minimal untuk jendela. Prosedur jendela yang ditentukan aplikasi harus meneruskan pesan apa pun yang tidak diproses ke fungsi DefWindowProc untuk pemrosesan default.
Subkelas Prosedur Jendela
Saat aplikasi membuat jendela, sistem mengalokasikan blok memori untuk menyimpan informasi khusus untuk jendela, termasuk alamat prosedur jendela yang memproses pesan untuk jendela. Ketika sistem perlu meneruskan pesan ke jendela, sistem mencari informasi khusus jendela untuk alamat prosedur jendela dan meneruskan pesan ke prosedur tersebut.
Subkelas adalah teknik yang memungkinkan aplikasi untuk mencegat dan memproses pesan yang dikirim atau diposting ke jendela tertentu sebelum jendela memiliki kesempatan untuk memprosesnya. Dengan subkelas jendela, aplikasi dapat menambah, memodifikasi, atau memantau perilaku jendela. Aplikasi dapat mensubkelas jendela milik kelas global sistem, seperti kontrol edit atau kotak daftar. Misalnya, aplikasi dapat mensubkelas kontrol edit untuk mencegah kontrol menerima karakter tertentu. Namun, Anda tidak dapat mensubkelas jendela atau kelas milik aplikasi lain. Semua subkelas harus dilakukan dalam proses yang sama.
Aplikasi mensubkelas jendela dengan mengganti alamat prosedur jendela asli jendela dengan alamat prosedur jendela baru, yang disebut prosedur subkelas. Setelah itu, prosedur subkelas menerima pesan apa pun yang dikirim atau diposting ke jendela.
Prosedur subkelas dapat mengambil tiga tindakan saat menerima pesan: itu dapat meneruskan pesan ke prosedur jendela asli, mengubah pesan dan meneruskannya ke prosedur jendela asli, atau memproses pesan dan tidak meneruskannya ke prosedur jendela asli. Jika prosedur subkelas memproses pesan, itu dapat melakukannya sebelum, setelah, atau baik sebelum dan sesudahnya meneruskan pesan ke prosedur jendela asli.
Sistem ini menyediakan dua jenis subkelas: instans dan global. Dalam subkelas instans, aplikasi menggantikan alamat prosedur jendela dari satu instans jendela. Aplikasi harus menggunakan subkelas instans untuk subkelas jendela yang ada. Dalam subkelas global, aplikasi menggantikan alamat prosedur jendela dalam struktur WNDCLASSEX dari kelas jendela. Semua jendela berikutnya yang dibuat dengan kelas memiliki alamat prosedur subkelas, tetapi jendela kelas yang ada tidak terpengaruh.
Subkelas Instans
Aplikasi mensubkelas instans jendela dengan menggunakan fungsi SetWindowLongPtr. Aplikasi meneruskan bendera GWL_WNDPROC , handel ke jendela ke subkelas, dan alamat prosedur subkelas ke SetWindowLongPtr. Prosedur subkelas dapat berada di aplikasi yang dapat dieksekusi atau DLL.
Saat melewati bendera GWL_WNDPROC , SetWindowLongPtr mengembalikan alamat prosedur jendela asli jendela. Aplikasi harus menyimpan alamat ini, menggunakannya dalam panggilan berikutnya ke fungsi CallWindowProc , untuk meneruskan pesan yang disadap ke prosedur jendela asli. Aplikasi juga harus memiliki alamat prosedur jendela asli untuk menghapus subkelas dari jendela. Untuk menghapus subkelas, aplikasi memanggil SetWindowLongPtr lagi, meneruskan alamat prosedur jendela asli dengan bendera GWL_WNDPROC dan handel ke jendela.
Sistem memiliki kelas global sistem, dan aspek kontrol mungkin berubah dari satu versi sistem ke versi berikutnya. Jika aplikasi harus mensublasifikasikan jendela milik kelas global sistem, pengembang mungkin perlu memperbarui aplikasi saat versi baru sistem dirilis.
Karena subkelas instans terjadi setelah jendela dibuat, Anda tidak dapat menambahkan byte tambahan ke jendela. Aplikasi yang mensubkelas jendela harus menggunakan daftar properti jendela untuk menyimpan data apa pun yang diperlukan untuk instans jendela subkelas. Untuk informasi selengkapnya, lihat Properti Jendela.
Ketika aplikasi mensubkelas jendela subkelas, aplikasi harus menghapus subkelas dalam urutan terbalik yang dilakukan. Jika urutan penghapusan tidak dibalik, kesalahan sistem yang tidak dapat dipulihkan dapat terjadi.
Subkelas Global
Untuk subkelas kelas jendela secara global, aplikasi harus memiliki handel ke jendela kelas. Aplikasi ini juga memerlukan handel untuk menghapus subkelas. Untuk mendapatkan handel, aplikasi biasanya membuat jendela tersembunyi kelas yang akan disubkelas. Setelah mendapatkan handel, aplikasi memanggil fungsi SetClassLongPtr , menentukan handel, bendera GCL_WNDPROC , dan alamat prosedur subkelas. SetClassLongPtr mengembalikan alamat prosedur jendela asli untuk kelas .
Alamat prosedur jendela asli digunakan dalam subkelas global dengan cara yang sama seperti yang digunakan dalam subkelas instans. Prosedur subkelas meneruskan pesan ke prosedur jendela asli dengan memanggil CallWindowProc. Aplikasi menghapus subkelas dari kelas jendela dengan memanggil SetClassLongPtr lagi, menentukan alamat prosedur jendela asli, bendera GCL_WNDPROC, dan handel ke jendela kelas yang disubkelas. Aplikasi yang secara global mensubkelas kelas kontrol harus menghapus subkelas ketika aplikasi berakhir; jika tidak, kesalahan sistem yang tidak dapat dipulihkan dapat terjadi.
Subkelas global memiliki batasan yang sama dengan subkelas instans, ditambah beberapa batasan tambahan. Aplikasi tidak boleh menggunakan byte tambahan untuk kelas atau instans jendela tanpa mengetahui dengan tepat bagaimana prosedur jendela asli menggunakannya. Jika aplikasi harus mengaitkan data dengan jendela, aplikasi harus menggunakan properti jendela.
Superclassing Prosedur Jendela
Superclassing adalah teknik yang memungkinkan aplikasi untuk membuat kelas jendela baru dengan fungsionalitas dasar kelas yang ada, ditambah peningkatan yang disediakan oleh aplikasi. Superclass didasarkan pada kelas jendela yang ada yang disebut kelas dasar. Sering kali, kelas dasar adalah kelas jendela global sistem seperti kontrol edit, tetapi dapat berupa kelas jendela apa pun.
Superclass memiliki prosedur jendela sendiri, yang disebut prosedur superkelas. Prosedur superkelas dapat mengambil tiga tindakan saat menerima pesan: Ini dapat meneruskan pesan ke prosedur jendela asli, mengubah pesan dan meneruskannya ke prosedur jendela asli, atau memproses pesan dan tidak meneruskannya ke prosedur jendela asli. Jika prosedur superkelas memproses pesan, itu dapat melakukannya sebelum, setelah, atau baik sebelum dan sesudahnya meneruskan pesan ke prosedur jendela asli.
Tidak seperti prosedur subkelas, prosedur superkelas dapat memproses pesan pembuatan jendela (WM_NCCREATE, WM_CREATE, dan sebagainya), tetapi juga harus meneruskannya ke prosedur jendela kelas dasar asli sehingga prosedur jendela kelas dasar dapat melakukan prosedur inisialisasinya.
Untuk superclass kelas jendela, aplikasi pertama-tama memanggil fungsi GetClassInfoEx untuk mengambil informasi tentang kelas dasar. GetClassInfoEx mengisi struktur WNDCLASSEX dengan nilai dari struktur WNDCLASSEX kelas dasar. Selanjutnya, aplikasi menyalin handel instansnya sendiri ke anggota hInstance dari struktur WNDCLASSEX dan menyalin nama superkelas ke anggota lpszClassName . Jika kelas dasar memiliki menu, aplikasi harus menyediakan menu baru dengan pengidentifikasi menu yang sama dan menyalin nama menu ke anggota lpszMenuName . Jika prosedur superkelas memproses pesan WM_COMMAND dan tidak meneruskannya ke prosedur jendela kelas dasar, menu tidak perlu memiliki pengidentifikasi yang sesuai. GetClassInfoEx tidak mengembalikan anggota lpszMenuName, lpszClassName, atau hInstance dari struktur WNDCLASSEX .
Aplikasi juga harus mengatur anggota lpfnWndProc dari struktur WNDCLASSEX . Fungsi GetClassInfoEx mengisi anggota ini dengan alamat prosedur jendela asli untuk kelas . Aplikasi harus menyimpan alamat ini, untuk meneruskan pesan ke prosedur jendela asli, lalu menyalin alamat prosedur superkelas ke anggota lpfnWndProc . Aplikasi dapat, jika perlu, memodifikasi anggota lain dari struktur WNDCLASSEX . Setelah mengisi struktur WNDCLASSEX, aplikasi mendaftarkan superclass dengan meneruskan alamat struktur ke fungsi RegisterClassEx. Superclass kemudian dapat digunakan untuk membuat jendela.
Karena superclassing mendaftarkan kelas jendela baru, aplikasi dapat menambahkan ke byte kelas tambahan dan byte jendela tambahan. Superclass tidak boleh menggunakan byte tambahan asli untuk kelas dasar atau jendela karena alasan yang sama bahwa subkelas instans atau subkelas global tidak boleh menggunakannya. Selain itu, jika aplikasi menambahkan byte tambahan untuk penggunaannya ke kelas atau instans jendela, aplikasi harus mereferensikan byte tambahan relatif terhadap jumlah byte tambahan yang digunakan oleh kelas dasar asli. Karena jumlah byte yang digunakan oleh kelas dasar dapat bervariasi dari satu versi kelas dasar ke versi berikutnya, offset awal untuk byte tambahan superclass sendiri juga dapat bervariasi dari satu versi kelas dasar ke versi berikutnya.