ComboBox Açılır Genişliğini Boyutlandırma

click fraud protection

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 kutusu.

Açılır liste

Açılan kutu bırakma durumundayken, Windows seçim için birleşik giriş kutusu öğelerini görüntülemek üzere bir liste kutusu denetim türü ç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.

Öğelerin uzunluğu (bir dizenin) birleşik giriş kutusunun genişliğini aştığında, öğeler kesme olarak görüntülenir!

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

Özel bir göndererek açılır listenin genişliğini ayarlayabiliriz Windows mesajı açılan kutuya. Mesaj CB_SETDROPPEDWIDTH ve bir birleşik giriş kutusunun liste kutusunun izin verilen minimum genişliğini piksel cinsinden gönderir.

Açılır listenin boyutunu sabit olarak 200 piksel olarak kodlamak için şunları yapabilirsiniz:

instagram viewer

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

Bu sadece tüm theComboBox eminseniz Tamam. Öğeler 200 pikselden uzun değil (çizildiğinde).

Açılır listenin her zaman yeterince geniş görünmesini sağlamak için gerekli genişliği hesaplayabiliriz.

Açılır listenin gerekli genişliğini almak ve ayarlamak için bir işlev şunlardır:

prosedür ComboBox_AutoWidth (const theComboBox: TCombobox); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: tamsayı; idx: tam sayı; itemWidth: integer; başla
itemsFullWidth: = 0; // açılır menüdeki öğeler için gereken maksimum değeri elde ediniçin idx: = 0 için -1 + ComboBox. Öğeler. Miktar yapmakbaşla
itemWidth: = theComboBox. Tuval. TextWidth (Metin Kutusu). Öğeler [IDX]); Inc (itemWidth, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) sonra itemsFullWidth: = itemWidth; son; // gerekirse açılır menünün genişliğini ayarlayınEğer (itemsFullWidth> birleşik giriş kutusu. Genişlik) sonra. başla// kaydırma çubuğu olup olmadığını kontrol etEğer theComboBox. DropDownCount sonra
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); SendMessage (theComboBox. Tanıtıcı, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); son; son; 

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

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

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

Bir test
Test için, bir form üzerinde 3 birleşik giriş kutumuz var. Hepsinde metinleri gerçek birleşik giriş kutusu genişliğinden daha geniş olan öğeler bulunur. Üçüncü birleşik giriş kutusu form kenarlığının sağ kenarına yakın yerleştirilir.

Bu örnek için Items özelliği önceden doldurulmuştur - form için OnCreate olay işleyicisinde ComboBox_AutoWidth'imizi çağırıyoruz:

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

Farkı görmek için Combobox1 için ComboBox_AutoWidth'i aramadık!

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

"Yakın Sağ Kenar Yerleşimi" İçin Açılır Listenin Tamamı Kesildi

Sağ kenarın yakınına yerleştirilen Combobox3 için açılır liste kesilir.

CB_SETDROPPEDWIDTH göndermek, açılır liste kutusunu her zaman sağa doğru genişletir. Açılan kutunuz sağ kenara yakın olduğunda, liste kutusunu sağa doğru genişletmek, liste kutusunun görüntülenmesinin kesilmesine neden olur.

Durum böyle olduğunda liste kutusunu bir şekilde sola doğru uzatmamız gerekir!

CB_SETDROPPEDWIDTH öğesinin liste kutusunu genişletmek için hangi yöne (sol veya sağ) belirleyecek bir yolu yoktur.

Çözüm: WM_CTLCOLORLISTBOX

Açılır listenin görüntülenmesi gerektiğinde, Windows WM_CTLCOLORLISTBOX iletisini liste kutusunun üst penceresine (açılan kutumuza) gönderir.

Sağ kenara yakın birleşik giriş kutusu için WM_CTLCOLORLISTBOX ile başa çıkmak sorunu çözecektir.

Yüce Pencere
Her VCL denetimi, denetime gönderilen iletilere yanıt veren yordam olan WindowProc özelliğini sunar. Denetimin pencere yordamını geçici olarak değiştirmek veya alt sınıflamak için WindowProc özelliğini kullanabiliriz.

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

// değiştirilmiş ComboBox3 WindowProcprosedür TForm. ComboBox3WindowProc (var Mesaj: TMessage); var
cr, lbr: TRect; başla// birleşik giriş öğeleri içeren liste kutusunu çizme
eğer Mesaj. Msg = WM_CTLCOLORLISTBOX sonra. başla
GetWindowRect (ComboBox3.Handle, cr); // liste kutusu dikdörtgeni
GetWindowRect (İleti. LParam, 1br); // sağ kenarlıkla eşleşmesi için sola taşıEğer cr. Sağ sonra
MoveWindow (İleti. LParam, lbr. Sol (LBR. Sağ clbr. Sağ), lbr. Üst, lbr. Sağ LBR. Sol, lbr. Alt-LBR. Üst, Doğru); sonBaşka
ComboBox3WindowProcORIGINAL (mesaj); son; 

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

İleti WM_CTLCOLORLISTBOX değilse, birleşik giriş kutusu (ComboBox3WindowProcORIGINAL) için orijinal ileti işleme yordamını çağırırız.

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

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

Formun beyanında nerede (tam):

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{Herkese açık beyanlar}son; 

Ve bu kadar. Tüm ele :)

instagram story viewer