Az TComboBox Az összetevő egyesíti a szerkesztődobozt egy görgethető "válogatási" listával. A felhasználók kiválaszthatnak egy elemet a listából, vagy közvetlenül beírhatják a szerkesztési mező.
Legördülő lista
Ha a kombinált doboz leesett állapotban van, a Windows felhívja a listamező típusú vezérlőelemet a választható kombinált doboz elemek megjelenítéséhez.
Az DropDownCount tulajdonság meghatározza a legördülő listában megjelenő elemek maximális számát.
Az a legördülő lista szélessége alapértelmezés szerint megegyezik a kombinált doboz szélességével.
Ha az elemek (egy karakterlánc) hossza meghaladja a kombinált doboz szélességét, akkor az elemek cut-offként jelennek meg!
A TComboBox nem biztosítja a legördülő lista szélességének beállítását :(
A ComboBox legördülő lista szélességének javítása
A legördülő lista szélességét beállíthatjuk egy speciális küldéssel Windows üzenet a kombinált dobozba. Az üzenet: CB_SETDROPPEDWIDTH és elküldi a kombinált doboz listájának minimális megengedett szélességét pixelekben.
Ha a legördülő lista méretét 200 pixelre állítja, akkor ezt megteheti:
SendMessage (a ComboBox. Fogantyú, CB_SETDROPPEDWIDTH, 200, 0);
Ez csak akkor van rendben, ha biztos benne, hogy az összes ComboBox-on van. Az elemek nem lehetnek hosszabbak 200 képpontnál (rajzoláskor).
Annak érdekében, hogy a legördülő lista mindig elég széles legyen, kiszámolhatjuk a szükséges szélességet.
Itt van egy funkció a legördülő lista kívánt szélességének eléréséhez és beállításához:
eljárás ComboBox_AutoWidth (const theComboBox: TCombobox); const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: egész szám; idx: egész szám; itemWidth: egész szám; kezdődik
tételek teljes szélessége: = 0; // kapja meg a szükséges maximális értéket az elemek legördülő állapotábanmert idx: = 0 nak nek -1 + a ComboBox. Terméket. Számol csinálkezdődik
itemWidth: = a ComboBox. Vászon. Szövegszélesség (a ComboBox. Tételek [IDX]); Inc (tételszélesség, 2 * HORIZONTAL_PADDING); if (itemWidth> itemsFullWidth) azután itemsFullWidth: = itemWidth; vég; // állítsa be a legördülő szélességet, ha szükségesha (tételek teljes szélessége> a comboBox. Szélesség), majd. kezdődik// ellenőrizze, hogy létezik-e görgetősávha theComboBox. DropDownCount azután
tételek teljes szélessége: = tételek teljes szélessége + GetSystemMetrics (SM_CXVSCROLL); SendMessage (a ComboBox. Fogantyú, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); vég; vég;
A leghosszabb húr szélességét a legördülő lista szélességére használjuk.
Mikor kell hívni a ComboBox_AutoWidth-t?
Ha előre kitölti az elemek listáját (a tervezés idején vagy az űrlap létrehozásakor), akkor meghívhatja a ComboBox_AutoWidth eljárást az űrlapon belül OnCreate eseménykezelő.
Ha dinamikusan megváltoztatja a kombinált dobozok listáját, akkor felhívhatja a ComboBox_AutoWidth eljárást a OnDropDown eseménykezelő - akkor fordul elő, amikor a felhasználó megnyitja a legördülő listát.
Egy teszt
A teszthez 3 kombinált doboz van egy űrlapon. Mindegyiknél vannak olyan elemek, amelyek szövege szélesebb, mint a kombinált doboz tényleges szélessége. A harmadik kombinált dobozt az űrlap határának jobb széle közelében kell elhelyezni.
A Példák Tulajdonság ebben a példában előzetesen kitöltésre kerül - hívjuk a ComboBox_AutoWidth-et az OnCreate eseménykezelőben az űrlaphoz:
// Az űrlap OnCreateeljárás TForm. FormCreate (Feladó: TObject); kezdődik
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); vég;
Nem hívtuk a ComboBox_AutoWidth-et a Combobox1-hez, hogy lássa a különbséget!
Vegye figyelembe, hogy futtatáskor a Combobox2 legördülő listája szélesebb lesz, mint a Combobox2.
A teljes legördülő listát levágják a "Jobb szélső elhelyezés"
A jobb széléhez közeli Combobox3 esetében a legördülő lista levágásra kerül.
A CB_SETDROPPEDWIDTH elküldésekor a legördülő listát mindig jobbra kell kiterjeszteni. Ha a kombinált doboz a jobb széle közelében helyezkedik el, akkor a listamező jobbra történő kiterjesztésekor a listamező megjelenése levágásra kerül.
Valahogy ki kell terjesztenünk a listát, ha ez a helyzet, nem jobbra!
A CB_SETDROPPEDWIDTH semmilyen módon nem tudja meghatározni, hogy milyen irányba (balra vagy jobbra) bővítse a listát.
Megoldás: WM_CTLCOLORLISTBOX
A legördülő lista megjelenésekor a Windows elküldi a WM_CTLCOLORLISTBOX üzenetet a listamező szülőablakához - a kombinált mezőbe.
A WM_CTLCOLORLISTBOX kezelése a jobboldali szélső kombinált dobozban megoldja a problémát.
A Mindenható WindowProc
Minden VCL-vezérlő kiteszi a WindowProc tulajdonságot - az az eljárás, amely a vezérlőnek küldött üzenetekre reagál. A WindowProc tulajdonsággal ideiglenesen helyettesíthetjük vagy alosztályozhatjuk a vezérlés ablakának eljárását.
Itt van a módosított WindowProc a Combobox3-hoz (a jobb szélénél lévő):
// módosított ComboBox3 WindowProceljárás TForm. ComboBox3WindowProc (var Üzenet: TMessage); var
cr, lbr: TRect; kezdődik// a listamező rajzolása kombinált elemekkel
ha Üzenet. Msg = WM_CTLCOLORLISTBOX, akkor. kezdődik
GetWindowRect (ComboBox3.Handle, cr); // lista doboz téglalap
GetWindowRect (Üzenet. LParam, lbr); // mozgassa balra, hogy megegyezzen a jobb szélgelha kr. Jobb <> lbr. Jobb azután
MoveWindow (Üzenet. LParam, lbr. Jobb- (LBR. Jobb clbr. Jobbra), lbr. Top, lbr. Jobb LBR. Balra, lbr. Bottom-LBR. Felső, igaz); végmás
ComboBox3WindowProcORIGINAL (Message); vég;
Ha az üzenet, amelyet a kombinált dobozunkban kap, a WM_CTLCOLORLISTBOX, megkapjuk az ablak téglalapját, akkor a megjelenő listamező téglalapját is megkapjuk (GetWindowRect). Ha úgy tűnik, hogy a listamező jobbra jelenik meg - balra mozgatjuk úgy, hogy a kombinált doboz és a listamező jobb szegélye megegyezzen. Olyan egyszerű :)
Ha az üzenet nem WM_CTLCOLORLISTBOX, akkor egyszerűen meghívjuk a kombinált doboz eredeti üzenetkezelési eljárását (ComboBox3WindowProcORIGINAL).
Végül, mindez működhet, ha helyesen állítottuk be (az űrlap OnCreate eseménykezelőjében):
// Az űrlap OnCreateeljárás TForm. FormCreate (Feladó: TObject); kezdődik
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // csatoljon módosított / egyedi WindowProc szoftvert a ComboBox3-hoz
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; vég;
Ahol az űrlapnyilatkozatban van (teljes):
típus
TForm = osztály(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;eljárás FormCreate (Feladó: TObject); magán
ComboBox3WindowProcORIGINAL: TWndMethod; eljárás ComboBox3WindowProc (var Üzenet: TMessage); nyilvános{Nyilvános nyilatkozatok}vég;
És ez az. Minden kezelt :)