Mengukur Lebar Drop Down ComboBox

Itu TComboBox komponen menggabungkan kotak edit dengan daftar "pilih" yang dapat digulir. Pengguna dapat memilih item dari daftar atau mengetik langsung ke kotak edit.

Daftar Drop Down

Ketika kotak kombo dalam keadaan drop down Windows menggambar jenis kotak daftar kontrol untuk menampilkan item kotak kombo untuk seleksi.

Itu Properti DropDownCount menentukan jumlah maksimum item yang ditampilkan dalam daftar drop-down.

Itu lebar daftar drop-down akan, secara default, sama dengan lebar kotak kombo.

Ketika panjang (string) item melebihi lebar kotak kombo, item ditampilkan sebagai cut-off!

TComboBox tidak menyediakan cara untuk mengatur lebar daftar drop-down :(

Memperbaiki Lebar Daftar Drop-Down ComboBox

Kami dapat mengatur lebar daftar drop-down dengan mengirim khusus Pesan Windows ke kotak kombo. Pesannya adalah CB_SETDROPPEDWIDTH dan mengirimkan lebar minimum yang diizinkan, dalam piksel, dari kotak daftar kotak kombo.

Untuk mengubah ukuran daftar drop-down, katakanlah, 200 piksel, Anda dapat melakukannya:

instagram viewer

SendMessage (theComboBox. Tangani, CB_SETDROPPEDWIDTH, 200, 0); 

Ini hanya ok jika Anda yakin semua theComboBox Anda. Item tidak lebih dari 200 px (saat ditarik).

Untuk memastikan kami selalu memiliki tampilan daftar drop-down yang cukup lebar, kami dapat menghitung lebar yang diperlukan.

Berikut adalah fungsi untuk mendapatkan lebar yang diperlukan dari daftar drop-down dan mengaturnya:

prosedur ComboBox_AutoWidth (const theComboBox: TCombobox); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: integer; idx: integer; itemWidth: integer; mulai
itemsFullWidth: = 0; // dapatkan maks yang dibutuhkan dengan item dalam status dropdownuntuk idx: = 0 untuk -1 + theComboBox. Item. Menghitung melakukanmulai
itemWidth: = theComboBox. Kanvas. TextWidth (theComboBox. Item [idx]); Inc (itemWidth, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) kemudian itemsFullWidth: = itemWidth; akhir; // atur lebar drop down jika perlujika (itemsFullWidth> theComboBox. Lebar) lalu. mulai// periksa apakah akan ada bilah gulirjika theComboBox. DropDownCount kemudian
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); SendMessage (theComboBox. Tangani, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); akhir; akhir; 

Lebar string terpanjang digunakan untuk lebar daftar drop-down.

Kapan menelepon ComboBox_AutoWidth?
Jika Anda mengisi terlebih dahulu daftar item (pada waktu desain atau saat membuat formulir), Anda dapat menghubungi prosedur ComboBox_AutoWidth di dalam formulir OnCreate pengendali acara.

Jika Anda secara dinamis mengubah daftar item kotak kombo, Anda dapat memanggil prosedur ComboBox_AutoWidth di dalam OnDropDown pengendali acara - terjadi ketika pengguna membuka daftar drop-down.

Sebuah tes
Untuk pengujian, kami memiliki 3 kotak kombo pada formulir. Semua memiliki item dengan teks mereka lebih lebar dari lebar kotak kombo yang sebenarnya. Kotak kombo ketiga ditempatkan di dekat tepi kanan batas formulir.

Properti Item, untuk contoh ini, sudah diisi sebelumnya - kami menyebutnya ComboBox_AutoWidth kami di event handler OnCreate untuk formulir:

// Form's OnCreateprosedur TForm. FormCreate (Pengirim: TObject); mulai
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); akhir; 

Kami belum menelepon ComboBox_AutoWidth untuk Combobox1 untuk melihat perbedaannya!

