Μεγέθυνση του πλάτους πτώσης ComboBox

ο TComboBox συνιστούν ένα πλαίσιο επεξεργασίας με μια λίστα με δυνατότητα επιλογής. Οι χρήστες μπορούν να επιλέξουν ένα στοιχείο από τη λίστα ή να πληκτρολογήσουν απευθείας στο πλαίσιο ελέγχου.

Λίστα απόσπασης

Όταν ένα σύνθετο πλαίσιο είναι κατεβασμένο κατάσταση, τα Windows σχεδιάζουν ένα πλαίσιο ελέγχου τύπου λίστας για να εμφανιστούν τα στοιχεία κουμπιού επιλογής για επιλογή.

ο Ιδιότητα DropDownCount καθορίζει τον μέγιστο αριθμό στοιχείων που εμφανίζονται στην αναπτυσσόμενη λίστα.

ο πλάτος της αναπτυσσόμενης λίστας θα ήταν, εξ ορισμού, ίσο με το πλάτος του σύνθετου πλαισίου.

Όταν το μήκος (μιας συμβολοσειράς) των αντικειμένων υπερβαίνει το πλάτος του combobox, τα στοιχεία εμφανίζονται ως αποκοπή!

Το TComboBox δεν παρέχει έναν τρόπο ρύθμισης του εύρους της αναπτυσσόμενης λίστας :(

Προσδιορισμός του πλάτους της λίστας συρραφής ComboBox

Μπορούμε να ορίσουμε το πλάτος της αναπτυσσόμενης λίστας αποστέλλοντας ένα ειδικό Μηνύματα των Windows στο σύνθετο πλαίσιο. Το μήνυμα είναι CB_SETDROPPEDWIDTH

instagram viewer
και στέλνει το ελάχιστο επιτρεπόμενο πλάτος, σε εικονοστοιχεία, του πλαισίου λίστας ενός σύνθετου πλαισίου.

Για τον σκληρό κώδικα του μεγέθους της αναπτυσσόμενης λίστας, για παράδειγμα 200 pixels, μπορείτε να κάνετε:


ΑποστολήMessage (τοComboBox. Χειρολαβή, CB_SETDROPPEDWIDTH, 200, 0). 

Αυτό είναι μόνο εντάξει αν είστε βέβαιοι σε όλο το TheBox. Τα στοιχεία δεν υπερβαίνουν τα 200 px (όταν σχεδιάζονται).

Για να διασφαλίσουμε ότι η λίστα των αναπτυσσόμενων λιστών είναι αρκετά μεγάλη, μπορούμε να υπολογίσουμε το απαιτούμενο πλάτος.

Ακολουθεί μια λειτουργία για να έχετε το απαιτούμενο πλάτος της αναπτυσσόμενης λίστας και να την ορίσετε:

διαδικασία ComboBox_AutoWidth (const τοComboBox: TCombobox). const
HORIZONTAL_PADDING = 4; var
itemsFullWidth: ακέραιο; idx: ακέραιο; itemWidth: ακέραιο; ξεκινήσει
itemsFullWidth: = 0; // πάρτε το μέγιστο που χρειάζεστε με τα στοιχεία στην κατάσταση dropdownΓια idx: = 0 προς το -1 + τοComboBox. Στοιχεία. μετρώ κάνωξεκινήσει
itemWidth: = τοComboBox. Καμβάς. TextWidth (τοComboBox. Στοιχεία [idx]); Inc (στοιχείοWidth, 2 * HORIZONTAL_PADDING); αν (itemWidth> itemsFullWidth) έπειτα itemsFullWidth: = αντικείμενοWidth; τέλος; // Ρυθμίστε το πλάτος του αναπτυσσόμενου πεδίου αν χρειαστείαν (itemsFullWidth> theComboBox. Πλάτος) τότε. ξεκινήσει// ελέγξτε εάν θα υπήρχε μια μπάρα κύλισηςαν τοComboBox. DropDownCount έπειτα
ΣτοιχείαFullWidth: = στοιχείαFullWidth + GetSystemMetrics (SM_CXVSCROLL); ΑποστολήMessage (τοComboBox. Χειριστείτε, CB_SETDROPPEDWIDTH, itemsFullWidth, 0); τέλος; τέλος; 

Το πλάτος της μεγαλύτερης γραμμής χρησιμοποιείται για το πλάτος της αναπτυσσόμενης λίστας.

Πότε πρέπει να καλέσετε το ComboBox_AutoWidth;
Αν προπληρώσετε τη λίστα των στοιχείων (κατά το σχεδιασμό ή κατά τη δημιουργία της φόρμας), μπορείτε να καλέσετε τη διαδικασία ComboBox_AutoWidth μέσα στο έντυπο της φόρμας OnCreate χειριστής συμβάντων.

Εάν αλλάξετε δυναμικά τη λίστα των στοιχείων συνδυαστικού κουτιού, μπορείτε να καλέσετε τη διαδικασία ComboBox_AutoWidth μέσα στο OnDropDown χειριστής συμβάντων - εμφανίζεται όταν ο χρήστης ανοίγει την αναπτυσσόμενη λίστα.

Μια δοκιμή
Για μια δοκιμή, έχουμε 3 σύνθετα πλαίσια σε μια φόρμα. Όλοι έχουν στοιχεία με το κείμενο τους μεγαλύτερο από το πραγματικό πλάτος του σύνθετου πλαισίου. Το τρίτο παράθυρο διαλόγου είναι τοποθετημένο κοντά στο δεξί άκρο των ορίων του εντύπου.

Η ιδιότητα Είδη, για αυτό το παράδειγμα, είναι προπληρωμένη - καλούμε το ComboBox_AutoWidth μας στο πρόγραμμα επεξεργασίας συμβάντων OnCreate για τη φόρμα:

// OnCreate της φόρμαςδιαδικασία TForm. FormCreate (αποστολέας: TObject); ξεκινήσει
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); τέλος; 

