Veličina ComboBox pada širine pada

TComboBox komponenta kombinira okvir za uređivanje s pomičnim popisom "pick". Korisnici mogu odabrati stavku s popisa ili je upisati izravno u okvir za uređivanje.

Padajući popis

Kad je kombinirani okvir u padajućem stanju, Windows crta vrstu okvira s popisom kako bi se prikazale stavke kombiniranog okvira za odabir.

DropDownCount svojstvo određuje maksimalni broj predmeta prikazanih na padajućem popisu.

širina padajućeg popisa bi, prema zadanim postavkama, bila jednaka širini kombiniranog okvira.

Kad duljina (niza) predmeta prelazi širinu kombiniranog okvira, predmeti se prikazuju kao presječeni!

TComboBox ne pruža način za postavljanje širine padajućeg popisa :(

Popravljanje širine padajućeg popisa ComboBox

Širinu padajućeg popisa možemo postaviti slanjem posebnog Windows poruka u kombinirani okvir. Poruka je CB_SETDROPPEDWIDTH i šalje minimalnu dopuštenu širinu, u pikselima, liste okvira kombiniranog okvira.

Da biste tvrdo kodirali veličinu padajućeg popisa na, recimo, 200 piksela, mogli biste učiniti:

instagram viewer

SendMessage (theComboBox). Ručka, CB_SETDROPPEDWIDTH, 200, 0); 

Ovo je u redu samo ako ste sigurni da su svi vaši theComboBox. Predmeti nisu duži od 200 px (kada ih crtamo).

Da bismo osigurali da je zaslon padajućeg popisa uvijek dovoljno širok, možemo izračunati potrebnu širinu.

Evo funkcije za dobivanje potrebne širine padajućeg popisa i postavljanje:

postupak ComboBox_AutoWidth (const theComboBox: TCombobox); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: cijeli broj; idx: cijeli broj; itemWidth: cijeli broj; početi
itemsFullWidth: = 0; // dobiti maksimum potreban za stavke u padajućem stanjuza idx: = 0 do -1 + theComboBox. Stavke. Računati činipočeti
itemWidth: = theComboBox. Platno. Širina teksta (theComboBox. Stavke [IDX]); Inc (širina predmeta, 2 * HORIZONTAL_PADDING); ako (itemWidth> itemsFullWidth) zatim itemsFullWidth: = itemWidth; kraj; // podesite širinu pada prema potrebiako (itemsFullWidth> theComboBox. Širina) tada. početi// provjerite postoji li traka za pomicanjeako theComboBox. DropDownCount zatim
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); SendMessage (theComboBox). Ručka, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); kraj; kraj; 

Širina najduljeg niza koristi se za širinu padajućeg popisa.

Kada nazvati ComboBox_AutoWidth?
Ako prethodno popunite popis stavki (u vrijeme dizajniranja ili prilikom stvaranja obrasca), možete nazvati postupak ComboBox_AutoWidth unutar obrasca onCreate dostavljač događaja.

Ako dinamički promijenite popis stavki kombiniranog okvira, možete nazvati postupak ComboBox_AutoWidth unutar OnDropDown rukovatelj događajima - događa se kada korisnik otvori padajući popis.

Test
Za test, na obrascu imamo 3 kombinirane kutije. Svi elementi imaju tekst čiji je tekst širi od stvarne širine polja. Treći kombinirani okvir postavljen je blizu desnog ruba obrasca obrasca.

Svojstvo Artikli, na primjer, unaprijed je popunjeno - u obrascu OnCreate događaja zovemo naš ComboBox_AutoWidth za obrazac:

// Obrazac je OnCreatepostupak TForm. FormCreate (pošiljalac: TObject); početi
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); kraj; 

Nismo pozvali ComboBox_AutoWidth za Combobox1 da bismo vidjeli razliku!

Imajte na umu da će, kada se pokrene, padajući popis za Combobox2 biti širi od Combobox2.

Cijeli padajući popis isključen je za "Položaj blizu desnog ruba"

Za Combobox3, onaj koji se nalazi blizu desnog ruba, padajući popis je odsječen.

Slanje CB_SETDROPPEDWIDTH uvijek će proširiti okvir padajućeg popisa s desne strane. Kada se vaš kombinirani okvir nalazi blizu desnog ruba, produženje okvira s popisom udesno rezultiraće odsječenjem okvira s popisom.

Moramo nekako proširiti okvir s lijeve strane kada je to slučaj, a ne s desne strane!

CB_SETDROPPEDWIDTH ne može odrediti u kojem smjeru (lijevo ili desno) produžiti okvir s popisom.

Rješenje: WM_CTLCOLORLISTBOX

Baš kada treba prikazati padajući popis, Windows šalje WM_CTLCOLORLISTBOX poruku roditeljskom prozoru okvira s popisom - u naš kombinirani okvir.

Mogućnost rješavanja problema s WM_CTLCOLORLISTBOX za kombinirani okvir s desne strane.

Svemogući prozorProc
Svaka VCL kontrola izlaže svojstvo WindowProc - postupak koji reagira na poruke poslane na kontrolu. Možemo koristiti svojstvo WindowProc da privremeno zamijenimo ili podklasiramo postupak prozora kontrole.

Evo našeg modificiranog WindowProc za Combobox3 (onaj blizu desnog ruba):

// izmijenjeni ComboBox3 WindowProcpostupak TForm. ComboBox3WindowProc (var Poruka: TMessage); var
cr, lbr: TRect; početi// crtanje okvira s popisima u kombiniranom okviru
ako je poruka. Msg = WM_CTLCOLORLISTBOX tada. početi
GetWindowRect (ComboBox3.Handle, cr); // pravokutnik okvirnog popisa
GetWindowRect (Poruka. LParam, lbr); // pomaknite ga ulijevo kako bi odgovarali desnoj graniciako cr. Desno <> lbr. Pravo zatim
MoveWindow (Poruka. LParam, lbr. Lijevu (lbr. Desni clbr. Desno), lbr. Vrh, lbr. Desni lbr. Lijevo, lbr. Dno-lbr. Vrh, istina); krajdrugo
ComboBox3WindowProcORIGINAL (poruka); kraj; 

Ako je poruka koju prima naš kombinirani okvir WM_CTLCOLORLISTBOX dobili smo pravokutnik njezina prozora, također ćemo dobiti pravokutnik okvira s popisom koji će biti prikazan (GetWindowRect). Ako se čini da će se okvir s popisom pojavljivati ​​više s desne strane - premještamo ga ulijevo tako da je kombinirani okvir i okvir okvira s desnim bokom isti. Jednostavno kao to :)

Ako poruka nije WM_CTLCOLORLISTBOX, jednostavno zovemo originalni postupak rukovanja porukama za kombinirani okvir (ComboBox3WindowProcORIGINAL).

Napokon, sve to može uspjeti ako smo ga ispravno postavili (u obrascu OnCreate događaja za obrazac):

// Obrazac je OnCreatepostupak TForm. FormCreate (pošiljalac: TObject); početi
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // priložite modificirani / prilagođeni WindowProc za ComboBox3
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; kraj; 

Gdje u deklaraciji obrasca imamo (cijelu):

tip
TForm = klasa(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;postupak FormCreate (pošiljalac: TObject); privatna
ComboBox3WindowProcORIGINAL: TWndMethod; postupak ComboBox3WindowProc (var Poruka: TMessage); javnost{Javne izjave}kraj; 

I to je to. Sve obrađeno :)

instagram story viewer