Membuat komponen di DELPHI. Pengantar Membuat Komponen Delphi

Sebelum membuat komponen, Anda perlu memilih leluhurnya. Siapa yang bisa menjadi nenek moyang komponen Anda?

Biasanya digunakan sebagai nenek moyang TComponent, TControl, TWinControl, TGraphicControl, TCustomXXXXXX, serta semua komponen palet komponen.
Mari kita ambil contoh komponen TOpenDialog, yang terletak di halaman Dialogs pada palet komponen. Ia melakukan tugasnya dengan baik, tetapi ada satu ketidaknyamanan kecil. Setiap kali Anda menggunakannya, Anda harus mengubah nilai properti Opsi setiap kali. Dan, biasanya, ini adalah tindakan yang sama.
OpenDialog1.Options:= OpenDialog1.Options + ;

sehingga file yang kita coba buka dengan dialog ini benar-benar ada di disk.
Kami telah memilih tugas untuk diri kami sendiri, yang tersisa hanyalah membuat komponen. Kita membuat blank untuk komponen dengan memilih perintah Component/New Component... dari menu dan memilih di kotak dialog
Tipe leluhur: TOpenDialog
Nama Kelas: TOurOpenDialog
Halaman Palet: Pengujian Kami
Kami mengklik Ok dan sekarang kami memiliki template untuk komponen masa depan kami.

Kami mengganti konstruktor untuk komponen ini, mis. di bagian publik masukkan baris:

Buat konstruktor(Pemilik: TComponent); mengesampingkan;

Mengklik baris ini Ctrl + Shift + C membuat template untuk metode ini, di dalamnya kita menyisipkan baris berikut:

Warisan Buat(Pemilik); (Panggil konstruktor yang diwarisi)
Pilihan:= Pilihan + ; (Kami melakukan tindakan yang kami perlukan)

Harap diperhatikan: Pintasan keyboard Ctrl + Shift + panah atas/bawah memungkinkan Anda menavigasi antara deklarasi metode dan implementasinya.

Menginstal Komponen komponen yang dibuat/Instal Komponen...
Instal Ke Paket Baru
Nama file paket: C:Program FilesBorlandDelphi4LibOurTest.dpk
Deskripsi paket: Paket kami yang telah diuji

Tidakkah Anda suka bahwa komponen kita memiliki ikon yang sama dengan komponen standar? Kalau begitu mari kita buat sendiri untuknya.
Untuk melakukan ini kita perlu memanggil Tools/Image Editor. Buat file *.dcr baru.
Masukkan gambar Resource/Baru/Bitmap ke dalamnya. Atur ukuran gambar menjadi 24x24 piksel. Dan kemudian - kreativitas Anda...
Mohon diperhatikan: warna titik yang sesuai dengan warna titik di pojok kiri bawah gambar akan dianggap TRANSPARAN!
Setelah Anda membuat gambar, ganti namanya dari Bitmap1 menjadi TOurOpenDialog dan simpan file sebagai OurOpenDialog.dcr.
Hapus komponen dari paket dan instal kembali (hanya dalam kasus ini tautan ke file *.dcr akan ditambahkan).
Kompilasi, Instal dan semoga berhasil!

satuan Dialog Terbuka Kami; antarmuka kegunaan Windows, Pesan, SysUtils, Kelas, Grafik, Kontrol, Formulir, Dialog; jenis TOUROpenDialog = kelas(TERbukaDialog) pribadi(Deklarasi pribadi) terlindung publik(Deklarasi publik) konstruktor Buat(Pemilik: TComponent); mengesampingkan; diterbitkan akhir; prosedur daftar; penerapan prosedur daftar; mulai RegisterComponents("Sampel", ); akhir; (Dialog Terbuka Kami) konstruktor TOurOpenDialog.Create(Pemilik: TComponent); mulai diwariskan Buat(Pemilik); (Panggil konstruktor yang diwarisi) Opsi:= Opsi + ; (Kami melakukan tindakan yang kami perlukan) akhir; akhir.

Deklarasi komponen terdiri dari bagian-bagian seperti pribadi, dilindungi, publik dan dipublikasikan. Apa yang mereka maksud?
Ini adalah arahan visibilitas.
Segala sesuatu yang dinyatakan di bagian tersebut pribadi, hanya tersedia di dalam modul tempat kelas dideklarasikan (deklarasi pribadi). Di sini, sebagai aturan, variabel yang menyimpan nilai properti, serta metode (prosedur atau fungsi) untuk mengaksesnya, dideklarasikan.
Segala sesuatu yang dinyatakan di bagian tersebut terlindung, tersedia seperti di bagian pribadi, serta turunan dari kelas ini (antarmuka pengembang).
Di sini Anda dapat mendeklarasikan metode untuk mengakses nilai properti (jika Anda ingin mengizinkan turunan komponen Anda mengubah metode ini),
serta properti, metode, dan peristiwa (metode untuk bereaksi terhadap peristiwa) dalam komponen bertipe TCustomXXX.
Segala sesuatu yang dinyatakan di bagian tersebut publik, tersedia untuk semua pengguna komponen (antarmuka runtime).
Metode biasanya dideklarasikan di sini. Hanya properti dan peristiwa yang dapat dideklarasikan di bagian yang diterbitkan (dinyatakan sebagai properti).
Mereka tersedia selama desain aplikasi (tahap desain antarmuka).

Properti

Ketik properti besar-besaran- array Object Pascal biasa, tetapi tidak seperti yang terakhir, array tersebut dapat diindeks tidak hanya dengan nilai numerik tetapi juga dengan nilai string. Sayangnya, jenis properti ini memerlukan editor properti khusus (di Object Inspector, editor properti memiliki tombol dengan tiga titik [...]), jadi pada contoh di bawah properti ArrayProp diumumkan di bagian publik.

jenis Komponen Kami = kelas(Komponen T) pribadi(Deklarasi pribadi) FArrayProp: Himpunan dari bilangan bulat; fungsi GetArrayProp(aIndex: bilangan bulat): bilangan bulat; prosedur SetArrayProp(aIndeks: bilangan bulat; konstanta Nilai: bilangan bulat); terlindung(Deklarasi yang dilindungi) publik(Deklarasi publik) Properti ArrayProp: bilangan bulat membaca DapatkanArrayProp menulis SetArrayProp; diterbitkan(Deklarasi yang diterbitkan) akhir;

Penentu properti

Penentu bawaan menentukan apakah akan menyimpan nilai properti dalam file formulir atau tidak. Jika nilai properti sesuai dengan nilainya bawaan- nilai dalam file formulir tidak disimpan, jika nilainya tidak sama - disimpan. Anda dapat memeriksanya dengan menempatkan komponen pada formulir dan memilih item menu "Lihat sebagai Teks" dengan tombol kanan mouse. Bawaan tidak menetapkan nilai awal properti ke nilai yang ditentukan. Ini harus dilakukan di konstruktor komponen.

satuan Komponen Kami; antarmuka kegunaan Windows, SysUtils, Kelas, Grafik, Formulir, Kontrol; jenis Komponen Kami = kelas(Komponen T) pribadi( Deklarasi pribadi ) FMyInteger: Integer; terlindung(Deklarasi yang dilindungi) publik(Deklarasi publik) konstruktor Buat(Pemilik: TComponent); mengesampingkan; diterbitkan(Deklarasi yang diterbitkan) Properti Bilangan Bulat Saya: Bilangan Bulat membaca FMSayaInteger menulis FMSayaInteger bawaan 10; akhir; penerapan konstruktor TOurComponent.Create(Pemilik: TComponent); mulai diwariskan Buat(Pemilik); Bilangan bulat:= 10; akhir; akhir.

Penentu kesalahan simpul menimpa nilai properti default. Penentu ini biasanya digunakan untuk mengganti nilai default properti yang diwarisi.
Misalnya: Properti Ukuran Otomatis kesalahan simpul;

Penentu disimpan menentukan kapan harus menyimpan nilai properti dalam file formulir. Setelah disimpan bisa berdiri BENAR(selalu simpan) PALSU(jangan pernah menyimpan) atau nama fungsi yang mengembalikan hasil Boolean.

Properti OneProp: bilangan bulat membaca FOneProp menulis SetOneProp disimpan PALSU; Properti TwoProp: bilangan bulat membaca FTwoProp menulis SetDuaProp disimpan BENAR; Properti ThreeProp: bilangan bulat membaca FTigaProp menulis SetTiga Prop disimpan Benar;

Dan hal terakhir:
Untuk menambahkan gambar ke komponen untuk demonstrasi di panel komponen, Anda perlu: - membuatnya dengan ukuran 24*24 dengan nama file.dcr (di resource, nama gambar sama dengan nama komponennya, dengan huruf kapital)
- letakkan gambar di sebelah komponen.

Perkembangan perangkat lunak untuk OS Windows dan populer lainnya dapat dilakukan dengan menggunakan berbagai jenis alat. Di antara yang sangat populer di kalangan programmer Rusia dan asing adalah program Delphi. Apa spesifik dari alat pengembangan ini? Apa saja fitur-fiturnya yang paling menonjol?

Informasi umum tentang Delphi

Delphi adalah lingkungan pengembangan untuk program aplikasi yang dirancang untuk berjalan di Windows, MacOS, dan perangkat seluler. sistem operasi- iOS dan Android. Hal ini ditandai dengan kesederhanaan bahasa dan prosedur pembuatan kode.

Jika perlu, menyediakan komunikasi tingkat rendah dengan OS dan perpustakaan yang ditulis dalam C dan C++. Program yang dibuat menggunakan Delphi tidak memerlukan shell pihak ketiga untuk dijalankan, seperti Java Virtual Machine. Delphi adalah lingkungan pengembangan yang dapat berhasil digunakan baik oleh para profesional maupun untuk tujuan pendidikan. Untuk menguasai kemampuan dasarnya, tidak perlu memiliki kualifikasi tinggi dan pengetahuan bahasa pemrograman yang kompleks.

Keuntungan utama

Mari kita pelajari apa saja keunggulan utama produk perangkat lunak yang dimaksud. Ketika perusahaan IT tertentu membenarkan pilihan lingkungan pengembangan, Delphi menjadi pilihan banyak programmer dan direkomendasikan oleh mereka untuk digunakan. Hal ini disebabkan oleh fakta bahwa lingkungan ini memungkinkan Anda membuat aplikasi dalam waktu secepat mungkin, memastikan kinerja tinggi bahkan pada komputer yang memiliki karakteristik perangkat keras sederhana. Argumen penting yang mendukung pemilihan lingkungan pengembangan yang dimaksud adalah bahwa lingkungan pengembangan tersebut dapat dilengkapi dengan alat-alat baru yang tidak disediakan oleh kumpulan solusi standar yang ada di antarmuka Delphi.

Sekarang mari kita pelajari nuansa penggunaan praktis kemampuan Delphi.

Spesifik antarmuka

Pertama-tama, Anda dapat memperhatikan beberapa fitur antarmuka lingkungan pengembangan perangkat lunak yang dimaksud. Dengan demikian, struktur ruang kerja program melibatkan kerja simultan dengan beberapa jendela utama. Mari kita pertimbangkan properti ini lebih detail.

