---- 1. Tips menggunakan kontrol pohon di Delphi
---- Kita semua tahu bahwa pengembang terutama menggunakan Delphi untuk mengembangkan perangkat lunak manajemen basis data. Oleh karena itu, penggunaan kontrol pohon paling baik dikaitkan dengan basis data. Delphi menyediakan TTreeView kontrol pohon, yang dapat digunakan untuk menggambarkan hubungan hierarki yang kompleks.
---- 1. Penyimpanan dan pemuatan informasi simpul pohon
---- Metode yang umum digunakan adalah dengan menggunakan metode LoadFromFile dan SavetoFile dari kontrol pohon untuk mewujudkan interaksi antara kontrol pohon dan file atau menggunakan metode Assign untuk mewujudkan interaksi antara kontrol pohon dan DBMemo, yaitu , interaksi dengan database. Keuntungan dari metode ini adalah pemrogramannya relatif sederhana. Kerugiannya adalah jumlah sebenarnya dari node kontrol pohon mungkin sangat besar. Untuk "pohon besar", jumlah data yang dimuat dan disimpan akan meningkat setiap saat mengurangi kecepatan, meningkatkan overhead sistem, dan menyebabkan redundansi data. Metode lain adalah dengan hanya menghasilkan node yang "terlihat" di pohon. Tidak ada file atau kolom database yang didedikasikan untuk mencatat seluruh struktur node pohon, dan struktur node pohon tersebar di setiap catatan database.
---- Cara spesifiknya adalah: membuat database, field ditentukan sesuai dengan bisnis sebenarnya, harus ada satu field yang informasinya akan ditampilkan pada node kontrol pohon, dan ada juga field untuk menyimpan nomor identifikasi unik dari node. Nomor identifikasi terdiri dari dua bagian dengan panjang yang sama. Bagian pertama mewakili nomor node induk dari node saat ini, dan bagian terakhir mewakili nomor node dari node saat ini sebuah "daftar tertaut" yang mencatat struktur node di pohon. Keuntungan dari metode ini: Ketika pengguna mengoperasikan "pohon besar", mereka umumnya tidak memperluas semua node, tetapi hanya menggunakan bagian yang terbatas, dan pada saat yang sama, mereka hanya dapat memperluas lapisan demi lapisan dari akar pohon metode hanya menghasilkan "" pada pohon. Node "terlihat", oleh karena itu, kecepatan penyimpanan dan pemuatan "pohon besar" cepat, jumlah data kecil, dan overhead sistem serta redundansi data kecil. Kekurangan: Pemrograman lebih rumit, namun metode ini dapat digabungkan untuk membentuk kontrol pohon baru, yang akan sangat meningkatkan efisiensi pemrograman. Perlu dicatat bahwa nomor ID harus unik, jadi cara menghasilkan ID secara wajar dalam pemrograman sangatlah penting.
---- 2. Contoh struktur database
----Buat database. Untuk menyederhanakan prosedur, saya hanya membuat dua field database, yang didefinisikan sebagai berikut:
Panjang jenis nama bidang
TeksC10
PanjangIDC6
---- Bidang LongID sebenarnya terdiri dari dua segmen, masing-masing segmen terdiri dari 3 digit. LongID hanya dapat mewakili 1000 catatan. Tentukan LongID sebagai bidang indeks dan simpan sebagai c: esttree ree.dbf. Edit file DBF, buat catatan baru, atur bidang Teks ke TOP, dan atur bidang LongID ke "000" (tiga spasi sebelum tiga "0").
---- 3. Buat program demo
---- Tempatkan TreeView1, Table1, PopupMenu1, Edit1, dan Edit2 pada Form1. Atribut PopupMenu dari TreeView1 disetel ke PopupMenu1; atribut DataBaseName dari Table1 disetel ke c: esttree, atribut TableName disetel ke tree.dbf, dan atribut IndexFieldNames disetel ke LongID; dan Caption masing-masing adalah Add dan Del; Edit1 digunakan Untuk memasukkan nilai atribut Teks dari node baru, Edit2 digunakan untuk memasukkan 3 digit nomor ID dari node baru. Simpan sebagai c:esttree reeunit.pas dan c:esttree esttree.dPR. Tambahkan baris setelah kata kunci Type in treeunit.pas: Pstr:^string;{Pstr is a string pointer} Tambahkan kode untuk event OnCreate di Form1:
prosedur TForm1.FormCreate(Pengirim: TObject);
var p:Pstr;Node:TTreeNode;
mulai
dengan Table1, Treeview1 lakukan
mulai
membuka;
Pertama;
baru(p);{Alokasikan memori untuk penunjuk p}
p^:=FieldByName(′LongID′).AsString;
Node:=Items.AddChildObject(nil,FieldByName
(′Teks′).AsString,p);
jika HasSubInDbf(Node) maka Item
.AddChildObject(Node,′ ′,nil);{Jika ada node anak, tambahkan node anak yang kosong}
akhir;
akhir;
---- HasSubInDbf adalah fungsi khusus, variabel independennya adalah Node, periksa apakah node Node memiliki node anak, kembalikan True jika ada, jika tidak, kembalikan False, dan tambahkan deklarasi prototipe ke definisi kelas TForm1 (prototipe dari fungsi khusus lainnya juga dideklarasikan dalam definisi kelas TForm1 tanpa penjelasan lebih lanjut), kode fungsinya adalah sebagai berikut:
fungsi TForm1.HasSubInDbf(Node:TTreeNode):Boolean;
mulai
dengan Tabel1 lakukan
mulai
Tabel1.TemukanTerdekat([copy(Pstr(Node.Data)^,4,3)+′000′]);
hasil:=copy(FieldByName(′LongID′).
AsString,1,3)=copy(Pstr(Node.Data)^,4,3);
{Misalnya, jumlah tiga digit pertama dari isi bidang LongID dari catatan saat ini dalam database
Jika tiga digit terakhir Data node Node sama, maka Node tersebut harus memiliki node anak}
akhir;
akhir;
Tambahkan kode untuk event OnDeletion pada kontrol TreeView1. Perlu diperhatikan bahwa,
Peristiwa OnDeletion tidak hanya dapat dipicu dengan memanggil metode Delete, tetapi juga sebelum kontrol pohon itu sendiri dilepaskan,
Event OnDeletion juga terpicu, jadi "aman" untuk menambahkan membuang(node.data) di sini:
prosedur TForm1.TreeView1Deletion
(Pengirim: TObject; Node: TTreeNode);
mulai
Buang(Node.Data);{Lepaskan memori data node}
akhir;
Tambahkan kode berikut ke event OnClick pada item menu Add1:
prosedur TForm1.Add1Click(Pengirim: TObject);
var p:pstr;Tmpstr:string;i:integer;
mulai
mencoba
StrToInt(Edit2.Teks);
Tmpstr:=Edit2.Text;{Catatan: Dalam praktiknya, metode yang lebih baik harus digunakan untuk menghasilkan ID}
kecuali;
ShowMessage('Masukkan kembali isi Edit2');
menggugurkan;
akhir;
dengan TreeView1 lakukan
mulai
baru(p);
p^:=copy(Pstr(Data Terpilih)^,4,3)+TmpStr;
Items.AddChildObject(Dipilih,Edit1.Teks,p);
akhir;
dengan Tabel1 lakukan{Tambahkan catatan dalam database}
mulai
Menambahkan;
FieldByName(′Text′).AsString:=Edit1.text;
FieldByName(′LongID′).AsString:=p^;
Pos;
akhir;
TmpStr:=inttostr(strtoint(TmpStr)+1);
untuk i:=length(TmpStr) sampai 2 lakukan TmpStr:=′0′+TmpStr;
Sunting2.Teks:=TmpStr;
akhir;
Tambahkan kode berikut ke event OnClick pada item menu Del1:
prosedur TForm1.Del1Click(Pengirim: TObject);
var DelList:TStringList;LongID,NSubLongID:string;
mulai
DelList:=TStringList.buat;
DelList.Diurutkan:=Benar;
DelList.Add(Pstr(TreeView1.Selected.Data)^);
sementara DelList.Count>0 lakukan
mulai
ID Panjang:=DelList.Strings[0];
DelList.Hapus(0);
Tabel1.SetKey;
Tabel1.FieldByName(′LongID′).AsString:=LongID;
jika Table1.GotoKey maka Table1.Delete;
jika HasSubInDbf(TreeView1.Selected) lalu
mulai
NSubLongID:=Tabel1.FieldByName(′LongID′).AsString;
while (salin(NSubLongID,1,3)=salin
(LongID,4,3))dan(bukan Table1.Eof) bisa
mulai
delist.Tambahkan(NSubLongId);
Tabel1.Berikutnya;
NSubLongId:=Tabel1.FieldByName(′LongID′).AsString;
akhir;
akhir;
akhir;
DelList.Gratis;
TreeView1.Items.Delete(TreeView1.Selected);
akhir;
Tambahkan kode untuk acara OnExpanding TreeView1:
prosedur TForm1.TreeView1Memperluas
(Pengirim: TObject; Node: TTreeNode;
var Izinkan Ekspansi: Boolean);
var TmpNode:TTreeNode;NSSubLongID:
String;p:Pstr;bm:TBookMark;
mulai
dengan Table1, TreeView1 lakukan
mulai
Item.BeginUpdate;
SetKey;
FieldByName(′LongID′).AsString:=Pstr(Node.Data)^;
jika bukan GotoKey maka Items.Delete(Node)
kalau tidak
mulai
TmpNode:=Node.GetFirstChild;
jika (TmpNode.Teks=′ ′)dan(TmpNode.Data=nil) maka
mulai
TmpNode.Hapus;
jika HasSubInDbf(Node) maka
mulai
NSubLongID:=FieldByName(′LongID′).AsString;
while (salin(NSubLongID,1,3)=salin(Pstr
(Node.Data)^,4,3))dan(bukan Eof) lakukan
mulai
baru(p);
p^:=FieldByName(′LongID′).AsString;
bm:=DapatkanBookMark;
TmpNode:=Item.AddChildObject(Node,
FieldByName(′Text′).AsString,p);
jika HasSubInDbf(TmpNode) maka Item.
AddChildObject(TmpNode,′ ′,nihil);
GotoBookMark(bm);
GratisBookMark(bm);
Berikutnya;
NSubLongId:=FieldByName(′LongID′).AsString;
akhir; akhir;
akhir;
Item.EndUpdate;
akhir;
akhir;
---- Di atas secara singkat membahas tentang metode dasar tampilan pohon dari database. Selain itu, saat mengedit atribut Teks dari node di pohon, database diubah pada saat yang sama beberapa pengguna pada saat yang sama, konsistensi database dan pohon, dan pohon Penyalinan dan replikasi node atas tidak akan dijelaskan secara rinci, dan pembaca dapat memperbaikinya sendiri.
---- 2. Penggunaan kontrol ip
---- Dalam program jaringan, kita sering menghadapi situasi di mana pengguna diharuskan memasukkan alamat IP. Namun Delphi tidak memberi kita kontrol yang dapat digunakan untuk memasukkan string IP, jadi kita harus menggunakan kontrol Tedit (kotak teks satu baris) untuk menerima string IP yang dimasukkan oleh pengguna. Namun, menggunakan Tedit untuk memasukkan string IP bukanlah ide yang baik karena sangat merepotkan untuk ditangani. Faktanya, ada kontrol Windows di samping kita yang khusus untuk memasukkan string IP. Kontrol IP akan menolak string IP ilegal (hanya angka antara 0..255 yang dapat dimasukkan di setiap bagian); ini memungkinkan Anda dengan mudah mendapatkan nilai IP (integer 32-bit) yang sesuai dengan string IP di kontrol menghemat kerumitan konversi antara string IP dan nilai IP; selain itu, Anda juga dapat membatasi rentang IP yang dapat dimasukkan dalam kontrol IP. Bagian ini memperkenalkan cara menggunakan kontrol IP Windows dalam program Delphi kami.
---- Ada dua pustaka tautan dinamis yang sangat penting di Windows: commctrl.dll dan comctl32.dll, yang merupakan pustaka kontrol khusus Windows (Kontrol Umum Windows). Pustaka kontrol khusus berisi banyak kontrol Windows yang umum digunakan, seperti Statusbar, Coolbar, HotKey, dll. di Delphi, sebagian besar kontrol ini telah dikemas sebagai kontrol visual. Setelah Microsoft meluncurkan Internet Explorer 3, beberapa kontrol baru ditambahkan ke perpustakaan kontrol kustom, termasuk kontrol IP Windows (kontrol edit Alamat IP).
---- 1. Inisialisasi perpustakaan kontrol khusus Windows
---- Windows menyediakan dua fungsi API, InitCommonControls dan InitCommonControlsEx, untuk menginisialisasi pustaka kontrol khusus. Dari namanya, tidak sulit untuk melihat hubungan antara kedua fungsi API ini: fungsi API ini merupakan penyempurnaan dari fungsi API sebelumnya. Jika Anda ingin menggunakan kontrol IP dalam program Anda, Anda harus menggunakan InitCommonControlsEx untuk menyelesaikan inisialisasi pustaka dan kelas kontrol kustom. Prototipe fungsi InitCommonControlsEx adalah sebagai berikut (sintaks Pascal):
... ...
Buat kontrol IP
... ...
Gunakan kontrol IP. Dalam program ini, kami berkomunikasi dengan kontrol IP dengan mengirimkan pesan ke sana.
Kontrol IP dapat merespons enam pesan berikut. Pesan-pesan ini dan artinya ditunjukkan pada tabel di bawah ini:
... ...
Jika Anda ingin mendapatkan nilai IP yang sesuai dengan string IP di kontrol IP, Anda harus mengirimkan
Pesan IPM_GETADDRESS, dan memerlukan alamat integer 32-bit sebagai
Parameter terakhir SendMessage.
... ...
---- 2. Pesan pemberitahuan kontrol IP
---- Ketika string IP diubah atau fokus input ditransfer, kontrol IP akan mengirimkan pesan pemberitahuan IPN_FIELDCHANGED ke jendela induknya. Dalam kebanyakan kasus, kita dapat mengabaikan pesan notifikasi ini. Berikut contoh penanganan pesan notifikasi IPN_FIELDCHANGED:
procedure Tform1.WndProc(var Pesan: TMessage);
var p:PNMHDR;
mulai
diwariskan;
jika Pesan.Pesan=WM_NOTIFY
lalu mulai
p:=Penunjuk(Msg.lParam);
jika p^.code=IPN_FIELDCHANGED
lalu mulai
{…
Menangani pesan notifikasi IPN_FIELDCHANGED dari kontrol IP
…}
akhir;
akhir;
akhir;
---- 3. Metode dan penerapan kontrol yang menghasilkan secara dinamis
---- 1.Dua metode untuk menghasilkan kontrol di Delphi
---- (1). Hasilkan kontrol dalam desain Formulir
---- Saat mendesain Formulir, biasanya memilih langsung kontrol yang diperlukan di kotak alat kontrol, lalu mengatur propertinya dan merespons peristiwa.
---- (2). Menghasilkan kontrol secara dinamis dalam program
---- Terkadang, kita perlu membuat kontrol secara dinamis saat program sedang berjalan. Hal ini memiliki dua keuntungan utama: pertama, dapat meningkatkan fleksibilitas program, kedua, jika jumlah kontrol yang dihasilkan terkait dengan hasil antara yang dijalankan; dari program tersebut, jelas metode pertama Tidak dapat direalisasikan, dan metode pembangkitan dinamis dalam program harus digunakan.
---- Metode menghasilkan kontrol secara dinamis dalam program ini dibagi menjadi tiga langkah. Pertama, tentukan jenis kontrol yang dihasilkan, kemudian gunakan fungsi Buat untuk menghasilkan kontrol, dan terakhir berikan nilai ke properti yang relevan dari kontrol tersebut. kontrol. Mengambil kontrol TButton sebagai contoh, langkah-langkahnya adalah sebagai berikut:
---- a. Tentukan jenis kontrol
var
Tombol1:Tombol;
---- b
Button1:=TButton.Create(mandiri);
Button1.Parent:=Diri;
//Umumnya, setel kontrol induknya ke Self. Jika nilai Parent tidak disetel,
maka kontrol tidak akan ada di layar
//tampilkan
---- c. Mengatur properti lain dan menentukan fungsi respons peristiwa terkait, seperti fungsi respons peristiwa Keterangan, Kiri, Atas, Tinggi, Lebar, Terlihat, Diaktifkan, Petunjuk, dan onClick, dll.
---- 2. Penerapan metode kontrol yang dihasilkan secara dinamis
---- Dalam pengembangan sistem penjadwalan dan manajemen produksi, perlu dibuat bagan penjadwalan produksi secara dinamis, yang diwakili oleh bagan Gantt, dan sangat berguna untuk menggunakan kontrol Bentuk untuk menampilkan status pemrosesan suku cadang (waktu mulai pemrosesan dan waktu akhir setiap proses). Menggunakan kontrol Bagan, pemanfaatan peralatan pemrosesan ditampilkan dalam histogram tiga dimensi, yang sangat intuitif. Sekarang kami akan menjelaskan proses pembuatan kontrol Bentuk dan kontrol Bagan secara dinamis dalam program.
---- (1). Menghasilkan kontrol Bentuk secara dinamis untuk menampilkan bagan rencana penjadwalan produksi (bagan Gantt)
prosedur TCreateMultiCharts.ProcCreateCharts;
var
i,j,Baris,Kolom,Ruang Baris,Tinggi Bagan:Bilangan Bulat;
ShapeChart:array dari array TShape;
mulai
Baris:=16; //Jumlah baris dalam array kontrol Bentuk
Kolom:=8; //Nomor kolom array kontrol bentuk
RowSpace:=20; // Kontrol bentuk spasi baris
ChartsHeight:=20; // Ketinggian kontrol bentuk
SetLength(ShapeChart,Baris,Kolom);
//Mengatur ukuran array ShapeChart
untuk i:=0 hingga Baris dilakukan
untuk j:=0 ke Kolom lakukan
mulai
ShapeChart[i][j]:=TShape.Create(self);
dengan ShapeChart[i,j] lakukan
mulai
Parent:=Self; //Baris ini penting,
Jika tidak, kontrol Bentuk tidak akan ditampilkan di layar.
Bentuk:=stRectangle; // Bentuk kontrol bentuk adalah persegi panjang
Atas:=45+i*(RowSpace+Tinggi Bagan);
Kiri:=Bulat(180+Q[i,j].StartTime);
//Karena Q[i,j].StartTime adalah bilangan real, maka perlu dibulatkan.
Lebar:=Bulat(Q[i,j].Nilai)
Tinggi:=Tinggi Grafik;
Kuas.Warna:=Warna Acak;
//Fungsi khusus, instruksi terlampir
Brush.Style:=bsSolid; //Atur metode pengisian
Diaktifkan:=Benar;
akhir;
akhir;
akhir;
---- Catatan: aQ adalah array dua dimensi tipe rekaman, yang didefinisikan sebagai berikut:
jenis
TempData=Rekam
Nilai: Nyata;
Waktu Mulai: Nyata;
akhir;
T:array array TempData
Dan komponen Q telah diberi nilai dalam proses lain.
---- b. Untuk membedakan bagian yang berbeda, Bentuk ditampilkan dalam warna berbeda. Fungsinya adalah:
fungsi TBuatMultiCharts.RandomColor;
var
merah, hijau, biru: byte;
mulai
merah:=acak(255);
hijau:=acak(255);
biru:=acak(255);
hasil:=merah atau (hijau shl 8) atau (biru shl 16);
akhir;
---- (2). Secara dinamis menghasilkan komponen ChartSeries dari kontrol Charts untuk menampilkan pemanfaatan perangkat
prosedur TFormMultiMachinesBurthen.
TampilkanMachineBurthenCharts;
var
saya:Bilangan Bulat;
Beban: Nyata;
Kelas Seri: Kelas Seri TChart;
Seri Baru: array TChartSeries;
mulai
SetLength(Seri Baru,CreateMultiCharts.Rows);
MesinBurthenCharts.height:=200;
MachinesBurthenCharts.Lebar:=550;
untuk i:=0 hingga CreateMultiCharts.Rows lakukan
mulai
SeriesClass:=TBarSeries; //Mengatur bentuk menjadi diagram batang tiga dimensi
Seri Baru[i]:=SeriKelas.Buat(Mandiri);
Seri Baru[i].ParentChart:=MachinesBurthenCharts;
Seri Baru[i].Hapus;
Burthen:=MesinBurthen[i];
Burthen:=Round(Burthen*100)/100; //Hanya mengambil dua digit setelah koma
Seri Baru[i].add(Burthen,',Seri Baru[i].SeriWarna);
akhir;
akhir;
---- Catatan: (a).MachineBurthen[i] adalah array nyata, nilainya adalah pemanfaatan perangkat terkait, yang telah dihitung dalam fungsi lain;
---- (b). MachinesBurthenCharts adalah kontrol TChart, dijelaskan di bagian tipe.
---- 3. Tampilan hasil program yang berjalan
---- (1). Menghasilkan kontrol Bentuk secara dinamis untuk menampilkan rencana penjadwalan bagian (dihilangkan)
---- (2). Secara dinamis menghasilkan komponen ChartSeries dari kontrol Chart dan menampilkan pemanfaatan perangkat (dihilangkan)