Bagikan melalui


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 gunakan 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 pada Jendela

Prosedur jendela adalah fungsi yang memiliki empat parameter dan mengembalikan nilai yang ditandatangani. Parameter terdiri dari handle jendela, sebuah 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. MakroLOWORD, misalnya, mengekstrak kata urutan rendah (bit 0 hingga 15) dari parameter pesan. Makro lainnya termasuk HIWORD, LOBYTE, dan makro 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 Bawaan

Fungsi prosedur jendela default, DefWindowProc menentukan perilaku mendasar 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.

Penurunan Kelas 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 tersebut 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 dilaksanakan 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 subclass 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, dapat melakukannya sebelum, sesudah, atau baik sebelum maupun sesudah meneruskan pesan ke prosedur jendela asli.

Sistem ini menyediakan dua jenis subkelas: instans dan global. Dalam instans subkelas , aplikasi mengganti alamat prosedur jendela dari satu instans jendela. Aplikasi harus menerapkan subkelas instans untuk menyubkelas window yang ada. Dalam subkelas global, aplikasi menggantikan alamat prosedur jendela dalam WNDCLASSEX struktur dari kelas jendela. Semua jendela baru yang dibuat dengan kelas ini memiliki alamat prosedur subkelas, tetapi jendela yang sudah ada dari kelas tersebut tidak terpengaruh.

Penciptaan Subkelas dari Instans

Aplikasi mensubkelas instans jendela dengan menggunakan fungsiSetWindowLongPtr. Aplikasi meneruskan bendera GWL_WNDPROC, handle ke jendela untuk subclass, dan alamat prosedur subclass untuk SetWindowLongPtr. Prosedur subkelas dapat berada di aplikasi yang dapat dieksekusi atau DLL.

Ketika menerima bendera GWL_WNDPROC, SetWindowLongPtr mengembalikan alamat prosedur asli jendela tersebut. Aplikasi harus menyimpan alamat ini, menggunakannya dalam panggilan berikutnya ke fungsiCallWindowProc, 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 flag GWL_WNDPROC dan handle 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 bisa lagi menambahkan byte tambahan ke jendela tersebut. Aplikasi yang mensubkelas jendela harus menggunakan daftar properti jendela untuk menyimpan data apa pun yang diperlukan untuk instans jendela subkelas. Untuk informasi lebih lanjut, lihat Properti Jendela.

Ketika aplikasi membuat subclass dari jendela yang sudah memiliki subclass, aplikasi harus menghapus subclass tersebut dalam urutan terbalik dari urutan saat penurunan subclass tersebut dilakukan. Jika urutan penghapusan tidak dibalik, kesalahan sistem yang tidak dapat dipulihkan dapat terjadi.

Subkelas Global

Untuk melakukan subclass secara global pada kelas jendela, aplikasi harus memiliki pegangan untuk sebuah jendela dari kelas tersebut. Aplikasi ini juga memerlukan pegangan untuk menghilangkan subkelas. Untuk mendapatkan penunjuk, aplikasi biasanya membuat jendela tersembunyi dari kelas yang menjadi subkelas. Setelah mendapatkan handle, aplikasi memanggil fungsi SetClassLongPtr, menentukan handle, 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, dengan menentukan alamat prosedur jendela asli, flag GCL_WNDPROC, dan handle 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 (Ekstensi) Prosedur Jendela

Superclassing adalah teknik yang memungkinkan aplikasi 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.

Kelas induk memiliki prosedur jendela sendiri yang disebut prosedur kelas induk. Prosedur superclass 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, prosedur tersebut dapat melakukannya sebelum, sesudah, atau baik sebelum maupun sesudah 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 menggunakan superclass pada 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 handle instansnya sendiri ke dalam anggota hInstance dari struktur WNDCLASSEX dan menyalin nama superclass 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 lpszMenuName, lpszClassName, atau hInstance anggota struktur WNDCLASSEX.

Aplikasi harus juga mengatur anggota lpfnWndProc dari struktur WNDCLASSEX. fungsi GetClassInfoEx melengkapi anggota ini dengan alamat dari prosedur jendela asli untuk kelas. Aplikasi harus menyimpan alamat ini untuk meneruskan pesan ke prosedur jendela asli, dan kemudian menyalin alamat prosedur superkelas ke anggota lpfnWndProc. Aplikasi ini dapat, jika perlu, memodifikasi anggota lain dari struktur WNDCLASSEX. Setelah mengisi struktur WNDCLASSEX, aplikasi mendaftarkan superkelas dengan meneruskan alamat struktur ke fungsiRegisterClassEx. Superclass kemudian dapat digunakan untuk membuat jendela.

Karena superclassing mendaftarkan kelas jendela baru, aplikasi dapat menambahkan byte tambahan ke kelas dan jendela. 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.