Lingkungan pengembangan Delphi, khususnya versi 7, melibatkan penggunaan modul utama berikut: perancang formulir, editor, palet, pemeriksa objek, dan buku referensi. Dalam beberapa modifikasi Delphi, komponen yang ditandai mungkin diberi nama berbeda. Misalnya, editor mungkin berhubungan dengan jendela kode program, dan seorang desainer mungkin berhubungan dengan jendela formulir. Namun tujuan fungsional milik mereka akan sama. Delphi yang ditandai dapat melengkapi berbagai alat bantu. Dua yang pertama dianggap yang utama dari sudut pandang prosedur pengembangan program. Tapi sisanya juga penting. Mari kita lihat fitur penggunaan modul Delphi yang ditandai.

Perancang formulir, editor, dan palet

Dengan bantuan perancang formulir, pengembang membuat antarmuka programnya. Pada gilirannya, kodenya ditulis di editor. Banyak programmer yang merekomendasikan memilih lingkungan pengembangan Delphi sebagai solusi paling optimal, mengutip kemudahan penggunaan perancang formulir sebagai argumen. Beberapa ahli percaya bahwa proses ini lebih seperti sebuah permainan.

Segera setelah pengguna mulai membuat program dan meluncurkan perancang formulir, awalnya tidak ada elemen di dalamnya, itu kosong. Tapi Anda bisa langsung mengisinya menggunakan alat yang terletak di modul Delphi lain - palet. Elemen antarmuka program yang dikonfigurasi dalam perancang formulir harus dikontrol oleh perintah, yang selanjutnya ditulis di editor.

Tapi mari kita kembali ke palet untuk saat ini. Dengan menggunakannya, Anda dapat menempatkan objek yang diperlukan di area desainer formulir. Untuk menggunakan alat tertentu, Anda harus mengkliknya sekali - saat berada di area palet, dan kedua kalinya - di jendela perancang formulir. Setelah ini, objek terkait akan dipindahkan ke area pengembangan, dan Anda dapat menulis kode untuk objek tersebut di editor.

Inspektur Objek

Elemen penting lainnya yang terkandung dalam Delphi, lingkungan pengembangan aplikasi untuk Windows dan platform umum lainnya adalah pemeriksa objek. Anda mungkin memperhatikan bahwa informasi yang ditampilkan di dalamnya berubah: ini dipengaruhi oleh status objek yang dipilih di area perancang formulir.

Struktur pemeriksa objek adalah sebagai berikut. Terdiri dari dua jendela. Masing-masing berisi algoritma yang menentukan perilaku komponen terkait. Yang pertama menampilkan properti, yang kedua menampilkan acara. Jika pemrogram ingin melakukan penyesuaian terhadap algoritma yang mempengaruhi komponen tertentu, maka kemampuan pemeriksa objek digunakan. Misalnya, Anda dapat mengubah posisi elemen antarmuka program tertentu, tinggi dan lebarnya.

Object Inspector memiliki tab yang memungkinkan Anda beralih antar halaman yang menampilkan properti atau peristiwa yang berhubungan langsung dengan editor. Jadi, jika Anda mengklik dua kali di sisi kanan salah satu item yang ditampilkan di layar, kode yang terkait dengan peristiwa tertentu akan dicatat di editor.

Pengembangan perangkat lunak di Delphi melibatkan penggunaan Object Inspector untuk memecahkan berbagai masalah. Hal ini ditentukan oleh fakta bahwa dengan bantuan alat ini Anda dapat mengubah properti hampir semua objek yang terletak di formulir, serta formulir itu sendiri. Mari kita lihat lebih dekat beberapa fitur bekerja dengan pemeriksa objek.

Inspektur Objek: Menggunakan Fitur

Untuk memahami bagaimana fungsi Delphi IDE dalam hal interaksi antara Object Inspector dan Form Inspector, Anda dapat mencoba membuat perubahan pada properti beberapa elemen antarmuka perangkat lunak umum di Windows - misalnya, Memo, Button dan Listbox (kami akan jelajahi esensinya secara lebih rinci nanti). Pertama, Anda perlu menempatkannya pada formulir menggunakan alat Delphi yang tersedia.

Anda dapat mencoba bereksperimen dengan properti Ctl3D. Untuk melakukan ini, Anda perlu mengklik formulir, lalu pergi ke pemeriksa objek dan mengubah nilai properti yang dimaksud. Setelah ini, bentuk akan berubah secara signifikan, dan pada saat yang sama, properti Ctl3D akan diubah pada setiap elemen yang ditempatkan di jendela desain.

Setelah percobaan dilakukan, kita dapat kembali ke form dan mengaktifkan nilai Ctl3D. Setelah itu mari kita lihat elemen Memo dan Listbox. Sekarang Anda dapat mengubah properti, lokasi pada formulir, dan tampilannya. Misalnya, dengan memilih opsi Edit di item menu lalu Ukuran, pemrogram dapat mengubah lebar dan tinggi objek. Ada pilihan untuk memusatkannya dengan memilih Edit dan Align. Tindakan terkait akan mempengaruhi elemen yang ditampilkan di Object Inspector.

Dengan menggunakan modul Delphi yang dimaksud, Anda dapat mengubah properti komponen. Jadi, misalnya, jika tugasnya adalah menentukan warna tertentu, maka ada opsi untuk menggunakan beberapa alat sekaligus. Pertama, Anda dapat memasukkan perintah yang sesuai dengan warna - misalnya, merah - clRed - ke dalam area. Kedua, pengguna dapat memilih warna yang diinginkan dari daftar. Ketiga, ada opsi untuk mengklik dua kali pada properti Warna - jendela pemilihan warna akan muncul. Demikian pula, pengembang dapat mengubah atribut objek lainnya - misalnya, jenis font, warna, atau ukurannya.

Direktori

Delphi merupakan lingkungan pengembangan yang dilengkapi dengan sistem bantuan yang cukup detail. Untuk mengaksesnya, pilih Bantuan dari menu. Setelah ini, salah satu yang kami catat di atas akan ditampilkan di jendela. modul perangkat lunak lingkungan pengembangan yang dimaksud - buku referensi. Keunikan penggunaannya adalah ketika Anda menekan F1, pengguna akan menerima petunjuk khusus yang mencerminkan spesifikasi penggunaan alat saat ini. Misalnya, jika seorang programmer bekerja dengan Object Inspector, dia dapat memilih salah satu properti, lalu tekan F1 dan dapatkan informasi bantuan tentang opsi yang sesuai. Hal yang sama dapat dilakukan ketika bekerja dengan elemen antarmuka lain yang menyertakan lingkungan pengembangan Delphi 7 dan versi lain dari jenis perangkat lunak yang sesuai.

Elemen antarmuka lainnya

Di antara komponen penting lainnya dari antarmuka yang dimaksud solusi perangkat lunak- menu, panel akses cepat, serta editor gambar. Mengenai menu, ini memungkinkan programmer untuk dengan cepat mengakses komponen-komponen penting yang ada dalam struktur lingkungan pengembangan. Anda dapat menggunakannya menggunakan mouse atau menggunakan tombol pintas. Tepat di bawah menu adalah panel akses cepat. Beberapa fungsinya menduplikasi fungsi menu, namun lebih cepat diakses. Delphi agak mirip dengan program Paint di Windows. Artinya, dengan bantuannya Anda dapat membuat penyesuaian sederhana pada gambar, memberi prasasti dan elemen lainnya pada gambar tersebut.

Alat Pemrograman

Delphi adalah lingkungan pengembangan yang mencakup sejumlah besar alat yang dirancang untuk meningkatkan produktivitas pemrogram. Oleh karena itu, modul-modul utama yang kita bahas di atas dilengkapi dengan seperangkat alat khusus. Ini termasuk debugger, kompiler, serta komponen WinSight dan WinSpector. Perhatikan bahwa di beberapa versi Delphi, elemen yang ditandai harus diinstal secara terpisah. Mari kita pelajari secara spesifik.

Debugger Delphi

Mengenai debugger, alat ini melengkapi editor kode dalam hal melakukan pemeriksaan yang diperlukan terhadap algoritma perangkat lunak terkait untuk mengetahui kebenarannya. Dengan itu, pengembang sebenarnya dapat memeriksa kode sumbernya baris demi baris. Dalam beberapa kasus, ketika menyelesaikan tugas seperti pengembangan komponen, Delphi sebagai produk independen dapat dilengkapi dengan debugger eksternal, yang memberikan kemampuan yang ditingkatkan kepada pemrogram untuk memeriksa kode perangkat lunak yang sedang dibuat.

Kompiler Delphi

Sekarang mari kita pelajari secara spesifik kompiler lingkungan pengembangan yang dimaksud. Perhatikan bahwa mungkin ada beberapa elemen yang sesuai dalam struktur Delphi. Jadi, ada opsi untuk menggunakan kompiler DCC, yang berguna jika tugasnya adalah bekerja dengan aplikasi di debugger eksternal.

Winsight dan WinSpector

Modul yang ditentukan adalah modul yang perlu diinstal tambahan di Delphi. Mereka dicirikan oleh kesulitan relatif dalam penguasaan. Namun, banyak pemrogram yang memilih lingkungan pengembangan Delphi percaya bahwa komponen ini harus dipelajari untuk digunakan. Jadi, modul Winsight digunakan untuk memantau pesan Windows. Komponen seperti WinSpector diperlukan untuk mencatat keadaan komputer dalam file khusus. Jika Anda mengalami masalah selama pengembangan perangkat lunak, Anda selalu dapat membuka file ini dan melihat apa yang menyebabkan masalah tersebut.

Komponen Standar

Lingkungan pengembangan Delphi, yang kita pelajari secara umum, mencakup sejumlah komponen standar yang juga berguna untuk diketahui. Para ahli mengklasifikasikannya sebagai: MainMenu, PopupMenu, Label, Edit, Memo, Button, Checkbox, Radiobutton, Listbox, Combobox, Scrollbar, Groupbox, Panel, dan Scrollbox. Mari pelajari secara spesifik lebih detail.

Komponen MainMenu dirancang untuk menempatkan menu utama pada antarmuka program yang dibuat. Untuk melakukan ini, Anda perlu menempatkan elemen yang sesuai pada formulir, lalu memanggil properti Items melalui pemeriksa objek, dan kemudian menentukan item menu yang diperlukan.

Komponen PopupMenu dirancang untuk menempatkan menu pop-up di antarmuka program yang dibuat, yaitu menu yang dibuka dengan mengklik kanan mouse.

Komponen Label digunakan untuk menampilkan teks di jendela program. Itu dapat dikustomisasi, misalnya, mengatur font yang diinginkan di inspektur objek.

Komponen Edit digunakan untuk menampilkan sepotong teks di layar yang dapat diedit pengguna saat program sedang berjalan. Ini dilengkapi dengan komponen Memo, yang selanjutnya dapat digunakan untuk bekerja dengan teks yang lebih besar. Elemen ini mencakup, misalnya, opsi seperti menyalin teks.

Komponen Button dirancang untuk melakukan tindakan tertentu dengan menekan tombol saat program sedang berjalan. Penting untuk menempatkan elemen yang sesuai pada formulir, dan kemudian memasukkan kode program yang diperlukan.

Komponen Kotak Centang memungkinkan Anda menampilkan garis di layar dengan jendela kecil di mana kotak centang dapat ditempatkan menggunakan mouse. Elemen serupa adalah Radiobutton. Mereka berbeda, pertama, penampilan- komponen kedua dibuat dalam bentuk lingkaran, dan kedua, elemen pertama memungkinkan pemilihan beberapa opsi secara bersamaan, Radiobutton - hanya satu.

Komponen Listbox digunakan untuk menampilkan daftar di layar yang dapat digulir pengguna menggunakan mouse. Elemen lainnya, Combobox, agak mirip dengannya, tetapi dilengkapi dengan kemampuan memasukkan teks dalam bidang khusus.

