Dydžio „ComboBox“ išskleidžiamojo pločio nustatymas

„TComboBox“ komponentas sujungia redagavimo laukelį su slenkamu „pasirinkti“ sąrašu. Vartotojai gali pasirinkti elementą iš sąrašo arba tiesiogiai įvesti redagavimo laukelis.

Pasirinkimu sarasas

Kai kombinuotasis langas yra nuleidžiamas, „Windows“ nubraižo sąrašo laukelio tipo valdiklį, kad būtų rodomi pasirinkimo elementai.

„DropDownCount“ nuosavybė nurodo maksimalų elementų, rodomų išskleidžiamajame sąraše, skaičių.

išskleidžiamojo sąrašo plotis pagal numatytuosius nustatymus būtų lygus kombinuotojo laukelio pločiui.

Kai elementų (eilutės) ilgis viršija kombo langelio plotį, elementai rodomi kaip iškirpti!

„TComboBox“ nepateikia būdo, kaip nustatyti jo išskleidžiamojo sąrašo plotį :(

„ComboBox“ išskleidžiamojo sąrašo pločio taisymas

Mes galime nustatyti išskleidžiamojo sąrašo plotį siųsdami specialų „Windows“ pranešimas prie kombinuotosios dėžutės. Žinia yra CB_SETDROPPEDWIDTH ir siunčia mažiausią leidžiamą kombinuotojo laukelio sąrašo langelio plotį pikseliais.

Norėdami išskleidžiamojo sąrašo dydį iki, tarkime, 200 pikselių, užfiksuoti taip:

instagram viewer

Siųsti pranešimą („ComboBox“. Rankena, CB_SETDROPPEDWIDTH, 200, 0); 

Tai tik gerai, jei esate tikri, kad turite visą „ComboBox“. Elementai yra ne ilgesni kaip 200 pikselių (kai piešiama).

Norėdami užtikrinti, kad išskleidžiamojo sąrašo ekranas visada būtų pakankamai platus, galime apskaičiuoti reikiamą plotį.

Štai funkcija, kurią naudojant reikiamą išskleidžiamojo sąrašo plotį gausite ir nustatysite:

procedūra „ComboBox_AutoWidth“ (const „ComboBox“: „TCombobox“); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: sveikasis skaičius; idx: sveikasis skaičius; itemWidth: sveikasis skaičius; prasideda
itemsFullWidth: = 0; // gaukite maksimalų reikiamą elementų, esančių išskleidžiamajame būsenojedėl idx: = 0 į -1 + „ComboBox“. Daiktai. Grafas darytiprasideda
itemWidth: = „ComboBox“. Drobė. Teksto plotis („ComboBox“. Daiktai [idx]); Inc (prekės plotis, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) tada itemsFullWidth: = itemWidth; galas; // Jei reikia, nustatykite išskleidžiamojo plotisjei („Viso pločio“> „ComboBox“. Plotis) tada. prasideda// patikrinkite, ar nėra slinkties juostosjei „ComboBox“. „DropDownCount“ tada
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); Siųsti pranešimą („ComboBox“. Rankena, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); galas; galas; 

Išskleidžiamojo sąrašo pločiui naudojamas ilgiausios eilutės plotis.

Kada skambinti „ComboBox_AutoWidth“?
Jei iš anksto užpildote elementų sąrašą (kurdami ar kurdami formą), galite iškviesti „ComboBox_AutoWidth“ procedūrą formos viduje „OnCreate“ renginių vedėjas.

Jei dinamiškai pakeisite papildomo lango elementų sąrašą, galite iškviesti „ComboBox_AutoWidth“ procedūrą, esančią „OnDropDown“ įvykių tvarkyklė - įvyksta vartotojui atidarius išskleidžiamąjį sąrašą.

Testas
Bandymui mes turime 3 formos dėžutes. Visi turi elementus, kurių tekstas yra platesnis nei tikrasis junginio dėžutės plotis. Trečiasis kombinuotas langelis dedamas šalia dešiniojo formos krašto.

Šio pavyzdžio nuosavybė „Elementai“ yra iš anksto užpildyta - „ComboBox_AutoWidth“ vadiname „OnCreate“ įvykių tvarkytuve, kad gautume formą:

// Formos „OnCreate“procedūra TForm. „FormCreate“ (siuntėjas: „TObject“); prasideda
„ComboBox_AutoWidth“ („ComboBox2“); „ComboBox_AutoWidth“ („ComboBox3“); galas; 

Mes nepaskambinome „ComboBox_AutoWidth“ „Combobox1“, kad pamatytume skirtumą!

Atminkite, kad paleidus „Combobox2“ išskleidžiamasis sąrašas bus platesnis nei „Combobox2“.

