Koko ComboBox-pudotusleveys

TComboBox komponentti yhdistää muokkauskentän ja vieritettävän "valinta" -luettelon. Käyttäjät voivat valita kohteen luettelosta tai kirjoittaa suoraan muokkausruutu.

Pudotusvalikosta

Kun yhdistelmäruutu on pudotettuna, Windows piirtää luetteloruudutyyppisen säätimen yhdistelmälaatikkokohtien näyttämistä valintaa varten.

DropDownCount-omaisuus määrittelee avattavassa luettelossa näytettävien kohteiden enimmäismäärän.

avattavan luettelon leveys olisi oletuksena yhtä suuri kuin yhdistelmäruudun leveys.

Kun esineiden (merkkijonon) pituus ylittää yhdistelmäruudun leveyden, kohteet näytetään raja-arvona!

TComboBox ei tarjoa tapaa asettaa avattavan luettelon leveyttä :(

ComboBox-pudotusluettelon leveyden vahvistaminen

Voimme asettaa avattavan luettelon leveyden lähettämällä erityisen Windows-viesti yhdistelmälaatikkoon. Viesti on CB_SETDROPPEDWIDTH ja lähettää yhdistelmälaatikon luetteloruudun vähimmäisleveyden pixeleinä.

Voit koodata avattavan luettelon koon 200 pikseliksi, mitä voisit tehdä:


Lähetä viesti (comboBox. Kahva, CB_SETDROPPEDWIDTH, 200, 0); 
instagram viewer

Tämä on oikein vain, jos olet varma kaikista ComboBox-laitteistasi. Tuotteet eivät ole pidempiä kuin 200 kuvapistettä (piirrettäessä).

Voimme laskea tarvittavan leveyden varmistaaksemme, että avattavan luettelonäyttö on aina riittävän leveä.

Tässä on toiminto, jolla saadaan tarvittava avattavan luettelon leveys ja asetetaan se:

menettely ComboBox_AutoWidth (const theComboBox: TCombobox); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: kokonaisluku; idx: kokonaisluku; itemWidth: kokonaisluku; alkaa
itemsFullWidth: = 0; // hanki tarvittava enimmäismäärä avattavassa tilassa olevista kohteistavarten idx: = 0 että -1 + comboBox. Kohteita. Kreivi tehdäalkaa
itemWidth: =ComboBox. Kangas. Tekstin leveys (comboBox. Tuotteet [IDX]); Inc (esineleveys, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) sitten itemsFullWidth: = itemWidth; pää; // aseta avattavan leveys tarvittaessajos (itemsFullWidth> the comboBox. Leveys). alkaa// tarkista onko vierityspalkkijos theComboBox. DropDownCount sitten
itemsFullWidth: = itemsFullWidth + GetSystemMetrics (SM_CXVSCROLL); Lähetä viesti (comboBox. Kahva, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); pää; pää; 

Pisimmän merkkijonon leveyttä käytetään avattavan luettelon leveyteen.

Milloin soittaa ComboBox_AutoWidth?
Jos täytät esineiden luettelon ennakkoon (suunnittelun aikana tai lomaketta luotaessa), voit soittaa lomakkeen sisällä olevaan ComboBox_AutoWidth-menettelyyn. onCreate tapahtumakäsittelijä.

Jos muutat dynaamisesti yhdistelmäruudun kohteiden luetteloa, voit soittaa ComboBox_AutoWidth-menettelyyn OnDropDown tapahtumakäsittelijä - tapahtuu, kun käyttäjä avaa avattavan luettelon.

Koe
Testiä varten meillä on 3 yhdistelmäruutua lomakkeella. Kaikissa kohteissa on tekstiä leveämpi kuin todellinen yhdistelmäruudun leveys. Kolmas yhdistelmäruutu on sijoitettu lähellä lomakkeen reunan oikeaa reunaa.

Tämän esimerkin Kohteet-ominaisuus on esitäytetty - kutsumme ComboBox_AutoWidth -sovellusta OnCreate-tapahtumakäsittelijään lomakkeelle:

// Lomakkeen OnCreatemenettely TForm. FormCreate (Lähettäjä: TObject); alkaa
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); pää; 