Komponen Scrollbar adalah scroll bar di windows. Biasanya muncul secara otomatis segera setelah ruang teks atau bentuk dengan objek menjadi lebih besar dari jendela.

Komponen Groupbox digunakan untuk mencatat urutan perpindahan antar jendela saat Anda menekan tombol TAB. Dapat dilengkapi dengan elemen Panel yang dapat digunakan untuk memindahkan beberapa objek pada form.

Komponen Scrollbox memungkinkan Anda memperbaiki area pada formulir yang dapat digulir secara horizontal dan vertikal. Properti ini mencirikan jendela pengembangan Delphi utama secara default. Namun jika ada kebutuhan untuk mengaktifkan opsi seperti itu pada bagian formulir tertentu, Anda dapat menggunakan komponen Scrollbox.

Ringkasan

Delphi adalah lingkungan pengembangan aplikasi yang kuat yang pada saat yang sama ditandai dengan kemudahan penggunaan fungsi intinya. Dengan bantuan alat yang disertakan dalam strukturnya, Anda dapat berkreasi semaksimal mungkin jenis yang berbeda program untuk Windows dan sistem operasi populer lainnya.

Pilihan alat pengembangan Delphi oleh banyak pemrogram ditentukan oleh kemudahan penggunaan antarmuka perangkat lunak terkait, serta berbagai alat yang berguna untuk bekerja pada setiap tahap pembuatan program - pada tahap desain, algoritma pemrograman. atau melakukan debug.


Mengembangkan komponen Anda sendiri

Jika Anda tidak puas dengan komponen standar yang disertakan dengan Delphi, inilah saatnya Anda mencoba membuatnya sendiri. Kita akan mulai dengan yang sederhana terlebih dahulu dan secara bertahap beralih ke yang lebih kompleks. Jadi, mari kita mulai.

Sebelum membuat komponen Anda, penting untuk memilih nenek moyang yang tepat untuk komponen tersebut. Siapa yang bisa menjadi nenek moyang komponen Anda? Biasanya digunakan sebagai nenek moyang TComponent, TControl, TWinControl, TGraphicControl, TCustomXXXXXX, serta semua komponen palet komponen. Mari kita ambil contoh komponen TOpenDialog, yang terletak di halaman Dialogs pada palet komponen. Ia melakukan tugasnya dengan baik, tetapi ada satu ketidaknyamanan kecil. Setiap kali Anda menggunakannya, Anda harus mengubah nilai properti Opsi setiap kali. Dan, biasanya, ini adalah tindakan yang sama.


Mengklik baris ini Ctrl + Shift + C membuat template untuk metode ini, di dalamnya kita menyisipkan baris berikut:


Menginstal Komponen komponen yang dibuat/Instal Komponen...

  • Instal Ke Paket Baru
  • Nama file paket: C:\Program Files\Borland\Delphi4\Lib\OurTest.dpk
  • Deskripsi paket: Paket kami yang telah diuji

Tidakkah Anda suka bahwa komponen kita memiliki ikon yang sama dengan komponen standar? Kalau begitu mari kita buat sendiri untuknya. Untuk melakukan ini kita perlu memanggil Tools/Image Editor. Buat file *.dcr baru. Masukkan gambar Resource/Baru/Bitmap ke dalamnya. Atur ukuran gambar menjadi 24x24 piksel. Dan kemudian - kreativitas Anda... Mohon diperhatikan: warna titik yang sesuai dengan warna titik di pojok kiri bawah gambar akan dianggap TRANSPARAN!

Setelah Anda membuat gambar, ganti namanya dari Bitmap1 menjadi TOurOpenDialog dan simpan file sebagai OurOpenDialog.dcr. Hapus komponen dari paket dan instal kembali (hanya dalam kasus ini tautan ke file *.dcr akan ditambahkan).

Kompilasi, Instal dan semoga berhasil!

Pengembangan aplikasi profesional dengan Delphi 5 | Alat Pengembangan | KomputerPress 2"2001

Membuat Komponen Delphi

Pengantar Membuat Komponen Delphi

Saat mengembangkan aplikasi menggunakan Borland Delphi, akan lebih mudah untuk membuat komponen karena alasan berikut:

  1. Kemudahan penggunaan. Komponen ditempatkan pada formulir, dan Anda perlu menetapkan nilai properti untuk komponen tersebut dan menulis kode pengendali kejadian. Oleh karena itu, jika dalam suatu proyek kombinasi kontrol dan event handler yang terkait dengannya terjadi di dua tempat, maka masuk akal untuk mempertimbangkan pembuatan komponen yang sesuai. Jika kombinasi kontrol dan event handler terkait terjadi lebih dari dua kali, maka pembuatan komponen dijamin akan menghemat tenaga saat mengembangkan aplikasi.
  2. Organisasi sederhana pengembangan proyek kelompok. Dalam pengembangan kelompok, bagian-bagian individual dari proyek dapat didefinisikan sebagai komponen dan pekerjaan dapat ditugaskan ke pemrogram yang berbeda. Komponen dapat di-debug secara terpisah dari aplikasi, yang cukup mudah dilakukan.
  3. Sederhana dan metode yang efektif berbagi kode dengan programmer lain. Ada banyak situs, misalnya http://www.torry.net/, di mana Anda dapat menemukan komponen yang didistribusikan secara bebas atau membelinya dengan sedikit biaya.

Paket Fitur

Di Delphi, komponen disimpan dalam paket. Daftar paket komponen yang digunakan dapat dipanggil menggunakan item menu Komponen/Instal Paket (namun, karena alasan tertentu, dialog ini diberi judul Opsi Proyek).

Dengan menggunakan dialog ini, Anda dapat menambahkan paket baru (Tambah) atau menghapus paket yang sudah ada (Hapus). Menghapus tidak berarti menghapus file secara fisik dari disk, melainkan menghapus link dari lingkungan pengembangan ke paket ini. Saat Anda menambahkan paket baru, komponen yang disimpan di dalamnya muncul di palet, tetapi saat Anda menghapusnya, sebaliknya, komponen tersebut hilang. Daripada menghapus sebuah paket, Anda dapat “menyembunyikan” isinya pada tahap pengembangan dengan menghapus centang pada nama paket dalam daftar. Anda juga dapat melihat komponen dan ikonnya (Komponen). Terakhir, Anda dapat mengedit paket yang ditambahkan pengguna (Edit) - paket yang disertakan dengan Delphi tidak dapat diedit (tombol Edit berwarna abu-abu).

Dalam dialog ini, Anda dapat menentukan cara membuat proyek: menggunakan paket runtime atau tanpa paket runtime. Dari sini jelas bahwa ada dua jenis paket komponen: paket runtime (paket yang bekerja saat runtime) dan paket design-time (paket yang digunakan selama pengembangan). Semuanya adalah DLL (perpustakaan yang dimuat secara dinamis).

Paket runtime (ekstensi *.bpl) dikirimkan ke pengguna akhir bersama dengan proyek jika proyek dikompilasi dengan opsi Bangun dengan paket runtime diaktifkan. Aplikasi itu sendiri (*.exe atau *.dll) dalam hal ini ternyata berukuran kecil, tetapi file *.bpl yang agak besar harus ditransfer bersamanya. Menurut para ahli, mengirimkan proyek dengan paket runtime memberikan keuntungan dalam volume file yang disediakan, hanya jika mencakup lima atau lebih modul (*.exe atau *.dll) yang ditulis dalam Delphi. Ketika modul-modul ini bekerja sama, sumber daya sistem operasi dihemat, karena satu paket yang dimuat ke dalam RAM melayani beberapa modul.

Paket waktu desain (ekstensi *.dcp) hanya digunakan pada tahap pengembangan. Selama pengembangan, mereka mendukung pembuatan komponen pada formulir. Proyek Delphi yang dikompilasi menyertakan kode bukan dari paket komponen, tetapi dari file *.dcu. Meskipun file *.dcp dihasilkan dari file *.dcu, isinya mungkin tidak sama jika ada perubahan pada file *.pas dan paket belum dikompilasi ulang. Kompilasi hanya dapat dilakukan untuk paket yang dibuat oleh pemrogram. Hal ini dicapai dengan mengklik tombol Edit pada dialog di atas. Setelah ini, sebuah formulir muncul yang memungkinkan Anda memanipulasi paket.

Paket ini berisi dua bagian. Bagian Berisi berisi daftar modul yang membentuk komponen paket ini (file *.pas dan *.dcu) dan ikonnya (file *.dcr). Bagian Wajib berisi tautan ke paket lain yang diperlukan agar komponen ini dapat berfungsi. Menambahkan komponen baru ke paket dilakukan dengan tombol Tambah, dan menghapus komponen yang sudah ada dilakukan dengan tombol Hapus. Sampai paket dikompilasi dengan mengklik tombol Kompilasi, perubahan apa pun yang dilakukan pada paket tidak akan muncul di lingkungan pengembangan. Terakhir, perintah Instal tersedia ketika konten paket telah dihapus dari lingkungan pengembangan dengan menghapus centang pada nama paket pada dialog sebelumnya.

Perintah Option memungkinkan Anda memilih opsi untuk mengkompilasi paket yang mirip dengan opsi proyek. Ini dapat digunakan untuk menentukan tipe paket apa yang dimiliki paket tertentu: run-time, design-time, atau keduanya (tipe paket default). Opsi menentukan direktori untuk mencari modul yang diperlukan dan menyimpan hasil kompilasi. Mereka juga menentukan tindakan yang diperlukan untuk debugging: apakah memeriksa rentang nilai yang dapat diterima atau tidak, bagaimana melakukan optimasi, bagaimana menangani kesalahan I/O. Terakhir, opsi mungkin menyertakan informasi versi paket. Hal ini sangat penting jika aplikasi didistribusikan bersama dengan paket runtime: saat menjalankan program instalasi, informasi versi akan memungkinkan Anda mengganti versi paket yang sudah ketinggalan zaman dengan benar, dan sebaliknya, jika Anda mencoba menginstal paket dengan versi yang lebih lama dari versi sebelumnya. yang sudah tersedia di komputer tertentu, yang terakhir tidak akan ditimpa.

Templat Komponen

Delphi memungkinkan Anda membuat komponen komposit sederhana dari beberapa komponen umum yang dipilih pada formulir pada waktu desain. Pakar terkait dipanggil menggunakan item menu Komponen/Buat Templat Komponen. Item menu ini tersedia jika setidaknya satu komponen dipilih pada formulir. Setelah memilihnya, kotak dialog Informasi Templat Komponen muncul.

Dalam dialog ini, Anda harus menentukan nama kelas dan nama halaman pada palet komponen dimana komponen baru harus ditempatkan. Jika halaman dengan nama ini tidak ada pada palet komponen, maka halaman tersebut akan dibuat. Anda juga dapat mengubah ikon yang diusulkan untuk komponen baru dengan mengunggah file *.bmp yang sesuai.

Saat templat dibuat, properti yang diubah oleh pemrogram di Object Inspector dan pengendali kejadian yang terkait dengan kontrol yang dipilih akan diingat. Dalam hal ini, event handler diingat sepenuhnya, tanpa memfilter panggilan ke komponen lain (tidak dipilih pada formulir), variabel global, metode, dll. Oleh karena itu, jika komponen tersebut (variabel, metode) tidak ada di proyek lain, maka ketika mencoba mengkompilasi proyek tersebut, pesan diagnostik Pengidentifikasi Tidak Dikenal akan diterima.