Δεν έχουμε ονομάσει ComboBox_AutoWidth για το Combobox1 για να δείτε τη διαφορά!

Σημειώστε ότι, κατά την εκτέλεση, η αναπτυσσόμενη λίστα για το Combobox2 θα είναι ευρύτερη από το Combobox2.

Ολόκληρη η λίστα απόσπασης είναι απενεργοποιημένη για την επιλογή "Κοντά στο δεξί άκρο"

Για το Combobox3, αυτό που βρίσκεται κοντά στο δεξί άκρο, ο αναπτυσσόμενος κατάλογος διακόπτεται.

Η αποστολή του CB_SETDROPPEDWIDTH θα επεκτείνει πάντοτε το αναπτυσσόμενο πλαίσιο προς τα δεξιά. Όταν ο συνδυασμός σας βρίσκεται κοντά στο δεξί άκρο, η επέκταση του πλαισίου λίστας πιο προς τα δεξιά θα είχε ως αποτέλεσμα την αποκοπή της εμφάνισης του πλαισίου λίστας.

Πρέπει να επεκτείνουμε κατά κάποιο τρόπο το πλαίσιο λίστας προς τα αριστερά, όταν συμβαίνει αυτό, όχι προς τα δεξιά!

Το CB_SETDROPPEDWIDTH δεν έχει τρόπο προσδιορισμού σε ποια κατεύθυνση (αριστερά ή δεξιά) να επεκτείνει το πλαίσιο λίστας.

Λύση: WM_CTLCOLORLISTBOX

Μόλις εμφανιστεί η αναπτυσσόμενη λίστα, τα Windows στέλνουν το μήνυμα WM_CTLCOLORLISTBOX στο γονικό παράθυρο ενός πλαισίου λίστας - στο σύνθετο πλαίσιο.

Το να μπορείτε να χειριστείτε το WM_CTLCOLORLISTBOX για το κοντόπλακο κοντά στο δεξί άκρο θα λύσει το πρόβλημα.

