Pembuatan menu aneh DELPHI
Penerjemah: Li Junyu email: [email protected],[email protected]
Menu Kustom, Teks, Garis / Delphi 4, 5
Menu khusus, teks, baris/Delphi 4, 5
Menu Mewah, dll.
Menu aneh, dll.
Menu Kustom, Teks Diputar, dan Garis Khusus
Menu yang disesuaikan, teks yang diputar, dan garis khusus
Sebelum Delphi 4, sulit untuk mengkustomisasi menu (menambahkan bitmap, mengubah font, dll.), karena gambar pemilik (yaitu gambar khusus) - meskipun diterapkan oleh Windows - tidak diekspos oleh kelas TMainMenu. Namun, situasi ini telah diperbaiki, dan kami dapat mengatur menu sesuai keinginan kami.
Sebelum Delphi 4, sulit untuk menyesuaikan menu (seperti menambahkan gambar BMP, mengubah font, dll.) karena acara menggambar pemilik (yaitu, acara menggambar khusus) - meskipun dijalankan oleh Windows, tidak muncul di Kelas TMainMenu.
Situasi ini telah berubah, dan kini kami memiliki kemampuan untuk menyesuaikan menu.
Artikel ini akan menyoroti beberapa teknik yang dapat Anda gunakan untuk menyesuaikan tampilan menu di aplikasi Delphi Anda. Kami akan membahas penempatan teks, ukuran menu, penetapan font, dan penggunaan bitmap dan bentuk untuk menyempurnakan tampilan menu. Sekadar bersenang-senang, artikel ini juga dilengkapi teknik untuk membuat teks yang diputar dan garis khusus. Semua teknik yang dibahas dalam artikel ini didemonstrasikan dalam Proyek yang tersedia untuk diunduh.
Artikel ini akan fokus pada beberapa teknik yang dapat Anda gunakan untuk menyesuaikan tampilan menu di aplikasi DELPHI Anda. Kami akan membahas penempatan teks, ukuran menu, pengaturan font, dan penyempurnaan dengan file BMP dan kontrol SHAPE . Sekadar bersenang-senang, artikel ini juga akan menampilkan teknik close-up untuk memutar teks dan garis khusus. Semua teknik yang dibahas dalam artikel ini telah di-debug dalam file proyek dan dapat diunduh secara online.
Font dan Ukuran Khusus
Atur font dan ukuran
Untuk membuat menu kustom, setel properti OwnerDraw dari komponen menu -TMainMenu atau TPopupMenu - ke True, dan sediakan pengendali peristiwa untuk peristiwa OnDrawItem dan OnMeasureItem. Misalnya, pengendali peristiwa OnMeasureItem dideklarasikan seperti ini:
Untuk membuat menu kustom, atur properti OwnerDraw dari komponen TmainMenu atau TpopupMenu ke TRUE, dan buat prosedur kejadian OnDrawItem dan OnMeasureItem. Misalnya, prosedur kejadian OnMeasureItem dapat dideklarasikan sebagai berikut:
procedure TForm1.Option1MeasureItem(Pengirim: TObject;
ACanvas: TCanvas; var Lebar, Tinggi: Integer);
Atur variabel Lebar dan Tinggi untuk menyesuaikan ukuran item menu. Event handler OnDrawItem adalah tempat semua kerja keras dilakukan; di situlah Anda menggambar menu dan membuat pengaturan khusus untuk menggambar opsi menu dengan font Times New Roman , misalnya, Anda harus melakukan sesuatu seperti ini:
Atur variabel Lebar dan Tinggi item menu dalam prosedur acara di atas ke ukuran yang sesuai. Semua hal utama dipicu oleh acara OnDrawItem; di sinilah Anda akan menggambar ulang menu dan membuat pengaturan khusus. Misalnya, untuk menggambar ulang item menu dengan font Times New Roman, Anda dapat melakukan hal berikut:
prosedur TForm1.Times1DrawItem(Pengirim: TObject;
ACanvas: TCanvas; ARect: TRect;
mulai
ACanvas.Font.Nama := 'Times New Roman';
ACanvas.TextOut(ARect.Left+1, ARect.Top+1,
(Pengirim sebagai TMenuItem).Caption);
akhir;
Namun kode ini memiliki kelemahan. Jika dijalankan, keterangan menu akan digambar sejajar dengan batas kiri menu. Biasanya ini bukan perilaku default Windows, ada ruang untuk meletakkan bitmap dan tanda centang di menu. Anda harus menghitung ruang yang dibutuhkan untuk tanda centang ini dengan kode seperti yang ditunjukkan pada Gambar 1. Gambar 2 menunjukkan menu yang dihasilkan.
Namun kode ini cacat. Jika Anda menjalankan kode ini, keterangan item menu akan disejajarkan di sebelah kiri item menu. Ini bukan perilaku default Windows. Biasanya, ada ruang di sisi kiri menu untuk gambar BMP dan pilihan tanda. Oleh karena itu, Anda harus menggunakan kode untuk menghitung berapa banyak ruang yang diperlukan untuk menempatkan bendera pilihan, seperti yang ditunjukkan pada Gambar 1. Gambar 2 menunjukkan menu yang sedang beraksi.
prosedur TForm1.Times2DrawItem(Pengirim: TObject;
ACanvas: TCanvas; ARect: TRect;
var
dwCheck : Bilangan Bulat;
Keterangan Menu: string;
mulai
// Dapatkan dimensi tanda centang.
Dapatkan jumlah piksel yang diperlukan untuk logo pilihan
dwCheck := GetSystemMetrics(SM_CXMENUCHECK);
// Sesuaikan posisi kiri.
Sesuaikan posisi kiri
ARect.Left := ARect.Left + LoWord(dwCheck) + 1;
MenuCaption := (Pengirim sebagai TMenuItem).Caption;
// Nama font adalah keterangan menu.
ACanvas.Font.Nama := 'Times New Roman';
// Menggambar teksnya.
menggambar teks
DrawText(ACanvas.Handle, PChar(MenuCaption),
Panjang(MenuCaption), ARect, 0);
akhir;
Gambar 1: Pengendali kejadian OnDrawItem ini menempatkan teks item menu dengan benar.
[Penerjemah menghilangkan semua Gambar, sama di bawah]
Gambar 2: Menu yang digambar dengan font khusus.
Jika teks terlalu besar untuk digambar di menu, Windows akan memotongnya agar pas. Oleh karena itu, Anda harus mengatur ukuran item menu agar semua teks dapat digambar. Ini adalah peran event handler OnMeasureItem yang ditunjukkan pada Gambar 3 .
Jika teksnya terlalu panjang, Windows akan secara otomatis memotongnya agar pas. Oleh karena itu, Anda harus mengatur ukuran menu agar semua teks dapat ditampilkan. Hal yang sama juga berlaku pada event OnMeasureItem, yang dapat dilihat pada Gambar 3.
procedure TForm1.Times2MeasureItem(Pengirim: TObject;
ACanvas: TCanvas; var Lebar, Tinggi: Integer);
mulai
ACanvas.Font.Nama := 'Times New Roman';
ACanvas.Font.Gaya := [];
// Lebar adalah ruang pemeriksaan menu
Panjang ini merupakan panjang tanda pemilihan menu
// ditambah lebar teks item.
Ditambah panjang item menu
Lebar := GetSystemMetrics(SM_CXMENUCHECK) +
ACanvas.TextWidth((Pengirim sebagai TMenuItem).Caption) + 2;
Tinggi := ACanvas.TextHeight(
(Pengirim sebagai TMenuItem).Caption) + 2;
akhir;
Gambar 3: Pengendali kejadian OnMeasureItem ini memastikan bahwa suatu item sesuai dengan menunya.
Bentuk Kustom dan Bitmap
Siapkan grafik dan bitmap
Dimungkinkan juga untuk menyesuaikan item menu dengan menyertakan bitmap atau bentuk lainnya. Untuk menambahkan bitmap, cukup tetapkan file bitmap ke properti TMenuItem.Bitmap - dengan Object Inspector pada waktu desain, atau dengan kode pada waktu proses sebagai keterangan item menu, Anda dapat menggunakan event handler OnDrawItem yang ditunjukkan pada Gambar 4. Gambar 5 menunjukkan hasilnya.
Dimungkinkan untuk mengatur menu dengan bitmap dan grafik lainnya. Untuk menambahkan bitmap, cukup tetapkan file BMP ke properti Bitmap TmenuItem di Object Inspector pada waktu desain, atau gunakan kode saat runtime. Untuk mengganti judul menu dengan persegi panjang berwarna, Anda dapat menggunakan event OnDrawItem, seperti yang ditunjukkan pada Gambar 4. Ditunjukkan pada Gambar 5 adalah hasilnya.
prosedur TForm1.ColorDrawItem(Pengirim: TObject;
ACanvas: TCanvas; ARect: TRect;
var
dwCheck : Bilangan Bulat;
MenuWarna: TWarna;
mulai
// Dapatkan dimensi tanda centang.
dwCheck := GetSystemMetrics(SM_CXMENUCHECK);
ARect.Left := ARect.Left + LoWord(dwCheck);
// Ubah keterangan item menu menjadi warna.
Ubah judul item menu menjadi warna
Warna Menu :=
StringToColor((Pengirim sebagai TMenuItem).Caption);
// Mengubah warna kuas kanvas.
Ubah warna kuas kanvas
ACanvas.Brush.Warna := MenuWarna;
// Menggambar persegi panjang. Jika item dipilih,
Menggambar persegi panjang jika item menu dipilih
// menggambar batas.
menggambar batas
jika Dipilih maka
ACanvas.Pen.Style := psSolid
kalau tidak
ACanvas.Pen.Style := psClear;
ACanvas.Rectangle(ARect.Left, ARect.Top,
ARect.Right, ARect.Bottom);
akhir;
Gambar 4: Menggunakan event OnDrawItem untuk menggambar persegi panjang berwarna pada item menu.
Gambar 5: Menu yang menampilkan persegi panjang berwarna sebagai item.
Hanya ada satu kendala. Jika Anda menggunakan Delphi 5, Anda harus mengatur properti AutoHotkeys menu ke maManual. Jika Anda membiarkannya sebagai default, maAutomatic, Delphi akan menambahkan karakter ampersand (&) ke keterangan, yang akan merusaknya. Solusi lain adalah menghapus ampersand dengan fungsi StripHotKey.
Pendekatan yang lebih populer adalah jika Anda menggunakan Delphi 5, Anda harus mengatur properti AutoHotkeys menu ke maManual. Jika Anda tidak melakukan ini dan membiarkan nilai default maAutomatic, Delphi akan secara otomatis menambahkan ampersand ke judul, yang akan merusak kode. Solusi lain adalah dengan menggunakan fungsi StripHotKey untuk menghapus ampersand.
Cara lain untuk menggunakan event OnDrawItem dan OnMeasureItem adalah dengan menulis teks secara vertikal pada menu (seperti yang ditunjukkan pada Gambar 7). Untuk melakukan ini, Anda harus membuat font yang diputar. Ini hanya mungkin menggunakan fungsi Windows API CreateFont atau CreateLogFont (lihat (tip "Teks yang Diputar" nanti di artikel ini). Maka Anda harus menggambarnya di event handler OnDrawItem. Event ini diaktifkan setiap kali item menu digambar, jadi jika ada menu 20 item, akan digambar 20 kali. Untuk membuatnya lebih cepat, teks vertikal akan digambar hanya ketika item menu dipilih (karena hanya ada satu item menu yang dipilih pada satu waktu). , dan Gambar 7 menunjukkan hasil run-time.
Kegunaan lain dari event OnDrawItem dan OnMeasureItem adalah untuk menulis teks vertikal di sebelah menu (seperti yang ditunjukkan pada Gambar 7). Untuk melakukan ini, Anda harus membuat font yang diputar. Satu-satunya cara adalah dengan menggunakan fungsi CreateFont atau CreateLogFont pada Windows API (lihat teknik "teks yang diputar" nanti di artikel ini). Jadi harus digambar ulang di event OnDrawItem. Event ini dijalankan ketika item menu ditarik keluar, jadi jika suatu menu mempunyai 20 item, maka akan dieksekusi sebanyak 20 kali. Untuk membuatnya lebih cepat, teks vertikal dapat digambar ulang setiap kali item menu dipilih (walaupun hanya satu item menu yang dipilih dalam satu waktu). Gambar 6 menunjukkan bagaimana kode dijalankan, sedangkan Gambar 7 menunjukkan hasilnya.
prosedur TForm1.VerticalDrawItem(Pengirim: TObject;
ACanvas: TCanvas; ARect: TRect;
var
jika : TLogFont;
Font Lama:HFont;
ke depan, ke belakang: LongInt;
Persegi Panjang: Benar;
dwCheck : LongInt;
Tinggi Menu : Integer;
mulai
dwCheck := GetSystemMetrics(SM_CXMENUCHECK);
// Ini akan dilakukan satu kali, saat item dipilih.
Ini akan dijalankan ketika item menu dipilih
jika Dipilih maka mulai
// Membuat font yang diputar.
Buat font yang diputar
FillChar(lf, SizeOf(lf), 0);
lf.lfTinggi := -14;
lf.lfEscapement := 900;
lf.lfOrientasi := 900;
lf.lfBerat := Fw_Bold;
StrPCopy(lf.lfFaceName, 'Arial');
// Pilih font ini untuk digambar.
Pilih font ini untuk digambar
OldFont := SelectObject(ACanvas.Handle,
CreateFontIndirect(lf));
// Mengubah warna latar depan dan latar belakang.
Mengubah warna latar depan dan latar belakang
clFore := SetTextColor(ACanvas.Handle, clSilver);
clBack := SetBkColor(ACanvas.Handle, clBlack);
// Dapatkan ketinggian menu.
Dapatkan tinggi menu
MenuTinggi := (ARect.Bottom-ARect.Top) *
((Pengirim sebagai TMenuItem).Induk sebagai TMenuItem).Count;
Persegi Panjang := Persegi(-1, 0, dwCheck-1, MenuHeight);
// Menggambar teksnya.
menggambar teks
ExtTextOut(ACanvas.Handle, -1, MenuHeight, Eto_Clipped,
@Rectang, 'Buatan Borland', 15, nihil);
// Kembali ke keadaan semula.
Kembali ke keadaan semula
DeleteObject(SelectObject(ACanvas.Handle, OldFont));
SetTextColor(ACanvas.Handle,clFore);
SetBkColor(ACanvas.Handle, clBack);
akhir;
// Gambar teks menu sebenarnya.
Gambar teks item menu sebenarnya
ARect.Left := ARect.Left + LoWord(dwCheck) + 2;
DrawText(ACanvas.Handle,
PChar((Pengirim sebagai TMenuItem).Caption),
Panjang((Pengirim sebagai TMenuItem).Caption), ARect, 0);
akhir;
Gambar 6: Menggunakan OnDrawItem untuk menggambar teks vertikal pada menu.
Gambar 7: Menu dengan teks vertikal.
Satu detail yang rumit adalah mengetahui di mana harus mulai menggambar teks. Ini harus dimulai di bagian bawah item terakhir pada menu. Untuk mendapatkan posisinya, kita mendapatkan ketinggian item menu, menggunakan:
Anda harus tahu di mana harus mulai menggambar teks. Ini harus dimulai di bagian bawah item terakhir dalam menu. Untuk mendapatkan posisi ini, kita mendapatkan ketinggian item menu sebagai berikut:
ARect.Top - ARect.Bawah
dan kalikan dengan jumlah item di menu:
Dan dikalikan dengan jumlah item menu:
(((Pengirim sebagai TMenuItem).Induk sebagai TMenuItem).Count)
Teks yang Diputar
teks diputar
Windows API memungkinkan Anda menggambar teks di sudut mana pun. Untuk melakukan ini di Delphi, Anda harus menggunakan fungsi API CreateFont atau CreateFontIndirect.
Windows API memungkinkan Anda menggambar teks dari sudut mana pun. Untuk melakukan hal ini di Delphi, Anda harus menggunakan dua fungsi API CreateFont atau CreateFontIndirect. Gambar 8 menunjukkan bagaimana CreateFont dideklarasikan.
fungsi BuatFont(
nTinggi, // Tinggi logis font.
nLebar, // Lebar karakter rata-rata logis.
nEscapement, // Sudut escapement
nOrientasi, // Sudut orientasi garis dasar.
fnWeight: Integer; // Berat font
fdwItalic, // Bendera atribut miring.
fdwUnderline, // Garis bawahi tanda atribut
fdwStrikeOut, // Tanda atribut dicoret
fdwCharSet // Pengidentifikasi kumpulan karakter
fdwOutputPrecision, // Presisi keluaran.
fdwClipPrecision, // Presisi kliping.
fdwQuality, // Kualitas keluaran.
fdwPitchAndFamily: DWORD; // Pitch dan keluarga.
lpszFace: PChar // Penunjuk ke string nama jenis huruf.
): HFONT;
Gambar 8: Deklarasi Object Pascal untuk fungsi CreateFont Windows API.
Meskipun fungsi ini memiliki banyak parameter, Anda biasanya hanya ingin mengubah satu atau dua atribut teks. Dalam kasus seperti ini, Anda sebaiknya menggunakan fungsi CreateFontIndirect. Fungsi ini hanya memerlukan satu argumen - record bertipe TLogFont, seperti yang ditunjukkan pada Gambar 9.
Meskipun fungsi ini memerlukan banyak parameter, Anda biasanya hanya perlu mengubah satu atau dua properti teks. Dalam hal ini, Anda akan menggunakan fungsi CreateFontIndirect sebagai gantinya. Ini hanya memerlukan satu parameter - parameter tipe rekaman TlogFont, seperti yang dapat dilihat pada Gambar 9.
tagLOGFONTA = catatan yang dikemas
jikaTinggi: Longint;
jikaLebar: Longint;
Jika Pelarian: Longint;
lfOrientasi: Longint;
jikaBerat: Longint;
lfItalic: Byte;
jikaGaris Bawah: Byte;
jikaStrikeOut: Byte;
lfCharSet: Byte;
lfOutPrecision: Byte;
lfClipPrecision: Byte;
jikaKualitas: Byte;
lfPitchAndFamily: Byte;
lfFaceName: array[0..LF_FACESIZE - 1] dari AnsiChar;
akhir;
TLogFontA = tagLOGFONTA;
TLogFont = TLogFontA;
Gambar 9: Catatan TLogFont.
Melihat catatan ini, Anda akan melihat anggotanya cocok dengan parameter untuk fungsi CreateFont. Keuntungan menggunakan kombinasi fungsi/catatan ini adalah Anda dapat mengisi anggota catatan dengan font yang dikenal menggunakan fungsi GetObject API, mengubah anggota Anda. inginkan, dan buat font baru.
Jika Anda melihat lebih dekat pada tipe rekaman ini, Anda akan menemukan bahwa anggotanya sangat mirip dengan parameter fungsi CreateFont. Keuntungan menggunakan kombinasi fungsi/record ini adalah Anda dapat menggunakan fungsi GetObject API untuk mengisi nilai anggota record ini dengan font yang dikenal, lalu mengubah nilai anggota yang ingin Anda ubah untuk menghasilkan font baru.
Untuk menggambar teks yang diputar, satu-satunya anggota yang harus Anda ubah adalah lfEscapement, yang mengatur sudut teks dalam sepersepuluh derajat. Jadi, jika Anda ingin teks digambar pada 45 derajat, Anda harus mengatur lfEscapement ke 450.
Untuk menggambar teks yang diputar, satu-satunya anggota yang perlu Anda ubah adalah lfEscapement, yang menetapkan sudut font dalam sepersepuluh derajat. Jadi jika ingin karakternya berputar 45 derajat, Anda harus mengaturnya
Jika pelarian adalah 450.
Perhatikan bahwa ada tanda untuk menggambar teks miring, garis bawah, dan coretan, tetapi tidak ada tanda untuk menggambar teks tebal. Hal ini dilakukan dengan anggota lfWeight, angka antara 0 dan 1000. 400 adalah teks normal, nilainya di atas ini. gambar teks tebal, dan nilai di bawahnya gambar teks terang.
Perhatikan bahwa ada cukup banyak penanda untuk mencetak miring, menggarisbawahi, dan menyorot teks, tetapi tidak ada penanda untuk membuat teks tebal. Hal ini karena anggota lfWeight digunakan sebagai gantinya, dan nilai anggota ini antara 0 dan 1000. 400 adalah nilai normal, nilai apa pun di atas ini adalah nilai tebal, dan nilai apa pun di bawah ini adalah nilai tipis.
Kode pada Gambar 10 menggambar teks pada sudut mulai dari 0 derajat hingga 360 derajat, pada interval 20 derajat. Ini adalah event handler OnPaint formulir, sehingga teks digambar ulang setiap kali formulir dicat.
Kode pada Gambar 10 menggambar karakter setiap 20 derajat dari 0 hingga 360 derajat. Hal ini dipicu dalam event OnPaint formulir, sehingga teks digambar ulang setiap kali formulir dicat. Efeknya dapat dilihat pada Gambar 11.
prosedur TForm1.FormPaint(Pengirim: TObject);
var
Font Lama, Font Baru: hFont;
LogFont: TLogFont;
saya : Bilangan bulat;
mulai
// Menangani font kanvas.
Mendapatkan pegangan pada objek font formulir
OldFont := Kanvas.Font.Handle;
saya := 0;
// Gambar transparan.
Tetapkan properti transparansi
SetBkMode(Kanvas.Handle, Transparan);
// Isi struktur LogFont dengan informasi
Isi struktur LogFont dengan informasi
// dari font saat ini.
dari font saat ini
GetObject(OldFont, Sizeof(LogFont), @LogFont);
// Sudut berkisar dari 0 hingga 360.
dari 0 hingga 360 derajat
sementara i <3600 dimulai
// Atur escapement ke sudut baru.
Atur orientasi teks ke sudut baru
LogFont.lfEscapement := i;
//Buat font baru.
Buat font baru
NewFont := CreateFontIndirect(LogFont);
// Pilih font yang akan digambar.
Pilih font untuk keluaran
SelectObject(Canvas.Handle, NewFont);
// Menggambar teks di tengah formulir.
Keluaran teks di tengah formulir
TextOut(Canvas.Handle, div Lebar Klien 2,
ClientHeight div 2, 'Teks Diputar', 21);
// Bersihkan.
Jernih
DeleteObject(SelectObject(Canvas.Handle, OldFont));
// Menambah sudut sebesar 20 derajat.
meningkat setiap 20 derajat
Inc(i, 200);
akhir;
akhir;
Gambar 10: Kode untuk menggambar teks yang diputar dalam interval 20 derajat.
Gambar 11: Teks diputar 360 derajat.
Font formulir disetel ke Arial, font TrueType. Kode ini hanya berfungsi dengan font TrueType; font jenis lain tidak mendukung rotasi teks. Untuk mendapatkan pengaturan font saat ini dan mengisi struktur TLogFont, Anda harus menggunakan fungsi GetObject API. Kode pada Gambar 12 menunjukkan cara mengisi dan menampilkan pengaturan TLogFont untuk font formulir.
Font formulir ini diatur ke Arial, font TrueType. Kode ini hanya berjalan pada font TrueType; font lain tidak mendukung rotasi teks. Untuk mendapatkan pengaturan font saat ini dan mengisi struktur TlogFont, Anda harus menggunakan fungsi GetObject API. Pada kode pada Gambar 12 terlihat cara mengisi dan menampilkan pengaturan TlogFont pada form.
prosedur TForm1.Info1Click(Pengirim: TObject);
var
LogFont: TLogFont;
mulai
// Isi struktur LogFont dengan informasi
Isi nilai anggota struktur LogFont
// dari font saat ini.
dari font saat ini
GetObject(Canvas.Font.Handle, Sizeof(LogFont), @LogFont);
// Menampilkan informasi font.
Tampilkan informasi font
dengan LogFont lakukan ShowMessage(
'lfHeight: ' + IntToStr(lfHeight) + #13 +
'lfWidth: ' + IntToStr(lfWidth) + #13 +
'lfEscapement: '+IntToStr(lfEscapement) + #13 +
'lfOrientasi: ' + IntToStr(lfOrientasi) + #13 +
'lfBerat: ' + IntToStr(lfBerat) + #13 +
'lfItalic: ' + IntToStr(lfItalic) + #13 +
'lfUnderline: ' + IntToStr(lfUnderline) + #13 +
'lfStrikeOut: ' + IntToStr(lfStrikeOut) + #13 +
'lfCharSet: ' + IntToStr(lfCharSet) + #13 +
'lfOutPrecision: ' + IntToStr(lfOutPrecision) + #13 +
'lfClipPrecision: ' + IntToStr(lfClipPrecision) + #13 +
'lfKualitas: ' + IntToStr(lfKualitas) + #13 +
'lfPitchAndFamily: '+IntToStr(lfPitchAndFamily) + #13 +
'lfFaceName: ' + string(lfFaceName));
akhir;
Gambar 12: Mendapatkan dan menampilkan atribut font.
Setelah Anda memiliki pengaturan dalam struktur TLogFont, satu-satunya perubahan yang tersisa adalah mengatur lfEscapement ke sudut yang diinginkan dan membuat font baru dengan CreateFontIndirect. Sebelum menggunakan font baru ini, font tersebut harus dipilih dengan SelectObject font baru ini ke pegangan font kanvas, sebelum menggambar teks. Setelah menggambar teks, pekerjaan ini harus dibalik; tidak terhapus, akan terjadi kebocoran memori, dan - jika rutinitas dijalankan berkali-kali - Windows (terutama 95/98) akan kehabisan sumber daya, dan crash.
Setelah Anda menyiapkan struktur TlogFont, satu-satunya hal yang perlu dilakukan adalah mengubah nilai lfEscapement ke nilai target dan menggunakan CreateFontIndirect untuk menghasilkan font baru. Sebelum menggunakan font baru ini, Anda harus menggunakan SelectObject untuk memilihnya. Metode lain adalah dengan menggunakan pegangan objek font baru ini ke pegangan objek font kanvas formulir sebelum menggambar teks. Setelah teks digambar, proses dimulai; font lama harus dipilih dan font baru dihapus. Jika font baru tidak dihapus, maka akan menyebabkan kebocoran memori, dan -----jika program dijalankan berkali-kali------ Windows (terutama 95/98) akan kehabisan sumber daya, dan
menabrak.
Garis Bergaya
garis populer
Saat Anda menggambar garis, piksel individual biasanya tidak menjadi masalah; Anda cukup mengatur gaya garis, dan itu digambar oleh Windows. Namun terkadang, Anda perlu melakukan sesuatu yang istimewa dan menggambar gaya garis yang tidak disediakan oleh Windows menggunakan fungsi Windows API bernama LineDDA, yang didefinisikan pada Gambar 13.
Saat Anda menggambar garis, piksel individual biasanya tidak penting; Anda cukup mengatur jenis garis dan diserahkan kepada Windows untuk menggambarnya. Namun terkadang, Anda ingin melakukan beberapa tipe garis khusus yang tidak disediakan Windows. Hal ini dapat dicapai dengan menggunakan fungsi API yang disebut LineDDA, yang definisinya dapat dilihat pada Gambar 13.
fungsi GarisDDA(
nXStart, //koordinat x titik awal garis.
Titik awal koordinat X
nYStart, //koordinat y titik awal garis.
Koordinat Y titik awal
nXEnd, // koordinat x titik akhir garis.
Titik akhir koordinat X
YEnd : Integer; //koordinat y dari titik akhir garis.
Titik akhir koordinat Y
// Alamat fungsi panggilan balik yang ditentukan aplikasi.
Alamat fungsi panggilan balik yang ditentukan aplikasi
lpLineFunc: TFNLineDDAProc;
lpData : LPARAM // Alamat data yang ditentukan aplikasi.
Alamat data yang ditentukan aplikasi
): BOOL;
Gambar 13: Deklarasi Objek Pascal untuk fungsi Windows API, LineDDA.
Empat parameter pertama adalah titik awal dan akhir garis. Parameter kelima adalah fungsi panggilan balik yang akan dipanggil setiap kali piksel harus digambar. Anda meletakkan rutinitas menggambar di sana diteruskan ke fungsi panggilan balik. Anda dapat meneruskan Integer atau penunjuk apa pun ke fungsi tersebut, karena ini adalah LParam (di Win32, ini diterjemahkan ke Longint).
Empat parameter pertama adalah titik awal dan akhir garis. Parameter kelima adalah fungsi panggilan balik yang akan dipanggil setiap kali piksel digambar. Anda dapat menulis tentang proses menggambar Anda di sini. Parameter terakhir ditentukan pengguna dan dapat diteruskan ke fungsi panggilan balik. Anda dapat meneruskan bilangan bulat atau penunjuk apa pun ke fungsi ini karena memang demikian
Tipe Lparam (di WIN32 diartikan sebagai tipe Longint). Fungsi callback ini harus menggunakan form seperti berikut:
prosedur CallBackDDA(x, y: Integer;
UserParam: LParam);
di mana x dan y adalah koordinat titik yang digambar, dan UserParam adalah parameter yang diteruskan ke fungsi. Fungsi ini harus dideklarasikan sebagai stdcall. Rutin pada Gambar 14 menggambar garis bitmap, dan Gambar 15 menunjukkan hasilnya.
Di sini X dan Y adalah titik koordinat yang digambar, dan UserParam adalah parameternya. Fungsi ini harus didefinisikan sebagai stdcall. Program pada Gambar 14 memplot garis BMP, dan Gambar 15 menampilkan hasilnya.
jenis
TForm1 = kelas(TForm)
Daftar Gambar1: Daftar Gambar;
prosedur FormPaint(Pengirim: TObject);
prosedur FormResize(Pengirim: TObject);
akhir;
var
Formulir1: TForm1;
prosedur CallDDA(x, y: Integer; Bentuk: TForm1);
pelaksanaan
{ $R *.DFM }
prosedur CallDDA(x, y: Integer; Bentuk: TForm1);
mulai
jika x mod 13 = 0 maka
Formulir.ImageList1.Draw(Formulir.Kanvas, x, y, 0);
akhir;
prosedur TForm1.FormPaint(Pengirim: TObject);
mulai
LineDDA(0, 0, Lebar Klien, Tinggi Klien,
@CallDDA, Integer (Diri));
akhir;
prosedur TForm1.FormResize(Pengirim: TObject);
mulai
Tidak valid;
akhir;
Gambar 14: Kode untuk menggambar garis bitmap.
Gambar 15: Jendela dengan garis kustom.
Rutin ini menangani event OnPaint pada form, memanggil LineDDA, jadi setiap kali form harus dicat, event lain yang ditangani adalah OnResize, yang membuat area klien form menjadi tidak valid, sehingga garis harus digambar ulang ketika seseorang mengubahnya. size. Fungsi callback LineDDA, CallDDA, sangat sederhana. Pada setiap titik ke-13 dipanggil, ia menggambar bitmap yang disimpan dalam ImageList fungsi panggilan balik, sehingga dapat mengakses data instance.
Program ini menangani event OnPaint form, memanggil LineDDA, sehingga akan menggambar ulang garis setiap kali form dicat. Peristiwa lainnya adalah OnResize, yang membuat area klien formulir menjadi tidak valid sehingga garis akan digambar ulang ketika seseorang mengubah ukurannya. Fungsi panggilan balik LineDDA dan CallDDA sangat sederhana. Setiap kali dipanggil 13 kali, itu akan menggambar bitmap yang disimpan di ImageList. Mungkin Anda memperhatikan bahwa SELF diteruskan sebagai parameter terakhir ke fungsi callback, sehingga dapat mengakses data program.
Kesimpulan
sebagai kesimpulan
Sejak gambar pemilik diekspos pada TMainMenu di Delphi 4, ada banyak cara untuk menambah menu Anda. Dengan menggunakan teknik yang telah kita bahas di sini, Anda dapat dengan mudah menyempurnakan menu aplikasi Delphi Anda dengan teks kustom, bitmap, dan warna.
Sekarang gambar pemilik telah muncul di TmainMenu di Delphi 4, ada banyak cara untuk memperluas fungsionalitas menu Anda. Dengan menggunakan teknik yang kita bahas di atas, Anda dapat dengan mudah meningkatkan fungsionalitas menu aplikasi DELPHI dengan teks, bitmap, dan warna khusus.