Kapan sebaiknya Anda menggunakan template? Pertama-tama, jika perlu mengubah properti apa pun yang tersedia secara default di kelas dasar. Misalnya, aplikasi menggunakan kontrol untuk mengedit baris teks berwarna kuning. Anda dapat menempatkan komponen TEdit pada formulir, mengubah properti Warna menjadi kuning, menandai komponen ini dan menyimpannya sebagai templat. Setelah ini, Anda dapat mengakses template ini, dan komponen yang ditempatkan pada formulir akan memiliki warna kuning. Namun, Anda tidak boleh menyalahgunakan kesempatan ini, karena kelas baru akan dibuat untuk kontrol dengan warna yang diubah dan semua metode virtual akan diduplikasi di memori. Ini akan berdampak negatif pada sumber daya sistem operasi.

Templat komponen juga mudah digunakan ketika Anda perlu mentransfer sejumlah komponen bersama dengan pengendali kejadian dari satu formulir ke formulir lainnya. Untuk melakukan ini, semuanya dipilih, templat komponen dibuat, yang ditempatkan pada formulir baru. Dalam hal ini, tidak hanya komponen itu sendiri yang akan ditransfer, tetapi juga event handler, yang tidak dapat dicapai saat memanggil perintah Salin/Tempel - dalam kasus terakhir, event handler akan hilang.

Komponen yang dibuat menggunakan perintah Create Component Template sangat berbeda dengan komponen biasa yang dibuat menggunakan metode standar (dijelaskan di bawah). Secara visual, perbedaan utamanya adalah ini: jika templat menyertakan beberapa kontrol, maka setelah komponen tersebut ditempatkan pada formulir, Anda dapat memilih satu kontrol dan menghapusnya - sementara sisanya akan tetap ada di formulir. Untuk komponen standar, jika menyertakan beberapa kontrol, tidak mungkin untuk memilih salah satunya dan menghapusnya - komponen dipilih dan dihapus seluruhnya.

Membuat Komponen Sederhana

Saat menulis komponen baru, Anda harus yakin bahwa komponen tersebut ditulis untuk pemrogram, bukan pengguna akhir. Dalam hal ini, sebaiknya pemrogram tidak mempelajari detail implementasi komponen, namun hanya menggunakan properti dan kejadian yang dipaparkan oleh komponen tersebut. Hal ini dicapai melalui pengujian yang sangat menyeluruh. Sebuah komponen baru harus diuji bahkan dalam situasi yang tidak dirancang dengan jelas.

Mari kita ajukan permasalahan sebagai berikut. Anda perlu membuat tombol yang akan berbunyi bip saat ditekan, dan mengimplementasikannya sebagai komponen sehingga pemrogram dapat menempatkannya pada formulir dan menggunakannya. Secara umum, ketika mempertimbangkan komponen, kita sering menggunakan efek eksternal yang paling sederhana: bunyi bip, tampilan pesan, dll. Ini menyiratkan bahwa di tempat di mana efek eksternal digunakan, kode apa pun yang cukup rumit dapat ditempatkan. Kami hanya tidak tertarik padanya saat ini.

Pembuatan komponen dimulai dengan memilih item menu Komponen/Komponen baru. Setelah ini, dialog Komponen Baru segera muncul.

Dalam dialog ini, Anda perlu menentukan kelas leluhur, nama kelas yang baru dibuat, halaman pada palet tempat komponen baru akan ditempatkan, nama modul yang berisi implementasi komponen baru, dan jalur ke dia. Jika komponen baru menggunakan modul lain, yang jalurnya tidak dijelaskan, maka komponen tersebut harus ditentukan di bidang Jalur Pencarian.

Jadi, tugas pertama (dan mungkin yang utama) adalah memilih kelas leluhur. Dalam daftar drop-down, semua komponen yang tersedia di palet ditawarkan sebagai kelas leluhur, termasuk komponen yang tidak termasuk dalam distribusi standar Delphi. Penting untuk memilih sebagai kelas leluhur sebuah kelas yang propertinya sedekat mungkin dengan kelas yang sedang dibuat. Untuk tugas kita, kita dapat, misalnya, memilih TWinControl sebagai leluhur, namun dalam kasus ini kita perlu menerapkan semua efek visual dari klik tombol, dll. Oleh karena itu, kami memilih TButton sebagai leluhurnya.

Nama kelas yang baru dibuat harus mencerminkan konten komponen dan tidak boleh bertepatan dengan nama komponen yang sudah terdaftar! Pada tahap pengisian dialog ini, nama tidak diperiksa kecocokannya - petualangan yang terkait dengan kesalahan seperti itu akan dimulai nanti...

Saat memilih halaman, Anda perlu tahu bahwa jika Anda menentukan nama halaman yang tidak ada, halaman baru akan dibuat.

Terakhir, ketika Anda mengklik tombol Instal dan OK, sebuah templat akan dibuat untuk mengimplementasikan komponen baru. Namun, ketika Anda mengklik tombol Instal, templat akan ditempatkan pada palet komponen, dan ketika Anda mengklik OK, templat akan dibuat begitu saja. Disarankan untuk menggunakan tombol Instal. Setelah komponen terinstal, dapat ditempatkan pada form. Sekarang semua perubahan yang dilakukan pada kode implementasi komponen akan dikompilasi bersama dengan proyek, dan pemrogram akan segera menerima pesan kesalahan. Jika komponen tidak diinstal, maka untuk menemukan kesalahannya harus dikompilasi melalui editor paket (lihat di atas) dengan mengklik tombol Kompilasi, yang kurang nyaman.

Jadi, setelah mengklik tombol Instal, dialog lain muncul, yang memungkinkan Anda menentukan paket di mana komponen ini akan ditempatkan.

Dialog ini memiliki dua halaman, halaman pertama Anda dapat memilih salah satu paket yang ada, dan halaman kedua Anda dapat membuat paket baru. Sangat disarankan untuk memberikan deskripsi teks singkat tentang paket; inilah yang akan ditampilkan dalam dialog yang dipanggil dengan perintah Komponen/Instal paket (lihat di atas). Setelah memilih paket dan menekan tombol OK, editor paket dipanggil, di mana modul yang baru dibuat untuk mengimplementasikan komponen baru ditempatkan secara otomatis. Berguna untuk tidak menutupnya, tetapi memindahkannya ke salah satu sudut layar sehingga dapat diaktifkan dengan menekan tombol mouse.

Pada saat yang sama, "kosong" akan dibuat di editor kode untuk menjelaskan komponen baru:

Tombol UnitBip; antarmuka menggunakan Windows, Pesan, SysUtils, Kelas, Grafik, Kontrol, Formulir, Dialog, StdCtrls; ketik TButtonBeep = class(TButton) private ( Deklarasi pribadi ) dilindungi ( Deklarasi yang dilindungi ) publik ( Deklarasi publik ) diterbitkan ( Deklarasi yang diterbitkan ) berakhir; prosedur Daftar; tata cara pelaksanaan Daftar; mulai RegisterComponents("Sampel", ); akhir; akhir.