Emme ole soittaneet ComboBox_AutoWidth -sovellusta Combobox1: lle nähdäksesi eron!

Huomaa, että suoritettaessa Combobox2: n avattava luettelo on leveämpi kuin Combobox2.

Koko avattava luettelo on katkaistu "lähellä oikean reunan sijoittelua"

Oikean reunan lähellä olevan Combobox3: n avattava luettelo leikataan.

CB_SETDROPPEDWIDTH-tiedoston lähettäminen pidentää avattavaa luetteloruutua aina oikealle. Kun yhdistelmäruutu on lähellä oikeaa reunaa, laajentamalla luetteloruutua enemmän oikealle, seurauksena luetteloruudun näyttö leikataan.

Meidän on jotenkin laajennettava luetteloruutua vasemmalle, kun näin on, ei oikealle!

CB_SETDROPPEDWIDTH: lla ei ole tapaa määritellä mihin suuntaan (vasen tai oikea) laajentaa luetteloruutua.

Ratkaisu: WM_CTLCOLORLISTBOX

Juuri kun avattava luettelo on tarkoitus näyttää, Windows lähettää WM_CTLCOLORLISTBOX -viestin luetteloruudun yläikkunaan - yhdistelmäruutuun.

WM_CTLCOLORLISTBOX -sovelluksen käsittely oikean reunan yhdistelmälaatikossa ratkaisee ongelman.

Kaikkivaltias WindowProc
Jokainen VCL-ohjaus paljastaa WindowProc-ominaisuuden - proseduurin, joka vastaa ohjaimeen lähetettyihin viesteihin. Voimme käyttää WindowProc-ominaisuutta korvataksesi tai alaluokan väliaikaisesti ohjauksen ikkunamenettelyn.

Tässä on muokattu WindowProc Combobox3: lle (oikea oikean reunan lähellä):

// muokattu ComboBox3 WindowProcmenettely TForm. ComboBox3WindowProc (var Viesti: TMessage); var
cr, lbr: TRect; alkaa// luetteloruudun piirtäminen yhdistelmälaatikoilla
jos Viesti. Msg = WM_CTLCOLORLISTBOX sitten. alkaa
GetWindowRect (ComboBox3.Handle, cr); // luetteloruudun suorakulmio
GetWindowRect (viesti. LParam, lbr); // siirrä se vasemmalle vastaamaan oikeaa reunaajos op. Oikea <> lbr. oikea sitten
Siirrä ikkuna (viesti. LParam, lbr. Vasemmalla (LBR. Oikea-clbr. Oikein), lbr. Yläosa, lbr. Oikea-LBR. Vasen, lbr. Bottom-LBR. Yläosa, totta); päämuu
ComboBox3WindowProcORIGINAL (Message); pää; 

Jos yhdistelmäruudun vastaanottama viesti on WM_CTLCOLORLISTBOX, saamme sen ikkunan suorakulmion, saamme myös näytettävän luetteloruudun suorakulmion (GetWindowRect). Jos näyttää siltä, ​​että luetteloruutu näkyy enemmän oikealla - siirrämme sitä vasemmalle niin, että yhdistelmäruudun ja luetteloruudun oikea reuna on sama. Niin helppoa kuin se :)

Jos viesti ei ole WM_CTLCOLORLISTBOX, kutsumme yksinkertaisesti yhdistelmälaatikon alkuperäistä viestinkäsittelymenetelmää (ComboBox3WindowProcORIGINAL).

Lopuksi kaikki tämä voi toimia, jos olemme asettaneet sen oikein (lomakkeen OnCreate-tapahtumakäsittelyohjelmassa):

// Lomakkeen OnCreatemenettely TForm. FormCreate (Lähettäjä: TObject); alkaa
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // liitä muokattu / mukautettu WindowProc ComboBox3: lle
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; pää; 

Missä lomakkeen ilmoituksessa meillä on (kokonainen):

tyyppi
TForm = luokka(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;menettely FormCreate (Lähettäjä: TObject); yksityinen
ComboBox3WindowProcORIGINAL: TWndMethod; menettely ComboBox3WindowProc (var Viesti: TMessage); julkinen{Julkiset ilmoitukset}pää; 

Ja siinä se on. Kaikki hoidettu :)

instagram story viewer