İlginç

ComboBox Drop Down Genişliğini Boyutlandırma

ComboBox Drop Down Genişliğini Boyutlandırma

TComboBox bileşeni, bir düzenleme kutusunu kaydırılabilir bir "seçim" listesiyle birleştirir. Kullanıcılar listeden bir öğe seçebilir veya doğrudan düzenleme kutusuna yazabilir.

Açılır liste

Birleşik giriş kutusu bırakıldığında, Windows, seçim için birleşik giriş kutusu öğelerini görüntülemek için bir liste kutusu tipi kontrol çizer.

DropDownCount özelliği açılır listede görüntülenen maksimum öğe sayısını belirtir.

açılır listenin genişliği , varsayılan olarak, birleşik giriş kutusunun genişliğine eşittir.

Maddelerin uzunluğu (bir dize) açılan kutunun genişliğini aştığında, öğeler kesme olarak gösterilir!

TComboBox, açılır listesinin genişliğini ayarlamak için bir yol sağlamaz :(

ComboBox Açılır Liste Genişliğini Düzeltme

Açılır listeye özel bir Windows mesajı göndererek açılır listenin genişliğini ayarlayabiliriz. Mesaj CB_SETDROPPEDWIDTH ve bir açılan kutunun liste kutusundaki izin verilen minimum genişliği piksel cinsinden gönderir.

Aşağı açılan listenin boyutunu sabitlemek için, diyelim ki, 200 piksele kadar şunları yapabilirsiniz:

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

Bu sadece tüm KomboBox'ınızın olduğundan eminseniz.Öğeler 200 piksele (çizildiğinde) daha uzun değildir.

Açılır listenin her zaman yeterince geniş olmasını sağlamak için gereken genişliği hesaplayabiliriz.

Aşağı açılır listenin gereken genişliğini elde etmek ve ayarlamak için bir işlev:

prosedür ComboBox_AutoWidth (const theComboBox: TCombobox); const HORIZONTAL_PADDING = 4; var itemsFullWidth: tamsayı; idx: tamsayı; itemWidth: tamsayı; başla itemsFullWidth: = 0; // aşağı açılır durumdaki öğelerin ihtiyaç duyduğu maksimum değeri al için idx: = 0 için -1 + Bileşen Kutusu. Öğe Sayısı yap başla itemWidth: = theComboBox.Canvas.TextWidth (theComboBox.Itemsidx); Inc (itemWidth, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) sonra itemsFullWidth: = itemWidth; son; // eğer gerekliyse açılan genişliğini ayarla Eğer (itemsFullWidth> theComboBox.Width) ardından başla // kaydırma çubuğu olup olmadığını kontrol edin Eğer theComboBox.DropDownCount <theComboBox.Items.Count sonra itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); SendMessage (theComboBox.Handle, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); son; son;

En uzun dizenin genişliği, aşağı açılan listenin genişliği için kullanılır.

ComboBox_AutoWidth ne zaman aranır?
Öğelerin listesini önceden doldurursanız (tasarım zamanında veya formu oluştururken), formun içindeki ComboBox_AutoWidth yordamını çağırabilirsiniz. OnCreate olay işleyicisi.

Açılan kutu öğeleri listesini dinamik olarak değiştirirseniz, içindeki ComboBox_AutoWidth yordamını çağırabilirsiniz. OnDropDown olay işleyicisi - kullanıcı açılır listeyi açtığında gerçekleşir.

Bir test
Bir test için, bir formda 3 açılan kutumuz var. Hepsi, birleşik giriş kutusunun genişliğinden daha geniş metinleri olan öğeler içerir. Üçüncü açılan kutu, form kenarlığının sağ kenarına yakın bir yere yerleştirilir.

Items örneği, bu örnekte önceden doldurulur - formun OnCreate olay işleyicisindeki ComboBox_AutoWidth'i çağırırız:

// Form OnCreate prosedür TForm.FormCreate (Gönderen: TObject); başla ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); son;

Farkı görebilmemiz için Combobox1 için ComboBox_AutoWidth adını almadık!

Çalıştırıldığında, Combobox2 açılır listesinin Combobox2'den daha geniş olacağını unutmayın.

Tüm Aşağıya Açılan Liste "Sağ Kenarına Yakın Yerleştirme" İçin Kesiliyor

Combobox3 için, sağ kenarın yakınına yerleştirilmiş olan açılır menü listesi kesilir.

CB_SETDROPPEDWIDTH gönderilmesi, açılan liste kutusunu her zaman sağa genişletir. Açılan kutunuz sağ kenarın yakınında olduğunda, liste kutusunu daha sağa genişletmek, liste kutusunun görüntülenmesine neden olur.

Bir şekilde sağa değil, bu durumda liste kutusunu sola doğru genişletmeliyiz!

CB_SETDROPPEDWIDTH, liste kutusunu genişletmek için hangi yöne (sola veya sağa) belirtmenin bir yolunu yoktur.

Çözüm: WM_CTLCOLORLISTBOX

Sadece açılır listenin gösterilmesi gerektiğinde, Windows WM_CTLCOLORLISTBOX mesajını bir liste kutusunun üst penceresine gönderir - açılan kutumuza.

Sağa yakın kombo kutusunun WM_CTLCOLORLISTBOX'ını kullanabilmesi sorunu çözecektir.

Yüce PencereProc
Her bir VCL denetimi, WindowProc özelliğini gösterir - kontrole gönderilen iletilere yanıt verme prosedürü. WindowProc özelliğini, kontrolün pencere prosedürünü geçici olarak değiştirmek veya alt sınıfları için kullanabiliriz.

İşte Combobox3 için değiştirilmiş WindowProc (sağa yakın olan):

// değiştirilmiş ComboBox3 WindowProc prosedür TForm.ComboBox3WindowProc (var Mesaj: TMessage); var cr, lbr: TRect; başla // liste kutusunu birleşik giriş öğeleriyle çizim eğer Message.Msg = WM_CTLCOLORLISTBOX başla GetWindowRect (ComboBox3.Handle, cr); // liste kutusu dikdörtgeni GetWindowRect (Message.LParam, lbr); // sağ kenarlıkla eşleşmesi için sola doğru oynat Eğer cr.Right lbr.Right sonra MoveWindow (Message.LParam, lbr.Left- (lbr.Right-clbr.Right), lbr.Top, lbr.Right-lbr.Left, lbr.Bottom-lbr.Top, True); son Başka ComboBox3WindowProcORIGINAL (mesaj); son;

Açılan kutumuzun aldığı mesaj WM_CTLCOLORLISTBOX ise, penceresinin dikdörtgenini alıyoruz, görüntülenecek liste kutusunun dikdörtgenini de alıyoruz (GetWindowRect). Liste kutusunun sağda daha fazla göründüğü görülüyorsa - açılan kutu ve liste kutusunun sağ kenarlığı aynı olacak şekilde sola doğru hareket ederiz. Bu kadar kolay :)

Mesaj WM_CTLCOLORLISTBOX değilse, sadece birleşik giriş kutusu için orijinal mesaj işleme prosedürünü çağırırız (ComboBox3WindowProcORIGINAL).

Son olarak, doğru bir şekilde ayarladıysak, tüm bunlar işe yarayabilir (formun OnCreate olay işleyicisinde):

// Form OnCreate prosedür TForm.FormCreate (Gönderen: TObject); başla ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // ComboBox3 için değiştirilmiş / özel WindowProc ekleyin ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; son;

Formun beyanında nerede (tümü) var:

tip TForm = sınıf(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox; prosedür FormCreate (Gönderen: TObject); özel ComboBox3WindowProcORIGINAL: TWndMethod; prosedür ComboBox3WindowProc (var Mesaj: TMessage); halka açık {Genel bildirimler} son;

Ve bu kadar. Tüm işlenmiş :)

Videoyu izle: CSS ile Açılır dropdown Menü Yapımı (Eylül 2020).