Kelas baru itu sendiri mendeklarasikan empat bagian, yang artinya dijelaskan secara rinci di bagian “Visibilitas variabel dan metode” pada artikel sebelumnya dalam seri ini (ComputerPress No. 1 "2001). Selain itu, kelas baru mendefinisikan Prosedur register, yang dipanggil oleh lingkungan pengembangan Delphi selama instalasi modul ini sebagai komponen. Ini berisi nama halaman pada palet tempat komponen ini ditempatkan, dan dalam tanda kurung siku - nama kelasnya. Secara umum, metode Register mengambil array tipe kelas sebagai parameternya, karena beberapa komponen dapat diimplementasikan dalam satu modul, oleh karena itu dipisahkan dengan tanda koma, misalnya:

Daftar Prosedur; mulai RegisterComponents("Sampel", ); akhir;

Mari kita lanjutkan menyelesaikan tugas yang ada - membuat tombol yang mengeluarkan bunyi mencicit. Pertama, mari kita lakukan sesuatu yang sepele (tetapi ternyata kemudian salah) - tetapkan event handler OnClick di konstruktor tombol. Untuk melakukan ini, di bagian pribadi, kami mendefinisikan header metode baru BtClick(Sender:TObject) dan mengimplementasikannya di bagian implementasi:

Prosedur TButtonBeep.BtClick(Pengirim:TObject); mulaiBip; akhir;

konstruktor Buat(Pemilik:TKomponen); mengesampingkan;

dengan arahan penggantian wajib! Mari kita implementasikan di bagian implementasi:

Konstruktor TButtonBeep.Create(AOwner:TComponent); mulai mewarisi Buat(Pemilik); OnClick:=BtKlik; akhir;

Setelah ini, mari kita kompilasi komponennya. Mari kita letakkan tombol pada formulir dari halaman Sampel dan jalankan proyek untuk dieksekusi. Anda dapat memastikan bahwa tombol berbunyi bip saat ditekan!

Sekarang mari kembali ke lingkungan pengembangan dan tetapkan event handler OnClick di pemeriksa objek. Di event handler, kami akan menampilkan teks dalam judul formulir:

Prosedur TForm1.ButtonBeep1Click(Pengirim:TObject); mulai Keterangan:="Uji"; akhir;

Mari kita jalankan proyeknya dan coba tekan tombolnya. Judul formulir berubah, tetapi tombolnya berhenti berbunyi! Kesalahannya adalah kami mencoba mendefinisikan dua penangan untuk satu peristiwa tombol OnClick: satu di dalam komponen BtClick, dan yang lainnya ditetapkan menggunakan pemeriksa objek. Setelah mengerjakan konstruktor TButtonBeep, kami memiliki link ke handler BtClick pertama. Kemudian sumber daya dimuat, dan metode ButtonBeep1Click ditugaskan ke event handler OnClick. Dalam hal ini, tautan ke pengendali pertama - BtClick - hilang dan tidak dapat diperbaiki lagi.

Oleh karena itu, saat menulis komponen baru, Anda harus selalu mempertimbangkan untuk mengubah properti dan event handler menggunakan Object Inspector. Jika suatu properti (peristiwa) tidak berubah, maka properti tersebut tidak boleh ditampilkan di Object Inspector. Dan jika sudah terlihat, sebaiknya sembunyikan (kita akan membicarakannya nanti). Pemrogram berhak mengubah properti apa pun di pemeriksa objek, dan jika setelah itu komponen berhenti bekerja, pengembang komponen harus disalahkan, tetapi pemrogram tidak boleh menggunakannya.

Bagaimana kita bisa mengatasi masalah ini dengan benar? Salah satu cara untuk membuat komponen adalah dengan menulis ulang metode yang sudah ada. Saat melihat file StdCtrls.pas, tempat kode sumber untuk komponen TButton diimplementasikan, Anda dapat melihat bahwa file tersebut berisi metode Klik dinamis yang dapat ditulis ulang. Oleh karena itu, kami kembali lagi ke kode sumber yang dibuat oleh pakar Delphi saat membuat komponen (kami menghapus konstruktor dan metode BtClick). Kemudian di bagian publik kita mendefinisikan header metode:

Klik Prosedur; mengesampingkan;

dan inilah implementasi metodenya:

Prosedur TButtonBeep.Klik; mulai diwarisi Klik; berbunyi; akhir;

Anda dapat memverifikasi bahwa tombol tersebut mengeluarkan bunyi mencicit saat ditekan. Selain itu, saat menugaskan pengendali kejadian di inspektur objek, pengendali ini dijalankan dan bunyi bip tidak hilang! Komponen diimplementasikan dengan benar.

Dengan menggunakan contoh ini, akan berguna untuk menganalisis kemungkinan kesalahan saat menulis kode:

  1. Lupa arahan override saat mendefinisikan header metode Klik. Tombol berhenti berbunyi bip, oleh karena itu metode Klik tidak dipanggil.
  2. Panggilan yang terlupakan ke metode leluhur (Klik yang diwarisi) dalam implementasi prosedur Klik. Tombol terus berbunyi bip saat ditekan, namun kode di event handler yang ditetapkan di pemeriksa objek tidak dijalankan. Oleh karena itu, metode Click pada kelas TButton memunculkan event OnClick.

Sekarang mari kita ubah ikon komponen TButtonBeep pada palet. Secara default, ikon komponen leluhur digunakan untuk komponen baru. Untuk melakukan ini, panggil Editor Gambar menggunakan perintah Alat/Editor Gambar. Di editor, panggil perintah File/New/Component Resource File (*.dcr). Setelah perintah Resource/New/Bitmap, sebuah dialog akan muncul menyarankan ukuran ikon 32x32. Ukuran default ini harus diubah menjadi 24x24 - ini adalah ukuran yang harus dimiliki ikon komponen! Setelah mengklik OK, Anda harus menggambar gambar menggunakan alat standar yang serupa Editor cat. Ingatlah bahwa warna piksel kiri bawah adalah warna topeng - warna ini akan menjadi “transparan”.

Setelah ini, Anda perlu mendefinisikan ulang nama sumber daya dengan ikon; secara default, namanya adalah Bitmap1. Nama sumber daya baru harus sesuai dengan nama kelas - dalam kasus kami TButtonBeep.

Sekarang Anda perlu menyimpan file ikon di direktori yang sama dengan modul yang berisi prosedur Daftar untuk komponen ini, dan dengan nama yang sama dengan nama modul. Hanya saja ekstensi filenya bukan *.pas, melainkan *.dcr. File dengan ikon komponen sudah siap. Namun jika kita melihat pada palet Components, kita akan melihat bahwa ikon lama masih ada. Jika Anda me-restart Delphi atau bahkan sistem operasi, ikon lama akan tetap ada di palet. Untuk mengubah ikon, komponen harus didaftarkan ulang. Untuk melakukan ini, Anda perlu:

Contoh ini harus dianggap sebagai latihan tes. Sebelum menulis komponen baru, Anda perlu melihat apakah ada komponen serupa di antara komponen yang didistribusikan secara bebas. Hampir semua tombol ada: transparan, melarikan diri, bulat, berwarna, dll. Situasinya kurang lebih sama dengan komponen lain - keturunan dari kelas yang sama. Oleh karena itu, paling sering Anda harus mengimplementasikan komponen yang terdiri dari beberapa kontrol.

Jadi, dalam contoh ini kita mengeksplorasi penggunaan metode penulisan ulang untuk membuat komponen baru.

Membuat Komponen Kompleks

Katakanlah Anda perlu memasukkan daftar nama pelanggan dalam sebuah aplikasi. Dalam aplikasi yang sama Anda juga perlu memasukkan daftar nomor telepon. Memasukkan daftar adalah operasi yang cukup umum, jadi Anda harus mempertimbangkan untuk menerapkannya sebagai sebuah komponen.

Untuk memasukkan elemen baru ke dalam daftar, Anda memerlukan editor - komponen TEdit. Selanjutnya, pengguna akan dapat melihat daftarnya - komponen TListBox akan diperlukan. Selain itu, Anda memerlukan perintah untuk menulis nilai saat ini dari TEdit ke daftar, mengedit item daftar yang dipilih, dan menghapusnya. Cara termudah untuk mengimplementasikan perintah ini adalah dengan menggunakan tombol. Untuk mempermudah tugas, kita akan menempatkan satu tombol pada form, ketika diklik kita akan menambahkan isi komponen TEdit ke dalam daftar.

Jadi kita perlu membuat komponen baru yang mencakup TEdit, TListBox, dan TButton. Seperti biasa, mari kita mulai membuatnya dengan perintah Komponen/Komponen Baru. Setelah ini, sebuah dialog muncul di mana Anda harus menentukan kelas leluhur, nama kelas, dan nama modul. Tidak ada kesulitan dengan nama kelas dan nama modul, tetapi nama kelas leluhurnya tidak jelas. Kami memiliki tiga kontrol. Kelas nenek moyang yang sama bagi mereka adalah TWinControl. Namun jika kita memilihnya sebagai kelas leluhur, kita dihadapkan pada implementasi kode TButton, TEdit dan TListBox yang sangat panjang dan membosankan. Dalam kasus seperti ini, perlu untuk memilih sebuah komponen sebagai kelas leluhur yang dapat menjadi “bapak” dalam kaitannya dengan komponen lainnya. Di antara komponen standar yang didistribusikan dengan Delphi, ada tiga: TPanel, TGroupBox, TScrollBox. Mari kita pilih panel sebagai kelas leluhur, tetapi bukan komponen TPanel itu sendiri, melainkan kelas TCustomPanel. Keuntungan memilih TCustomPanel dibandingkan TPanel akan kami bahas di bawah ini.

Beri nama kelas baru TListAdd dan klik tombol Install. Setelah memilih paket, komponen akan dipasang di palet, yang kemudian dapat ditempatkan pada formulir aplikasi yang baru dibuat. Hal ini berguna karena ketika proyek dikompilasi, modul komponen juga akan dikompilasi dan jika ada kesalahan, kompiler akan menampilkan pesan.

Akan lebih mudah untuk menempatkan kontrol kita pada beberapa formulir dan kemudian membuat komponen darinya. Tidak ada pakar seperti itu dalam paket standar Delphi. Oleh karena itu, Anda perlu membuat sendiri komponennya dan menempatkannya di panel. Masuk akal untuk membuat kontrol - TButton, TEdit dan TListBox - di konstruktor TCustomPanel, yang jelas memerlukan penulisan ulang. Untuk saat ini, mari kita tempatkan kontrolnya dalam kotak berukuran 100x100. Koordinatnya juga perlu ditentukan di konstruktor. Perlu diingat bahwa setelah konstruktor elemen kontrol apa pun dikerjakan, ia belum memiliki induk, yaitu, ia tidak mengetahui jendela mana yang harus mengukur koordinat sudut kiri atas. Mencoba mengubah koordinat jendela anak yang tidak memiliki induk akan langsung memunculkan pengecualian. Oleh karena itu, operator pertama setelah memanggil konstruktor kontrol adalah menetapkannya sebagai induk, yang mana kita akan memilih TCustomPanel. Kami juga akan menjadikannya pemiliknya, dalam hal ini tidak perlu menulis ulang destruktornya.

Jadi, di bagian penggunaan kita menambahkan modul StdCtrls, di mana deskripsi kelas TEdit, TButton dan TListBox berada, dan di bagian pribadi kita mendefinisikan tiga variabel:

FEdit Pribadi:TEdit; FListBox:TListBox; Tombol F: Tombol T;

Di bagian publik kami mendeklarasikan header konstruktor dengan arahan override wajib:

Buat Konstruktor(Pemilik:TKomponen); mengesampingkan;

Kami mengimplementasikan konstruktor di bagian implementasi:

Konstruktor TListAdd.Create(AOwner:TComponent); mulai mewarisi Buat(Pemilik); FButton:=TButton.Create(Self); FButton.Parent:=Diri; FButton.Kiri:=5; FButton.Atas:=5; FButton.Lebar:=40; FButton.Tinggi:=25; FEdit:=TEdit.Buat(Mandiri); FEdit.Parent:=Diri; FEdit.Kiri:=50; FEdit.Atas:=5; FEdit.Lebar:=45; FEdit.Tinggi:=25; FListBox:=TListBox.Buat(Mandiri); FListBox.Parent:=Diri; FListBox.Kiri:=5; FListBox.Atas:=35; FListBox.Lebar:=90; FListBox.Tinggi:=60; akhir;

Perlu ditekankan sekali lagi bahwa destruktor dalam hal ini tidak perlu ditulis ulang: panel adalah pemilik semua kontrol, dan ketika destruktornya dipanggil, destruktor kontrol akan dipanggil secara otomatis.

Setelah komponen dikompilasi ulang menggunakan editor paket, perubahan pada komponen sudah dapat dilihat secara visual, pada tahap pengembangan.

Kelemahan pertama yang menarik perhatian Anda adalah perilaku kontrol yang tidak memadai saat menskalakan komponen. Ketika dimensinya diubah, dimensi dan posisi elemen tidak berubah. Selain itu, komponennya bisa dibuat kecil sehingga tiga kontrol tidak bisa muat di dalamnya. Dan terakhir, saat memasang komponen pada formulir dari palet komponen dengan satu klik mouse sederhana, dimensinya juga meninggalkan banyak hal yang diinginkan.

Pertama, mari kita perbaiki ukuran default komponen, yaitu ukuran yang ditetapkan secara otomatis ketika Anda mengklik palet komponen dan kemudian mengklik formulir. Untuk melakukan ini, Anda hanya perlu menentukan dimensi panel baru di konstruktor:

Lebar:=100; Tinggi:=100;

Maka Anda perlu meningkatkan perilaku komponen saat melakukan penskalaan. Untuk melakukan ini, Anda perlu menerima pesan bahwa dimensi telah berubah. Ketika ukuran kontrol berubah, sistem mengirimkan pesan WM_SIZE ke kontrol tersebut. Pesan ini harus disadap. Untuk melakukan ini, di bagian pribadi kami menjelaskan header pencegat pesan:

Prosedur WMSize(var Pesan:Tmessage); pesan WM_SIZE;

dan di bagian implementasi kami mengimplementasikan handlernya:

Prosedur TListAdd.WMSize(var Pesan:TMessage); mulai diwariskan; jika Lebar<100 then Width:=100; if Height<100 then Height:=100; FEdit.Width:=Width-55; FListBox.Width:=Width-10; FListBox.Height:=Height-40; end;

Pernyataan pertama adalah panggilan ke handler WM_SIZE default (diwarisi). Setelah memanggilnya, properti Lebar dan Tinggi akan berisi lebar dan tinggi panel yang baru. Setelah itu ditentukan dimensi minimum komponen, dalam hal ini 100x100. Jika ukuran horizontal atau vertikal kurang dari minimum, maka ditetapkan nilai minimum. Kontrol kemudian diskalakan sehingga memenuhi seluruh panel dengan beberapa lekukan. Dengan mengkompilasi komponen melalui editor paket, Anda sudah dapat mencatat pada tahap pengembangan bahwa kontrol pada panel berfungsi dengan benar saat diskalakan, dan juga bahwa ukuran komponen tidak boleh dibuat kurang dari 100x100.

Sekarang akan berguna untuk menjalankan keseluruhan proyek, coba masukkan data ke dalam editor teks satu baris dan klik tombol. Dalam hal ini, tidak ada yang ditambahkan ke daftar. Dan tidak mengherankan, di komponen kami tidak disebutkan apa yang harus dilakukan saat tombol ditekan. Untuk membuat event handler yang terkait dengan klik tombol, Anda dapat melanjutkan seperti saat menulis komponen TbuttonBeep, yaitu menentukan kelas baru - turunan dari TButton dan menulis ulang metode Klik. Namun, mendefinisikan kelas baru memerlukan sumber daya sistem (metode virtual dikalikan). Jika kita menandai komponen pada formulir dan melihat pada pemeriksa objek, kita akan menemukan bahwa komponen TlistAdd memperlihatkan sedikit properti dan tidak ada kejadian, termasuk tidak ada pengendali kejadian untuk tombol OnClick. Oleh karena itu, apa yang kami tolak di bab terakhir sebagai metode yang salah, mendefinisikan ulang pengendali tombol OnClick, dapat diterapkan dalam kasus ini, karena pemrogram tidak dapat menetapkan pengendali baru di pemeriksa objek. Jadi, di bagian pribadi kami menjelaskan header metode baru:

Prosedur BtClick(Pengirim:TObject);

Dalam implementasi konstruktor TListAdd, kami menetapkan pengendali ini ke pengendali peristiwa FButton.OnClick:

FButton.OnClick:=BtKlik;

Terakhir, mari terapkan metode BtClick:

Prosedur TListAdd.BtClick(Pengirim:TObject); mulai jika panjang(FEdit.Teks)>0 lalu mulai FListBox.Items.Add(FEdit.Text); FEdit.Teks:=""; FEdit.SetFokus; akhir; akhir;

Pertama, mari kita periksa apakah editor satu baris kosong: kami tidak akan menambahkan baris kosong ke daftar. Kemudian kami mentransfer konten editor ke daftar (FListBox.Items.Add(FEdit.Text);) dan menyiapkan editor untuk memasukkan nilai berikutnya - yaitu, kami menghapusnya dari teks (yang telah ditransfer ke daftar ) dan transfer fokus masukan ke sana. Sekarang, setelah mengkompilasi dan menjalankan aplikasi, Anda dapat memastikan bahwa aplikasi berfungsi dengan benar - ketika Anda menekan tombol, konten editor ditransfer ke daftar.

Menambahkan Properti dan Metode

Jika Anda menempatkan komponen TPanel di sebelah komponen TListAdd dan membandingkan apa yang ditampilkan di pemeriksa objek, Anda akan melihat bahwa sejumlah besar properti dan peristiwa diekspos untuk panel, sementara hanya sedikit properti yang diekspos untuk TListAdd. Sedangkan kelas TCustomPanel merupakan nenek moyang dari kedua komponen tersebut. Untuk memahami alasannya, mari kita buka modul ExtCtrls.pas dan lihat perbedaan antara kelas TCustomPanel dan TPanel. Dapat dicatat bahwa semua metode dan variabel yang menyediakan fungsionalitas panel ditentukan pada tingkat kelas TCustomPanel. Ini juga mendefinisikan properti yang kemudian ditampilkan di pemeriksa objek untuk TPanel, hanya properti ini yang ditentukan di bagian Dilindungi. Implementasi kelas TPanel sangat sederhana: TCustomPanel didefinisikan sebagai leluhur, dan properti kelas ini dideklarasikan, tetapi di bagian yang diterbitkan. Menjadi jelas apa yang perlu dilakukan di kelas TListAdd agar properti dan metode kelas TcustomPanel muncul di pemeriksa objek, yaitu mendeklarasikan properti. Di bagian yang diterbitkan dari kelas TListAdd kami menulis:

Penyelarasan Properti; properti OnMouseDown;

Saat mendeklarasikan properti, Anda tidak perlu menentukan tipe atau variabel referensi atau metode untuk membaca atau menulis properti. Setelah mengkompilasi komponen melalui editor paket di inspektur objek, Anda dapat mengamati tampilan properti Align dan event OnMouseDown. Jadi, untuk turunan dari kelas TCustom..., programmer mempunyai kesempatan untuk memilih properti dan kejadian mana yang harus ditampilkan di pemeriksa objek dan mana yang tidak. Karena alasan inilah kelas TCustom... direkomendasikan untuk digunakan sebagai nenek moyang untuk membuat komponen.

Sekarang mari kita lihat bagaimana Anda dapat memperkenalkan properti baru (yang kami lakukan di atas adalah mendeklarasikan ulang properti yang sudah ada). Teks pada tombol dapat digunakan sebagai properti yang sesuai untuk ditampilkan di pemeriksa objek: biarkan pemrogram yang menggunakan komponen TListAdd mengubah teks pada waktu desain. Mencoba memperkenalkan properti baru (sebut saja BtCaption) menggunakan deklarasi:

Properti BtCaption:string baca FButton.Caption tulis FButton.Caption;

menghasilkan kesalahan saat mencoba mengkompilasi komponen. Oleh karena itu, kami mendefinisikan header dari dua metode di bagian pribadi:

Fungsi GetBtCaption:string; prosedur SetBtCaption(Nilai const:string);

Di bagian yang diterbitkan kami mendeklarasikan properti BtCaption:

Properti BtCaption:string baca GetBtCaption tulis SetBtCaption;

Terakhir, kami menerapkan dua metode yang dideklarasikan di bagian implementasi:

Fungsi TListAdd.GetBtCaption:string; mulai Hasil:=FButton.Caption; akhir; prosedur TListAdd.SetBtCaption(Nilai const:string); mulai FButton.Caption:=Nilai; akhir;

Setelah mengkompilasi komponen menggunakan editor paket, properti baru muncul di Object Inspector. Perubahan nilai properti ini tercermin langsung pada tahap pengembangan.

Sekarang mari kita tentukan acara baru. Dalam hal ini, masuk akal untuk membuat acara yang memungkinkan pemrogram yang menggunakan komponen ini menganalisis teks sebelum menambahkan konten editor ke daftar dan mengizinkan atau menonaktifkan penambahan teks ke daftar. Oleh karena itu, metode ini harus berisi parameter nilai teks saat ini di editor dan bergantung pada variabel Boolean, yang dapat ditetapkan oleh pemrogram dengan nilai Benar atau Salah. Selain itu, setiap event handler dalam sebuah komponen harus bergantung pada parameter Sender, di mana komponen yang memanggilnya meneruskan referensi ke dirinya sendiri. Hal ini diperlukan karena dalam lingkungan pengembangan Delphi event handler yang sama dapat dipanggil dari beberapa komponen yang berbeda dan pemrogram harus dapat menganalisis komponen mana yang disebut handler tersebut. Jadi, setelah tipe kata di bagian antarmuka, sebelum mendefinisikan TListAdd, kita mendefinisikan tipe metode baru:

Ketik TFilterEvent=procedure(Sender:TObject; const EditText:string; var CanAdd:boolean) objek;

FOnFilter:TFilterEvent;

Dan di bagian yang diterbitkan kami mendefinisikan properti jenis ini:

Properti OnFilter:TFilterEvent baca FOnFilter tulis FOnFilter;

Saat mendefinisikan properti baru, kami merujuk ke variabel FOnFilter, dan bukan ke metode - metode tersebut tidak diperlukan di sini. Sekarang, jika Anda mengkompilasi komponen menggunakan editor paket, Anda dapat melihat event OnFilter muncul di Object Inspector. Namun, jika kita menugaskan pengendali padanya dan menjalankan proyek untuk dieksekusi, maka itu mungkin tidak akan dipanggil. Ini karena kita belum memanggilnya dimanapun di komponen kita. Tempat yang baik untuk memanggil event OnFilter adalah di event handler OnClick untuk FButton, yang sudah diimplementasikan. Oleh karena itu, kami akan mengubah kode implementasi metode BtClick yang telah ditentukan sebelumnya:

Prosedur TListAdd.BtClick(Pengirim:TObject); var CanAdd:boolean; mulai jika panjang(FEdit.Teks)>0 lalu mulai CanAdd:=True; jika Ditugaskan(FOnFilter) maka FOnFilter(Self,FEdit.Text,CanAdd); jika CanAdd maka mulai FListBox.Items.Add(FEdit.Text); FEdit.Teks:=""; FEdit.SetFokus; akhiri lagi bip; akhir; akhir;

Jadi, dalam cuplikan kode di atas, variabel boolean CanAdd didefinisikan. Saat menulis kode, ketahuilah bahwa programmer mungkin tidak membuat event handler OnFilter. Oleh karena itu, kami menetapkan nilai default variabel CanAdd ke True - tambahkan semua baris ke daftar. Selanjutnya, sebelum memanggil FonFilter, Anda harus memeriksa apakah programmer telah membuat event handler. Hal ini dicapai dengan memanggil metode Assigned, yang mengembalikan nilai boolean. Untuk sebuah pointer, memanggil metode Assigned sama dengan memeriksa P<>nol. Untuk metode objek kita tidak bisa menggunakan pemeriksaan FOnFilter<>nihil, karena metode objek dicirikan oleh dua alamat dan pemeriksaan seperti itu tidak akan diizinkan oleh kompiler. Namun memanggil metode Assigned dengan sempurna memeriksa apakah event handler telah dibuat. Kode di atas adalah mutlak cara standar memanggil event handler dari sebuah komponen.

Yang tersisa hanyalah menguji event handler. Mari kita tempatkan dua komponen TListAdd pada formulir, untuk satu kita hanya mengizinkan penambahan bilangan bulat, dan untuk yang lain - hanya kata-kata yang dimulai dengan huruf kapital bahasa Inggris. Oleh karena itu, kode untuk event handler OnFilter akan terlihat seperti ini:

Prosedur TForm1.ListAdd1Filter(Pengirim: TObject; const EditText: String; var CanAdd: Boolean); var I,N: bilangan bulat; mulai Val(EditTeks,N,I); DapatMenambahkan:=I=0; akhir; procedure TForm1.ListAdd2Filter(Pengirim: TObject; const EditText: String; var CanAdd: Boolean); mulai CanAdd:=Salah; jika panjang(EditTeks)>0 maka CanAdd:=(EditTeks>="A") dan (EditTeks<="Z"); end;

Kode ini mudah dimengerti, satu-satunya peringatan adalah ia memeriksa bahwa teks tersebut bukan string kosong sebelum memeriksa huruf pertama teks di event handler ListAdd2Filter. Melakukan pemeriksaan seperti itu adalah wajib: string dalam Object Pascal adalah objek, dan string kosong berhubungan dengan pointer nihil. Jika Anda mencoba memeriksa huruf pertama dari string kosong, aplikasi akan mencoba melakukan dereferensi nil, yang akan memunculkan pengecualian. Dalam hal ini, ini bukan masalah: sebelum memanggil event handler FOnFilter dari komponen TListAdd, string diperiksa panjangnya bukan nol. Namun, untuk komponen yang kode sumbernya tidak tersedia untuk Anda, verifikasi tersebut wajib dilakukan!

Menyembunyikan Properti di Object Inspector

Misalkan Anda membuat komponen akses data, misalnya turunan dari kelas TTable. Katakanlah komponen ini menganalisis daftar tabel yang tersedia di database, dan berdasarkan beberapa kriteria (misalnya, keberadaan bidang dengan tipe tertentu dan dengan nama tertentu), salah satu dipilih untuk berfungsi. Agar komponen berfungsi normal, nama tabel ini harus dimasukkan di properti TableName. Tapi properti ini terlihat di inspektur objek! Seorang programmer yang menggunakan komponen ini dapat mengubah nilainya selama pengembangan, yang mungkin akan membuat komponen tersebut tidak dapat dioperasikan. Dan dia akan benar! Jika salah satu properti atau peristiwa tidak dapat diubah, properti atau peristiwa tersebut harus disembunyikan.

Kami akan terus mengerjakan komponen TListAdd dan menghapus properti Cursor dari pemeriksa objek sebagai tugas model. Properti ini didefinisikan di bagian yang diterbitkan dari kelas TControl dan ditampilkan di inspektur objek untuk TListAdd sejak awal pengembangan komponen. Berdasarkan hal ini, Anda dapat mencoba mengganti properti ini di bagian yang dilindungi. Kompiler akan mengizinkan penggantian seperti itu, tetapi itu tidak akan memberikan hasil yang diinginkan: properti Kursor akan tetap berada di pemeriksa objek seperti semula... Properti apa pun, setelah ditentukan di bagian yang diterbitkan, akan selalu ditampilkan di objek inspektur untuk semua keturunan kelas ini.

Untuk menyembunyikan properti dari pemeriksa objek, kami menggunakan dua fitur kompiler Delphi, yaitu:

  1. Saat mendeklarasikan properti baru dengan nama yang sama dengan properti yang sudah ada, properti yang ditentukan sebelumnya akan “dibayangi”.
  2. Properti yang memiliki akses baca-saja atau tulis-saja tidak muncul di pemeriksa objek, meskipun dinyatakan di bagian yang diterbitkan.

Sebelum Anda mulai menyembunyikan properti Cursor, sebaiknya hapus komponen TListAdd dari formulir, jika tidak, pengecualian mungkin terjadi saat membaca sumber daya formulir. Jadi, di bagian privat kita mendeklarasikan variabel FDummy:integer (nama dan tipe variabel bisa apa saja) dan di bagian terbitan kita mendefinisikan properti baru:

Kursor Properti: bilangan bulat dibaca FDummy;

Properti baru harus disebut Cursor, tipenya harus sesuai dengan tipe variabel yang ditentukan di atas, properti harus read-only atau write-only. Setelah mengkompilasi komponen menggunakan editor paket, Anda harus menempatkan kembali komponen TListAdd pada formulir. Anda mungkin menemukan bahwa properti Cursor tidak lagi terlihat di Object Inspector.

Sekarang mari kita mempersulit tugas ini sedikit. Misalkan Anda ingin kursor ditampilkan bukan sebagai panah, tetapi sebagai jam pasir (crHourGlass). Untuk mengubah nilai default properti, nilai baru harus ditetapkan ke variabel di konstruktor. Saat mencoba memberikan nilai baru ke Kursor di konstruktor

Kursor:=crHourGlass;

Kompiler Delphi akan mengeluarkan pesan diagnostik yang menyatakan bahwa nilai baru tidak dapat diberikan ke variabel read-only. Jika Anda membuat properti “hanya tulis” baru, kompiler akan mengeluarkan pesan diagnostik yang berbeda – tentang tipe data yang tidak kompatibel. Jika Anda mendeklarasikan variabel FDummy:TCursor dan menjadikannya hanya tulis, kompiler akan mengizinkan penetapan ini, tetapi tampilan kursor tidak akan berubah: tetap berupa panah.

Solusi sepele untuk masalah ini adalah dengan mendeklarasikan kelas turunan TCustomPanel, yang konstruktornya perlu Anda tetapkan nilai baru ke variabel Cursor, dan dari situ menghasilkan komponen TListAdd kami. Solusi ini memiliki dua kelemahan:

  1. Ini membutuhkan banyak sumber daya - metode virtual berlipat ganda.
  2. Kami menyembunyikan properti di inspektur objek dari pemrogram yang akan menggunakan komponen ini. Kami ingin bekerja sama dengan properti ini.

Oleh karena itu, solusi untuk masalah ini terlihat seperti ini: di konstruktor TListAdd kami mendeklarasikan operator:

Kursor yang Diwarisi:=crHourGlass;

dan itu saja! Ini cukup untuk mengubah kursor.

Sebelumnya, kita menggunakan fungsi word yang diwarisi hanya untuk memanggil metode leluhur. Konstruksi ini memungkinkan Anda untuk lebih memahami arti warisan sebagai referensi ke kelas leluhur. Anda dapat mengakses properti dan metode. Saat mengakses properti, Anda dapat membacanya atau memberikan nilai baru padanya; dalam hal ini, kata bantu warisan muncul di sebelah kiri tanda penugasan. Demikian pula, Anda dapat memanggil metode leluhur yang tersembunyi. Panggilan hierarki yang lebih tinggi dari kelas leluhur dilarang - konstruksi

Kursor yang diwariskan:=crHourGlass;

tidak akan dikompilasi.

Pada titik ini kami akan menganggap proyek ini selesai. Di komponen baru, kami mencegat pesan, mendeklarasikan properti, menambahkan properti dan peristiwa baru, dan menyembunyikan properti yang dideklarasikan sebelumnya. Semua metode ini digunakan untuk membuat komponen. Di bawah ini kita akan melihat metode menarik lainnya.

Menggunakan Prosedur Hook untuk Membuat Komponen

Telah disebutkan sebelumnya bahwa setiap anak TWinControl memiliki prosedur yang menerima dan memproses pesan. Jika ada referensi ke pegangan jendela (HWND), maka Anda dapat menentukan alamat prosedur ini dan, yang lebih penting, mengganti alamat ini dan memproses pesan yang diterima dengan cara Anda sendiri. Biasanya, tidak ada yang menulis penangan lengkap untuk semua pesan; metode default lama lebih sering dipanggil. Dalam hal ini, prosedur baru digunakan sebagai filter: ketika suatu peristiwa tiba, kode dijalankan. Faktanya, ini adalah "mata-mata" di TwinControl: kita diberi tahu ketika ada pesan masuk dan beberapa kode dapat dieksekusi. Jika prosedur Hook diterapkan dengan benar, TWinControl terus bekerja seperti biasa, tanpa menyadari bahwa ia membagikan pesannya kepada orang lain.

Prosedur pengait didefinisikan sebagai berikut:

Prosedur(var Pesan:TMessage) objek;

Itu bergantung pada variabel bertipe TMessage, yang berisi semua informasi tentang pesan tersebut. Namun mendefinisikan prosedur ini saja tidak cukup. Itu harus disalin untuk setiap TWinControl yang akan dilampirkan. Hal ini dicapai dengan memanggil metode WinAPI MakeObjectInstance. Metode ini mengambil metode objek sebagai parameter, membuat salinannya di memori, dan mengembalikan alamat metode baru. Jelas bahwa ini mencadangkan sumber daya sistem yang perlu dikembalikan ke sistem. Hal ini dicapai dengan memanggil metode FreeObjectInstance.

Kondisi penting lainnya: sebelum menghancurkan TWinControl, komunikasi dengan prosedur pemrosesan pesan lama harus dipulihkan, jika tidak, sumber daya tidak akan dikembalikan ke sistem. Ini berarti Anda harus mengingat penunjuk ke prosedur lama, yang dapat ditemukan dengan memanggil metode Win API GetWindowLong dengan parameter GWL_WNDPROC. Pointer ini juga akan digunakan untuk memanggil event handler default TWinControl. Metode sebaliknya, SetWindowLong, digunakan untuk mengatur prosedur Hook.

Jadi, mari kita rumuskan masalah untuk latihan berikutnya. Katakanlah kita ingin membuat komponen yang akan membuat komponen lain - turunan dari TWinControl - berbunyi bip saat tombol mouse ditekan. Jelas bahwa komponen ini tidak boleh ditampilkan selama eksekusi aplikasi, jadi kami akan memilih TComponent sebagai kelas leluhurnya. Mari kita definisikan nama kelas sebagai TBeepWnd. Di bagian privat kami mendefinisikan tiga variabel:

FOldProc,FNewProc:penunjuk; Kontrol F: Kontrol Kembar;

Dari namanya jelas kita akan mengingat link prosedur lama di variabel FOldProc, link ke prosedur baru (setelah menjalankan metode MakeObjectInstance) akan disimpan di variabel FNewProc. Dan dalam variabel FControl kita akan menyimpan link ke elemen kontrol di mana prosedur Hook saat ini “digantung”. Mari kita definisikan tiga metode di bagian yang sama:

Prosedur HookProc(var Pesan:TMessage); prosedur HookWindow(W:TWinControl); prosedur Buka Kait Jendela;

dan di bagian implementasi kami menerapkannya:

Prosedur TBeepWnd.HookProc(var Pesan:TMessage); mulai huruf Pesan.Pesan WM_LBUTTONDOWN:mulai (Tugas kita) Bip; Pesan.Hasil:=CallWindowProc(FOldProc, FControl.Handle, Pesan.Pesan, Pesan.WParam, Pesan.lParam); akhir; WM_DESTROY:begin (Saat jendela akan dihancurkan, lepaskan kait) Message.Result:=CallWindowProc(FOldProc, FControl.Handle, Message.Msg, Message.WParam, Message.lParam); Buka Kait Jendela; akhir; (Panggil pengendali default) else Message.Result:=CallWindowProc(FOldProc, FControl.Handle, Message.Msg, Message.WParam, Message.lParam); akhir; akhir;

Dalam prosedur Hook itu sendiri, sebuah pesan dicegat, yang menimbulkan reaksi - WM_LBUTTONDOWN. Selain itu, setiap prosedur Hook harus menangani pesan WM_DESTROY. Ini adalah pesan terakhir yang dikirim ke jendela sebelum dimusnahkan. Tanggapan kami adalah memulihkan metode sebelumnya dengan memanggil metode UnhookWindow yang dijelaskan di bawah. Terakhir, penangan pesan default dipanggil menggunakan metode CallWindowProc. Melupakan event handler default sama dengan melupakan warisan dalam event handler; dalam 80% kasus, hal ini akan menyebabkan perilaku aplikasi yang salah. Anda tidak boleh lupa untuk menetapkan hasil pemanggilan metode CallWindowProc ke bidang Hasil dari variabel Pesan! Kode tidak akan berfungsi dalam kasus ini!

Prosedur TBeepWnd.HookWindow(W:TWinControl); mulai jika csDesigning di ComponentState lalu mulai (Memeriksa apakah komponen pada desain atau run-time) FControl:=W; KELUAR; akhir; jika FKontrol<>nihil lalu UnhookWindow; (Lepaskan pengait jika sudah terpasang sebelumnya) jika W<>nil lalu mulai FOldProc:=pointer(GetWindowLong(W.Handle,GWL_WNDPROC)); (Menentukan alamat prosedur lama) FNewProc:=MakeObjectInstance(HookProc); (Buat salinan di memori) SetWindowLong(W.Handle,GWL_WNDPROC,integer(FNewProc)); (Tetapkan prosedur baru) akhir; Kontrol F:=W; (Simpan referensi di kontrol) akhir;

Metode ini digunakan untuk mengatur rutinitas penanganan pesan baru. Pertama, ia memeriksa pada tahap mana komponen berada: pada tahap pengembangan atau pada tahap eksekusi. Jika komponen sedang dalam tahap pengembangan, yaitu flag csDesigning disetel di properti ComponentState, maka link ke komponen tersebut akan disimpan tanpa menginstal prosedur Hook. Hal ini dilakukan untuk menghindari pemasangan prosedur Hook di lingkungan pengembangan Delphi. Jika prosedur ini sebelumnya diatur pada kontrol lain, prosedur ini dihapus dengan memanggil metode UnhookWindow. Setelah ini, alamat prosedur lama diingat (GetWindowLong), salinan dibuat di memori prosedur baru (MakeObjectInstance) dan alamat prosedur baru ditetapkan (SetWindowLong). Tipe casting dari integer ke pointer digunakan, dan sebaliknya - metode yang disebut memerlukan (atau mengembalikan) variabel dengan tipe yang tidak sesuai. Terakhir, referensi ke kontrol disimpan dalam variabel FControl, yang kita definisikan di bagian privat.

Prosedur TBeepWnd.UnhookWindow; mulai jika (FControl=nil) atau (FOldProc=nil) atau (FNewProc=nil) lalu Keluar; (Tidak ada kait yang dipasang) SetWindowLong(FControl.Handle,GWL_WNDPROC,integer(FOldProc)); (Atur prosedur jendela lama) FreeObjectInstance(FNewProc); (Sumber daya gratis) FControl:=nihil; (Memulai variabel) FOldProc:=nil; FNewProc:=nihil; akhir;

Metode ini mengembalikan event handler lama. Ini dipanggil dari metode HookProc dan juga harus dipanggil dari destruktor komponen - Hook harus dihapus baik saat jendela dihancurkan maupun saat komponen ini dihancurkan. Metode SetWindowLong dengan alamat metode lama mengembalikan penangan pesan lama. Setelah ini, Anda harus mengembalikan sumber daya ke sistem dengan memanggil metode FreeObjectInstance.

Jadi, metode dasar untuk bekerja dengan prosedur Hook telah ditentukan. Sekarang Anda perlu menulis ulang destruktor sehingga prosedur Hook dihapus ketika komponen ini dimusnahkan:

Destruktor TBeepWnd.Destroy; mulai Buka Kait Jendela; Kehancuran yang diwariskan; akhir;

Dan terakhir, di bagian yang diterbitkan kita mendefinisikan properti yang akan ditampilkan di inspektur objek:

Kontrol properti:TWinControl baca FControl tulis HookWindow;

Untuk menginstal komponen baru, kita mengacu pada metode yang telah ditentukan sebelumnya, yang ketika aplikasi sedang berjalan, akan segera “menggantung” prosedur Hook pada komponen, yang akan berbunyi bip saat tombol ditekan. Ingatlah bahwa alih-alih operator Bip, Anda dapat menulis kode apa pun yang dapat dieksekusi.

Komponen ini diuji dengan cukup sederhana: komponen tersebut ditempatkan pada formulir di mana beberapa komponen turunan TWinControl ditempatkan. Setelah memilih komponen TBeepWnd di latar belakang, mengklik mouse di bidang Kontrol di inspektur objek akan memperluas daftar yang berisi semua TWinControl yang ditentukan pada formulir. Anda harus memilih salah satunya dan meluncurkan aplikasi. Saat Anda mengklik tombol kiri mouse pada komponen yang dipilih, komponen tersebut mengeluarkan bunyi mencicit.

Editor properti dan editor komponen

Segala sesuatu yang dibahas di bagian sebelumnya berkaitan dengan pembuatan kode aplikasi yang akan didistribusikan kepada pengguna. Namun, lingkungan pengembangan Delphi memungkinkan Anda untuk memodifikasi dirinya sendiri. Ini tidak memerlukan pengetahuan bahasa khusus, karena semua metode untuk mengubah lingkungan pengembangan ditulis dalam Delphi. Di sini metode ini, yaitu editor properti dan editor komponen, dianggap sebagian - dalam hal pembuatan alat untuk bekerja dengan komponen. Saat membaca materi di bagian ini, Anda harus memahami dengan jelas bahwa pengguna akhir yang bekerja dengan aplikasi Anda tidak akan pernah melihat editor properti atau editor komponen - keduanya dibuat untuk pemrogram dan hanya bekerja di lingkungan pengembangan Delphi.

Editor properti

Selama pengembangan aplikasi, properti ditampilkan di Object Inspector. Harap dicatat bahwa properti diedit secara berbeda di Object Inspector. Beberapa properti (Lebar, Keterangan) hanya dapat diberi nilai teks baru. Properti bertipe Cursor menyediakan daftar drop-down yang dapat Anda klik untuk memilih nilai. Properti bertipe TFont memiliki tanda "+" di sebelah kiri; Ketika Anda mengkliknya, itu meluas, memungkinkan Anda untuk mengubah masing-masing bidang. Selain itu, di sebelah kanan terdapat tombol tiga titik (tombol elips), jika diklik akan muncul dialog editor properti.

Masing-masing properti di atas memiliki editornya sendiri, dan keuntungan besar dari lingkungan pengembangan Delphi adalah kemampuan untuk membuat editor properti Anda sendiri. Editor properti baru cukup umum di antara komponen terdistribusi. Namun pengujian tersebut harus ditangani dengan hati-hati: jalankan pengujian terlebih dahulu pada komputer di mana Anda dapat menginstal ulang Delphi jika perlu. Biasanya, mereka dibuat oleh pemrogram yang berkualifikasi dan tidak ada keluhan tentang kodenya, tetapi mereka sering lupa menyertakan DLL apa pun di editor properti terdistribusi. Setelah menginstal editor seperti itu, kami mendapatkan sejumlah properti yang tidak dapat diedit - editor lama diblokir, dan yang baru tidak berfungsi...

Sebelum membuat editor properti baru, masuk akal untuk memikirkan apakah hal ini layak dilakukan - Anda mungkin dapat menemukan editor yang cocok di antara editor standar. Jika Anda harus membuat editor properti, Anda harus mengikuti aturan: Anda harus menghindari membuat editor untuk tipe data standar (integer, string, dll.). Pemrogram lain sudah terbiasa dengan editor standar, dan mereka mungkin tidak menyukai editor Anda. Oleh karena itu, Anda harus bersikap rendah hati dan mendaftarkan editor untuk kelas Anda, dan bukan untuk kelas TComponent. Jika pemrogram menyukai editor properti Anda, sebagian besar dari mereka akan dapat mengubah registrasinya sendiri sehingga editor berfungsi untuk semua komponen. Masalah pendaftaran editor akan kita bahas di bawah ini.

Jadi, mari kita ajukan masalah model, yang implementasinya memerlukan implementasi editor properti. Misalkan beberapa komponen memiliki properti - hari dalam seminggu. Pada prinsipnya, untuk memasukkan hari dalam seminggu, Anda dapat menggunakan editor standar dengan daftar drop-down. Namun, kami ingin pemrogram pada tahap pengembangan dapat memasukkan hari dalam seminggu, menentukan nomor serinya (1 - Senin, 2 - Selasa, dll.), atau teks dalam bahasa nasional atau Inggris. Saat memasukkan teks, diperbolehkan mencampur huruf besar dan kecil.

Pertama-tama, Anda perlu membuat komponen yang akan menyimpan hari dalam seminggu. Mari buat komponen baru dengan memanggil perintah Komponen/Komponen baru. Mari pilih TComponent sebagai kelas leluhur dan beri nama kelas baru TDayStore. Setelah itu, instal komponen di palet. Sekarang kita perlu memutuskan dalam bentuk apa menyimpan hari dalam seminggu. Jelas bahwa untuk identifikasi yang jelas dan penghematan sumber daya, data tersebut harus disimpan sebagai bilangan bulat dengan rentang valid 1-7. Namun, jika kita akan membuat editor properti, kita harus mengingat aturan tentang tidak membuat editor baru untuk tipe yang sudah ada. Oleh karena itu, kami akan mendefinisikan tipe baru - TDayWeek, dan semua operasi dengannya akan dilakukan seperti bilangan bulat. Mari kita definisikan variabel FDay di bagian privat komponen. Karena variabel ini akan diinisialisasi ke 0 ketika konstruktor default dijalankan, dan angka ini berada di luar nilai yang diizinkan, maka konstruktor harus ditulis ulang. Terakhir, mari kita definisikan properti DayWeek di bagian yang diterbitkan untuk menampilkannya di pemeriksa objek. Komponen terakhir terlihat seperti ini:

Ketik TDayWeek=ketik bilangan bulat; TDayStore = class(TComponent) private ( Deklarasi pribadi ) FDay:TDayWeek; dilindungi ( Deklarasi yang dilindungi ) publik ( Deklarasi publik ) konstruktor Create(AOwner:TComponent); mengesampingkan; diterbitkan ( Deklarasi yang diterbitkan ) properti DayWeek:TDayWeek baca FDay tulis FDay; akhir; ... konstruktor implementasi TDayStore.Create(AOwner:TComponent); mulai mewarisi Buat(Pemilik); Hari F:=1; akhir;

Perlu memperhatikan konstruksi langka dari definisi tipe baru

TDayWeek=ketik bilangan bulat;

Dengan demikian, tipe data baru diperkenalkan, yang memiliki ukuran yang sama dengan tipe integer; semua operasi pada tipe data ini dilakukan seperti pada integer. Maksud dari operasi ini adalah untuk mendeklarasikan tipe data baru sehingga editor properti kita dapat diterapkan secara khusus padanya dan tidak mempengaruhi tipe data lainnya.

Sekarang mari kita buat editor untuk properti TDayWeek. Untuk melakukan ini, tambahkan formulir baru ke proyek yang ada, ingatlah dengan nama yang sesuai (DayPropE.pas) dan kecualikan dari proyek. Setelah ini, kita akan membuka formulir sebagai file terpisah dan mengimplementasikan editor properti di dalamnya. Pada tahap pertama kita tidak membutuhkan formulir, tapi nanti kita akan melakukan dialog mengenainya.

Modul untuk membuat editor properti disebut DsgnIntf.pas (Design Interface), yang mendefinisikan kelas dasar TPropertyEditor dan kelas turunan yang dimaksudkan untuk mengedit properti standar - TIntegerProperty, TFloatProperty, TStringProperty, dll. Mekanisme pengoperasian editor properti adalah sebagai berikut:

  1. Itu didaftarkan di lingkungan pengembangan Delphi dengan memanggil metode RegisterPropertyEditor. Metode ini mengambil nilai berikut sebagai parameter:

    a) informasi tentang jenis properti pengeditan yang dimaksudkan oleh editor ini. Karena informasi ini, kami harus mendefinisikan TDayWeek tipe baru;

    b) informasi tentang komponen di mana editor ini berlaku. Editor akan dipanggil tidak hanya untuk komponen tertentu, tetapi juga untuk semua turunannya. Jika Anda menyetelnya ke TComponent, editor akan dipanggil untuk komponen apa pun;

    c) nama properti yang digunakan editor ini. Jika nama adalah string kosong, dua filter di atas digunakan;

  2. Metode GetValue dipanggil ketika nilai properti saat ini perlu dibaca dari komponen. Untuk properti apa pun, metode ini mengembalikan string yang ditempatkan di pemeriksa objek.
  3. Metode SetValue dipanggil ketika programmer telah memasukkan nilai properti baru di Object Inspector. String baru diteruskan sebagai parameter. Dalam metodenya, harus dianalisis dan diubah menjadi jenis properti yang sedang diedit.

Metode GetValue dan SetValue bersifat virtual; ketika ditulis ulang, editor properti baru akan dibuat. Jadi sekarang kita bisa mulai membuat editor properti baru.

Mari kita lihat modul DsgnIntf ​​​​di bagian penggunaan modul DayPropE.pas dan tentukan kelas baru di bagian Antarmuka:

Ketik TDWPropED=class(TPropertyEditor) fungsi publik GetValue:string; mengesampingkan; prosedur SetValue(Nilai const:string); mengesampingkan; akhir;

Bagian implementasi harus menerapkan kedua metode ini. Dalam hal ini, kita juga memerlukan daftar nama hari dalam seminggu - dalam rumusan awal masalah, programmer harus dapat memasukkan hari dalam seminggu:

Const DayWeek:array of string = ("Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"); DayWeekEn:array of string = ("Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu");

Publikasi tentang topik tersebut