Το Παντοδύναμο ΠαράθυροProc
Κάθε έλεγχος VCL εκθέτει την ιδιότητα WindowProc - τη διαδικασία που ανταποκρίνεται στα μηνύματα που αποστέλλονται στον έλεγχο. Μπορούμε να χρησιμοποιήσουμε την ιδιότητα WindowProc για την προσωρινή αντικατάσταση ή υποκλάση της διαδικασίας παραθύρου του στοιχείου ελέγχου.

Εδώ είναι το τροποποιημένο WindowProc για Combobox3 (το ένα κοντά στο δεξί άκρο):

// τροποποιημένο ComboBox3 WindowProcδιαδικασία TForm. ComboBox3WindowProc (var Μήνυμα: TMessage); var
cr, lbr: TRect. ξεκινήσει// σχεδίαση του πλαισίου λίστας με στοιχεία combobox
αν Μήνυμα. Msg = WM_CTLCOLORLISTBOX τότε. ξεκινήσει
GetWindowRect (ComboBox3.Handle, cr); // ορθογώνιο πλαίσιο λίστας
GetWindowRect (Μήνυμα. LParam, lbr); // μετακινήστε το προς τα αριστερά για να ταιριάξετε το σωστό περίγραμμααν cr. Δεξιά <> lbr. σωστά έπειτα
MoveWindow (Μήνυμα. LParam, lbr. Αριστερά (lbr. Δεξιά clbr. Δεξιά), lbr. Κορυφή, lbr. Δεξιά-lbr. Αριστερά, lbr. Κάτω-lbr. Αρχή, Αληθινή); τέλοςαλλού
ComboBox3WindowProcORIGINAL (Μήνυμα); τέλος; 

Εάν το μήνυμα που λαμβάνει το σύνθετο κουτί είναι WM_CTLCOLORLISTBOX, έχουμε το ορθογώνιο παραθύρου του παραθύρου, έχουμε επίσης το ορθογώνιο του πλαισίου λίστας που θα εμφανιστεί (GetWindowRect). Εάν φαίνεται ότι το πλαίσιο λίστας θα φαίνεται πιο δεξιά - θα το μετακινήσουμε προς τα αριστερά, έτσι ώστε το πλαίσιο συντομεύσεων και το δεξί πλαίσιο του πλαισίου λίστας να είναι το ίδιο. Όσο εύκολο είναι αυτό :)

Εάν το μήνυμα δεν είναι WM_CTLCOLORLISTBOX απλά καλέστε την αρχική διαδικασία χειρισμού μηνυμάτων για το σύνθετο πλαίσιο (ComboBox3WindowProcORIGINAL).

Τέλος, όλα αυτά μπορούν να λειτουργήσουν αν το έχουμε ρυθμίσει σωστά (στο handler συμβάντος OnCreate για τη φόρμα):

// OnCreate της φόρμαςδιαδικασία TForm. FormCreate (αποστολέας: TObject); ξεκινήσει
ComboBox_AutoWidth (ComboBox2); ComboBox_AutoWidth (ComboBox3); // προσαρμόστε το τροποποιημένο / προσαρμοσμένο WindowProc για το ComboBox3
ComboBox3WindowProcORIGINAL: = ComboBox3.WindowProc; ComboBox3.WindowProc: = ComboBox3WindowProc; τέλος; 

Όταν στη δήλωση της φόρμας έχουμε (ολόκληρο):

τύπος
TForm = τάξη(TForm) ComboBox1: TComboBox; ComboBox2: TComboBox; ComboBox3: TComboBox;διαδικασία FormCreate (αποστολέας: TObject); ιδιωτικός
ComboBox3WindowProcORIGINAL: TWndMethod; διαδικασία ComboBox3WindowProc (var Μήνυμα: TMessage); δημόσιο{Δημόσιες δηλώσεις}τέλος; 

Και αυτό είναι. Όλοι χειρίζονται :)

instagram story viewer