Perhatikan bahwa, ketika dijalankan, daftar drop-down untuk Combobox2 akan lebih luas dari Combobox2.

Seluruh Daftar Drop-Down Dipotong Untuk "Penempatan Tepi Kanan"

Untuk Combobox3, yang ditempatkan di dekat tepi kanan, daftar drop-down terpotong.

Mengirim CB_SETDROPPEDWIDTH akan selalu memperpanjang kotak daftar tarik turun ke kanan. Ketika kotak kombo Anda berada di dekat tepi kanan, memperpanjang kotak daftar lebih ke kanan akan mengakibatkan tampilan kotak daftar terputus.

Kita perlu entah bagaimana memperpanjang kotak daftar ke kiri ketika ini terjadi, bukan ke kanan!

CB_SETDROPPEDWIDTH tidak memiliki cara menentukan arah apa (kiri atau kanan) untuk memperpanjang kotak daftar.

Solusi: WM_CTLCOLORLISTBOX

Tepat ketika daftar drop-down akan ditampilkan, Windows mengirimkan pesan WM_CTLCOLORLISTBOX ke jendela induk dari kotak daftar - ke kotak kombo kami.

Mampu menangani WM_CTLCOLORLISTBOX untuk kotak kombo dekat-kanan akan memecahkan masalah.

Jendela Yang Mahakuasa
Setiap kontrol VCL memperlihatkan properti WindowProc - prosedur yang merespons pesan yang dikirim ke kontrol. Kita bisa menggunakan properti WindowProc untuk sementara mengganti atau subkelas prosedur jendela kontrol.

Inilah WindowProc kami yang telah dimodifikasi untuk Combobox3 (yang dekat dengan tepi kanan):

// Windows ComboBox3 dimodifikasiprosedur TForm. ComboBox3WindowProc (var Pesan: TMessage); var
cr, lbr: Lintasan; mulai// gambar kotak daftar dengan item combobox
jika Pesan. Msg = WM_CTLCOLORLISTBOX lalu. mulai
GetWindowRect (ComboBox3.Handle, cr); // kotak daftar persegi panjang
GetWindowRect (Pesan. LParam, lbr); // pindahkan ke kiri untuk mencocokkan perbatasan kananjika cr. Benar <> lbr. Baik kemudian
MoveWindow (Pesan. LParam, lbr. Kiri- (lbr. Kanan-brbr. Benar), lbr. Top, lbr. Benar lbr. Kiri, lbr. Bawah-lbr. Atas, Benar); akhirlain
ComboBox3WindowProcORIGINAL (Pesan); akhir; 

Jika pesan yang diterima kotak kombo kami adalah WM_CTLCOLORLISTBOX, kami mendapatkan kotak jendelanya, kami juga mendapatkan kotak dari kotak daftar yang akan ditampilkan (GetWindowRect). Jika terlihat bahwa kotak daftar akan muncul lebih ke kanan - kami memindahkannya ke kiri sehingga kotak kombo dan batas kotak kotak daftar sama. Semudah itu :)

Jika pesannya bukan WM_CTLCOLORLISTBOX, kami cukup memanggil prosedur penanganan pesan asli untuk kotak kombo (ComboBox3WindowProcORIGINAL).

Akhirnya, semua ini bisa berfungsi jika kita telah menyetelnya dengan benar (di event handler OnCreate untuk formulir):

// Form's OnCreateprosedur TForm. FormCreate (Pengirim: TObject); mulai
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // pasang modifikasi / custom WindowProc untuk ComboBox3
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; akhir; 

Di mana dalam deklarasi formulir kami memiliki (seluruh):

Tipe
TForm = kelas(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;prosedur FormCreate (Pengirim: TObject); pribadi
ComboBox3WindowProcORIGINAL: TWndMethod; prosedur ComboBox3WindowProc (var Pesan: TMessage); publik{Pernyataan publik}akhir; 

Dan itu saja. Semua ditangani :)

instagram story viewer