Rozmiar rozwijanej szerokości ComboBox
Zapewnia, że lista rozwijana jest widoczna, gdy wyświetlana jest lista rozwijana
ermgut/Getty Images
TheTComboBoxkomponent łączy pole edycyjne z przewijaną listą 'pick'. Użytkownicy mogą wybrać pozycję z listy lub wpisać bezpośrednio w pole edycji .
Lista rozwijana
Gdy pole kombi jest w stanie rozwijanym, system Windows rysuje kontrolkę typu pola listy, aby wyświetlić elementy pola kombi do wyboru.
The Właściwość DropDownCount określa maksymalną liczbę pozycji wyświetlanych na liście rozwijanej.
The szerokość listy rozwijanej domyślnie równałaby się szerokości pola kombi.
Gdy długość (ciągu) elementów przekracza szerokość pola kombi, elementy są wyświetlane jako odcięte!
TComboBox nie zapewnia sposobu na ustawienie szerokości swojej listy rozwijanej :(
Naprawianie szerokości listy rozwijanej ComboBox
Możemy ustawić szerokość listy rozwijanej, wysyłając specjalną Wiadomość Windows do pola kombi. Wiadomość jest CB_SETDROPPEDWIDTH i wysyła minimalną dopuszczalną szerokość w pikselach pola listy pola kombi.
Aby na stałe zakodować rozmiar listy rozwijanej na, powiedzmy, 200 pikseli, możesz zrobić:
|_+_|
Jest to w porządku tylko wtedy, gdy masz pewność, że wszystkie elementy ComboBox.Items nie są dłuższe niż 200 pikseli (po narysowaniu).
Aby upewnić się, że lista rozwijana jest zawsze wystarczająco szeroka, możemy obliczyć wymaganą szerokość.
Oto funkcja, która pozwala uzyskać wymaganą szerokość listy rozwijanej i ustawić ją:
|_+_|Szerokość najdłuższego ciągu jest używana jako szerokość listy rozwijanej.
Kiedy zadzwonić ComboBox_AutoWidth?
Jeśli wstępnie wypełnisz listę elementów (w czasie projektowania lub podczas tworzenia formularza), możesz wywołać procedurę ComboBox_AutoWidth wewnątrz formularza Przy utworzeniu obsługa zdarzeń.
Jeśli dynamicznie zmienisz listę elementów pola kombi, możesz wywołać procedurę ComboBox_AutoWidth wewnątrz On DropDown obsługa zdarzeń - występuje, gdy użytkownik otworzy listę rozwijaną.
Badanie
Do testu mamy 3 pola kombi na formularzu. Wszystkie mają elementy, których tekst jest szerszy niż rzeczywista szerokość pola kombi. Trzecie pole kombi znajduje się w pobliżu prawej krawędzi obramowania formularza.
W tym przykładzie właściwość Items jest wstępnie wypełniona — wywołujemy nasze ComboBox_AutoWidth w procedurze obsługi zdarzeń OnCreate dla formularza:
|_+_|Nie nazwaliśmy ComboBox_AutoWidth dla Combobox1, aby zobaczyć różnicę!
Zauważ, że po uruchomieniu lista rozwijana Combobox2 będzie szersza niż Combobox2.
Cała lista rozwijana jest odcięta w przypadku „umieszczenia blisko prawej krawędzi”
W przypadku Combobox3, umieszczonego blisko prawej krawędzi, rozwijana lista jest odcięta.
Wysłanie CB_SETDROPPEDWIDTH zawsze rozszerzy listę rozwijaną w prawo. Gdy pole listy rozwijanej znajduje się blisko prawej krawędzi, rozszerzenie pola listy bardziej w prawo spowoduje odcięcie wyświetlania pola listy.
W takim przypadku musimy jakoś rozszerzyć pole listy w lewo, a nie w prawo!
CB_SETDROPPEDWIDTH nie ma możliwości określenia kierunku (w lewo lub w prawo) rozszerzenia pola listy.
Rozwiązanie: WM_CTLCOLORLISTBOX
Gdy tylko lista rozwijana ma się wyświetlić, Windows wysyła wiadomość WM_CTLCOLORLISTBOX do okna nadrzędnego pola listy - do naszego pola kombi.
Umiejętność obsługi pola WM_CTLCOLORLISTBOX dla pola kombi przy prawej krawędzi rozwiązałaby problem.
Okno WszechmocyProc
Każda kontrolka VCL uwidacznia właściwość WindowProc — procedurę, która odpowiada na komunikaty wysyłane do kontrolki. Możemy użyć właściwości WindowProc do tymczasowego zastąpienia lub podklasy procedury okna kontrolki.
Oto nasz zmodyfikowany WindowProc dla Combobox3 (ten przy prawej krawędzi):
|_+_|Jeśli komunikat, który otrzymuje nasze pole kombi to WM_CTLCOLORLISTBOX, otrzymujemy prostokąt jego okna, otrzymujemy również prostokąt listy, która ma zostać wyświetlona (GetWindowRect). Jeśli okaże się, że pole listy znajdowałoby się bardziej po prawej stronie - przesuwamy je w lewo, aby pole kombi i prawe obramowanie pola listy były takie same. Tak proste :)
Jeśli wiadomość nie jest WM_CTLCOLORLISTBOX, po prostu wywołujemy oryginalną procedurę obsługi wiadomości dla pola kombi (ComboBox3WindowProcORIGINAL).
Wreszcie wszystko to może działać, jeśli ustawiliśmy to poprawnie (w obsłudze zdarzeń OnCreate dla formularza):
|_+_|Gdzie w deklaracji formularza mamy (całość):
|_+_|I to wszystko. Wszystko załatwione :)