2009-08-21 6 views
5

W Delphi wszystkie kontrolki TEdit i TComboBox mają domyślnie wysokość 21 pikseli. W przypadku TComboBox rozmiar ten jest bezwzględny i próba rozciągnięcia go do czegoś większego nie działa. W przypadku TComboBoxEx domyślna wysokość to 22 piksele, co sprawia, że ​​wyróżnia się trochę w jakiejkolwiek formie, w której go używasz. Teraz, zgodnie z Microsoft docs, ComboBoxEx jest w zasadzie ComboBox z funkcjami ciągnionymi przez właściciela, które są obsługiwane w celu umożliwienia wyświetlania obrazów i wcięć.Czy można uzyskać wartość TComboBoxEx na taką samą wysokość jak TComboBox?

Czy możliwe jest sprawienie, że moje kontrolki TComboBoxEx będą miały 21 pikseli wysokości? Na czym to polega?

Aktualizacja: Dodałem Quality Central report w sprawie, zgodnie z sugestią Roddy'ego. Znalazłem też poprawkę. Wygląda na to, że rozmiar zależy od wielkości pozycji -1 w combobox. Ustawiasz ten rozmiar na 15 (lub o jeden piksel mniej niż domyślny rozmiar), a pudełko kurczy się do bardziej znanych 21 pikseli.

+0

Wow - schludny Fix! Sugeruję, aby dodać go jako "zaakceptowaną odpowiedź" na własne pytanie. Warto przegrać! – Roddy

+0

Dodano odpowiedź, ale mogę ją zaakceptować tylko za dzień lub dwa. Istnieje również zastrzeżenie, które wiąże się z wyświetlaniem obrazu - zobacz moją odpowiedź poniżej. –

Odpowiedz

6

Znalazłem poprawkę. Delphi wydaje się mieć kilka błędów związanych z tym:

  1. Wartość opublikowanego własności ItemHeight jest zmuszony do 16, ponieważ klasa TComboBoxEx zastępuje funkcję GetItemHt być zakodowane 16. bez uwzględnienia jakiejkolwiek dla rzeczywistego rozmiaru przedmiotu - dziwne, ponieważ działa to doskonale na TComboBox. Nie wiem, dlaczego zdecydowali się zastosować tę strategię. Prawdopodobnie, aby obrazy zawsze pasowały.
  2. Delphi faktycznie nie wywołuje wiadomości CB_SETITEMHEIGHT, więc nawet jeśli zastąpisz tę funkcję, nic się nie zmieni.

Aktualizacja:

Jak podkreślił mghie, mój początkowy pomysł wykorzystania zakodowane wartość 15 w wywołaniu wiadomość nie działa dobrze w różnych ustawieniach DPI. Tak więc używam calll do GetTextMetrics, aby określić wysokość. Dodana do wysokości czcionki jest wartość GetSystemMetrics (SM_CYBORDER).

Jest to oparte na sposobie, w jaki VCL określa rozmiar TEdit.Nie sądzę, że to jest w porządku, ale ponieważ celem jest, aby ComboBoxEx miał taką samą wielkość jak TEdit, prawdopodobnie jest tak blisko, jak to tylko możliwe. I działa w ustawieniach DPI 96, 120, 144 i 192.

Wysokość ComboBoxEx jest określona przez wysokość pozycji -1. Tak więc pozycje od 0 do liczby-1 są rzeczywistymi pozycjami na liście, ale pozycja -1 jest wysokością używaną dla edytora. Jeśli ustawisz tę wysokość na 15, wysokość kontrolki zostanie skorygowana do 21 pikseli (zobacz powyższą aktualizację w celu skalowania). Myślę, że Mason może mieć rację, że rozmiar czcionki odgrywa tutaj pewną rolę (prawdopodobnie zmienia rozmiar elementu), ale może to sprawić, że będzie dobrze działać, dostosowując rozmiar elementu.

Wygląda na to, że wprowadziłem nowy (moim zdaniem, mniejszy) problem polegający na tym, że na obrazach 96-megapikselowych o rozdzielczości 16-cio pikselowej tracę najbardziej dolną linię, gdy jest ona wyświetlana w części edytora, ale jest to ledwo zauważalne.

Więc poprawka jest więc nazwać ten kod:

GetTextMetrics(Canvas.Handle, TM); 
SendMessage(Handle, CB_SETITEMHEIGHT, -1, 
    GetSystemMetrics(SM_CYBORDER) * 2 + TM.tmHeight); 
+0

TEdit na moim laptopie z ustawieniem DPI 124 z pewnością nie ma 21 pikseli wysokości. Ciężko zakodowane wysokości są po prostu złe, niezależnie od tego, czy pracują dla ciebie, czy nie, a powrót 15 nie jest wcale lepszy niż powrót 16. Co z różnymi czcionkami lub ustawieniami DPI? Prawdziwa poprawka polegałaby na uzyskaniu wysokości czcionki i obliczeniu wysokości elementu na podstawie tego. – mghie

+0

-1 dla stałych zakodowanych, takich jak mghie wyjaśnił –

+0

Punkt wzięty o ustawienie DPI. Teraz muszę wiedzieć, jak obliczana jest wysokość pola edycji. Spojrzałem na obliczenie wysokości elementu w oparciu o wysokość czcionki, ale nie widzę, w jaki sposób doprowadziło to do 16 punktów - uważam, że zostało wybrane, aby pasowało 16x16 glifów. To, co wydaje się działać zarówno na 96 DPI, jak i na 120, nazywa się GetTextMetric i używa tmHeight + 2. Myślałem, że użycie tmHeight + tmInternalLeading byłoby poprawne, ale działa tylko przy 120 DPI. Mógłbym zacząć od 15 i skalować od 96 do 120, ale to też nie wydaje się właściwe. Jakieś pomysły? –

1

Wysokość TComboBox nie jest bezwzględna; jest on powiązany z wysokością używanej czcionki. TComboBoxEx działa w ten sam sposób, ale wydaje się, że ma dodatkowy piksel "narzutowy", jak zauważyliście, i nie wydaje się, aby istniał jakikolwiek prosty sposób na zmianę tego. Jeśli jest to opakowanie dla wbudowanego kontrolera systemu Windows, może nie być żadnego sposobu zmiany go na poziomie Delphi, kropka.

+0

Chyba że chcesz stworzyć własną wersję, ale nie sądzę, że jest to poprawna opcja ;-). –

1

Dwa sposoby na zmianę wysokości TComboBoxEx, niestety nie są prawdopodobnie tym, czego potrzebujesz.

  • Ustaw mniejszą wartość właściwości font.size - pole zostanie zmniejszone. (jednak tekst jest mniejszy)

  • Ustaw parametr StyleEx.csExNoSizeLimit: = false, a następnie ustaw wysokość: = 21 zgodnie z potrzebami. Niestety, powoduje to jedynie obcięcie pudełka, więc dolna ramka znika.

I pewnie wymienić wszystkie TComboBoxes z TComboBoxEx - GExperts ma genialny „zastąpić komponenty” kreatora dla tej operacji.

To wygląda jak bug Delphi. Czy zgłosiłeś to poprzez QC?

+0

Dodano raport kontroli jakości. Link został dodany do pytania. –