TComboBox komponent ühendab redigeerimiskasti keritava loendiga "vali". Kasutajad saavad loendist elemendi valida või otse sisestada redigeerimise kast.
Rippmenüü
Kui liitkast on rippmenüüst, joonistab Windows nimekirjaboksi tüübi juhtelemendi, et kuvada valikuboksi üksusi.
DropDownCount vara määrab ripploendis kuvatavate üksuste maksimaalse arvu.
ripploendi laius oleks vaikimisi võrdne liitkasti laiusega.
Kui üksuste (stringi) pikkus ületab liitkasti laiuse, kuvatakse üksused läbilõikena!
TComboBox ei paku võimalust oma ripploendi laiuse määramiseks :(
ComboBoxi ripploendi laiuse fikseerimine
Saame ripploendi laiuse seada, saates selleks spetsiaalse Windowsi teade liitkasti juurde. Sõnum on CB_SETDROPPEDWIDTH ja saadab liitkasti loendiboksi minimaalse lubatud laiuse pikslites.
Ripploendi suuruse, näiteks 200 piksli, kõvakodeerimiseks võiksite teha järgmist:
SendMessage (komboboks. Käepide, CB_SETDROPPEDWIDTH, 200, 0);
See on korras ainult siis, kui olete kindel, et kogu teie ComboBox on olemas. Üksused ei ole pikemad kui 200 pikslit (joonistamisel).
Selleks, et rippmenüü kuva oleks alati piisavalt lai, saame vajaliku laiuse arvutada.
Siin on funktsioon ripploendi vajaliku laiuse saamiseks ja määramiseks:
protseduur ComboBox_AutoWidth (const theComboBox: TCombobox); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: täisarv; idx: täisarv; itemWidth: täisarv; alustada
itemsFullWidth: = 0; // hankige rippmenüüst üksuste jaoks vajalik maksimumjaoks idx: = 0 kuni -1 + ComboBox. Esemed. Krahv tehaalustada
itemWidth: = ComboBox. Lõuend. Teksti laius (comboBox. Kirjed [idx]); Inc (üksuse laius, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) siis itemsFullWidth: = üksuse laius; lõpp; // vajadusel seadistage rippmenüü laiuskui (itemsFullWidth> ComboBox. Laius) siis. alustada// kontrollige, kas kerimisriba olekskui ühendboks. DropDownCount siis
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); SendMessage (komboboks. Käepide, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); lõpp; lõpp;
Ripploendi laiuseks kasutatakse pikima stringi laiust.
Millal helistada ComboBox_AutoWidth?
Kui täidate üksuste loendi eeltäitmisel (disaini ajal või vormi loomisel), võite vormi sees kutsuda protseduuri ComboBox_AutoWidth. OnCreate sündmuste käitleja.
Kui muudate dünaamiliselt liitkasti üksuste loendit, võite helistada protseduurile ComboBox_AutoWidth OnDropDown sündmuste töötleja - ilmneb siis, kui kasutaja avab ripploendi.
Test
Testi jaoks on meil vormil 3 liitkasti. Kõigil on üksused, mille tekst on laiem kui tegelik liitboksi laius. Kolmas liitkast on paigutatud vormi piiri paremasse serva.
Selle näite atribuudid Üksused on eeltäidetud - kutsume oma ComboBox_AutoWidth OnCreate'i sündmuste käitlejasse järgmise vormi jaoks:
// Vormi OnCreateprotseduur TForm. FormCreate (saatja: TObject); alustada
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); lõpp;
Erinevuse nägemiseks pole me ComboBox_AutoWidth'i jaoks helistanud.
Pange tähele, et käitamisel on Combobox2 ripploend laiem kui Combobox2.
Parempoolse serva lähedal asuva paigutuse jaoks on lahti rippmenüü täielik nimekiri.
Parempoolse serva lähedal asuva Combobox3 puhul on ripploend ära lõigatud.
CB_SETDROPPEDWIDTH saatmine laiendab ripploendi kasti alati paremale. Kui teie liitkast on parempoolse serva lähedal, suurendaks loendikasti paremale, siis loendikast kuvataks.
Peame loendikasti kuidagi laiendama vasakule, kui see on nii, mitte paremale!
CB_SETDROPPEDWIDTH ei saa kuidagi täpsustada, millises suunas (vasakule või paremale) loendikasti laiendada.
Lahendus: WM_CTLCOLORLISTBOX
Just siis, kui ripploendit kuvatakse, saadab Windows WM_CTLCOLORLISTBOX teate loendikasti vanemaknasse - meie liitkasti.
Parempoolse servaga liitboksi WM_CTLCOLORLISTBOX käsitsemine lahendaks probleemi.
Kõikvõimas WindowProc
Iga VCL-i juhtseade paljastab aken WindowProc - protseduur, mis reageerib juhtseadmele saadetud teadetele. Saame kasutada WindowProc omadust, et ajutiselt asendada või alamklassi juhtseadme aknad.
Siin on meie muudetud WindowProc Combobox3 jaoks (see parempoolse serva lähedal):
// muudetud ComboBox3 WindowProcprotseduur TForm. ComboBox3WindowProc (var Sõnum: TMessage); var
cr, lbr: TRect; alustada// liitboksi elementidega loendikasti joonistamine
kui Sõnum. Msg = WM_CTLCOLORLISTBOX siis. alustada
GetWindowRect (ComboBox3.Handle, cr); // loendikast ristkülik
GetWindowRect (teade. LParam, lbr); // teisaldage see vasakule, et sobitada parem äärkui kr. Paremal <> lbr. Õige siis
MoveWindow (teade. LParam, lbr. Vasak- (lbr. Parempoolne-klbr. Paremal), lbr. Üles, lbr. Parem-lbr. Vasakul, lbr. Alt-lbr. Ülemine, tõsi); lõppmuud
ComboBox3WindowProcORIGINAL (teade); lõpp;
Kui kiri, mille meie liitkast saab, on WM_CTLCOLORLISTBOX, saame akna ristküliku, saame ka kuvatava loendikasti ristküliku (GetWindowRect). Kui ilmneb, et loendikast paistab rohkem paremal - liigutame seda vasakule, nii et liit- ja loendikasti parem äär on samad. Nii lihtne see ka pole :)
Kui kiri ei ole WM_CTLCOLORLISTBOX, kutsume lihtsalt liitkastis algset sõnumikäsitluse protseduuri (ComboBox3WindowProcORIGINAL).
Lõpuks võib see kõik toimida, kui oleme selle õigesti seadnud (vormi OnCreate'i sündmuste käitleja).
// Vormi OnCreateprotseduur TForm. FormCreate (saatja: TObject); alustada
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // lisage muudetud / kohandatud WindowProc ComboBox3 jaoks
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; lõpp;
Kus vormi deklaratsioonis meil (kogu) on:
tüüp
TForm = klass(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;protseduur FormCreate (saatja: TObject); privaatne
ComboBox3WindowProcORIGINAL: TWndMethod; protseduur ComboBox3WindowProc (var Sõnum: TMessage); avalik{Avalikud deklaratsioonid}lõpp;
Ja see ongi kõik. Kõik käideldud :)