Visas išskleidžiamasis sąrašas „Netoli dešiniojo krašto“ yra atmestas.

„Combobox3“, kuris yra šalia dešiniojo krašto, išskleidžiamasis sąrašas yra išpjaustytas.

Siųsdami „CB_SETDROPPEDWIDTH“, išskleidžiamasis sąrašas visada bus išplėstas į dešinę. Kai jūsų kombinuotasis dėžutė yra šalia dešiniojo krašto, išplėtę sąrašo laukelį daugiau į dešinę, sąrašo lango vaizdas bus nukirstas.

Turime kažkaip išplėsti sąrašo langelį į kairę, kai tai yra, o ne į dešinę!

CB_SETDROPPEDWIDTH neturi galimybės nurodyti, kuria kryptimi (į kairę ar į dešinę) išplėsti sąrašo laukelį.

Sprendimas: WM_CTLCOLORLISTBOX

Kai tik reikia parodyti išskleidžiamąjį sąrašą, „Windows“ siunčia WM_CTLCOLORLISTBOX pranešimą į pagrindinį sąrašo lango langą - į mūsų junginį.

Gebėjimas tvarkyti beveik dešiniojo krašto junginio „WM_CTLCOLORLISTBOX“ išspręstų problemą.

Visagalis „WindowProc“
Kiekvienas VCL valdiklis atskleidžia „WindowProc“ ypatybę - procedūrą, kuri reaguoja į valdikliui siunčiamus pranešimus. Mes galime naudoti „WindowProc“ ypatybę, kad laikinai pakeistume arba perklasifikuotume valdymo lango procedūrą.

Štai mūsų modifikuotas „WindowsProc“, skirtas „Combobox3“ (tas, kuris yra šalia dešiniojo krašto):

// modifikuotas „ComboBox3 WindowProc“procedūra TForm. „ComboBox3WindowProc“ (var Žinutė: TMessage); var
cr, lbr: TRect; prasideda// sąrašo langelio su kombinuotosiomis dėžutėmis piešimas
jei Žinutė. Msg = WM_CTLCOLORLISTBOX tada. prasideda
„GetWindowRect“ („ComboBox3.Handle“, cr); // sąrašo langelio stačiakampis
(Žinutė. LParam, lbr); // perkelkite jį į kairę, kad atitiktumėte dešinę kraštinęjei kr. Dešinė <> lbr. Teisingai tada
(Pranešimas. LParam, lbr. Kairė- (lbr. Dešinysis-klbr. Dešinėje), lbr. Viršuje, lbr. Dešinė-lbr. Kairė, lbr. Apačia-lbr. Viršuje, tiesa); galasKitas
„ComboBox3WindowProcORIGINAL“ (pranešimas); galas; 

Jei pranešimas, kurį gauna mūsų jungtinis langelis, yra WM_CTLCOLORLISTBOX, mes gauname jo lango stačiakampį, taip pat gauname rodomo sąrašo langelio stačiakampį (GetWindowRect). Jei paaiškėja, kad sąrašo laukelis pasirodys labiau dešinėje - perkelkime jį į kairę, kad junginio ir sąrašo laukelio dešinė kraštinė būtų vienoda. Taip paprasta :)

Jei pranešimas nėra WM_CTLCOLORLISTBOX, mes tiesiog iškviečiame originalią kombinuotojo lango tvarkymo procedūrą (ComboBox3WindowProcORIGINAL).

Galiausiai visa tai gali veikti, jei teisingai nustatėme (formos „OnCreate“ įvykių apdorojimo priemonėje):

// Formos „OnCreate“procedūra TForm. „FormCreate“ (siuntėjas: „TObject“); prasideda
„ComboBox_AutoWidth“ („ComboBox2“); „ComboBox_AutoWidth“ („ComboBox3“); // pridėkite modifikuotą / pasirinktinį „WindowsProc“, skirtą „ComboBox3“
„ComboBox3WindowProcORIGINAL“: = „ComboBox3.WindowProc“; „ComboBox3.WindowProc“: = „ComboBox3WindowProc“; galas; 

Kur formos deklaracijoje turime (visą):

tipo
TForm = klasė(TForm) „ComboBox1“: „TComboBox“; „ComboBox2“: „TComboBox“; „ComboBox3“: „TComboBox“;procedūra „FormCreate“ (siuntėjas: „TObject“); privatus
„ComboBox3WindowProcORIGINAL“: „TWndMethod“; procedūra „ComboBox3WindowProc“ (var Žinutė: TMessage); viešai{Vieši pareiškimai}galas; 

Štai ir viskas. Viskas tvarkoma :)

instagram story viewer