2009-08-21 1 views
5

В Delphi все элементы управления TEdit и TComboBox по умолчанию имеют 21 пиксель. В случае с TComboBox этот размер является абсолютным и пытается растянуть его на нечто большее, не работает. Однако в случае TComboBoxEx высота по умолчанию составляет 22 пикселя, что делает ее немного выделяющейся в любой форме, где вы ее используете. Теперь, согласно Microsoft docs, ComboBoxEx - это, по сути, ComboBox с обработанной собственностью функциональностью, которая позволяет обрабатывать изображения и отступать.Могу ли я получить TComboBoxEx на ту же высоту, что и TComboBox?

Возможно ли, чтобы мои контроллеры TComboBoxEx достигли 21 пиксела в высоту? От чего это зависит?

Обновление: Я добавил Quality Central report по вопросу, как предложил Родди. Кроме того, я нашел исправление. По-видимому, размер зависит от размера элемента -1 в поле со списком. Таким образом, вы устанавливаете этот размер на 15 (или на один пиксель меньше, чем размер по умолчанию), и коробка сжимается до более привычных 21 пиксела.

+0

Wow - аккуратный исправить! Я предлагаю вам добавить его как «принятый ответ» на свой вопрос. Хорошо стоит upvote! – Roddy

+0

Добавлен ответ, но я могу принять его только через день или два. Существует также предостережение, которое включает отображение изображения - см. Мой ответ ниже. –

ответ

6

Я нашел исправление. Delphi, кажется, есть несколько ошибок, связанных с этим:

  1. Значение опубликованного ItemHeight собственности вынужден быть 16, потому что класс TComboBoxEx отменяет функцию GetItemHt не быть жестко закодированы 16. не обращая внимания вообще для фактического размера элемента - странно, поскольку это отлично работает на TComboBox. Я не знаю, почему они решили пойти с этой стратегией. Вероятно, чтобы изображения всегда соответствовали друг другу.
  2. Delphi фактически не вызывает сообщение CB_SETITEMHEIGHT, поэтому даже если вы переопределите эту функцию, ничего не изменится.

Update:

Как отметил mghie, моя первоначальная идея использования жестко закодированное значение 15 в вызове сообщение не работает при различных настройках DPI. Поэтому я теперь использую calll для GetTextMetrics для определения высоты. Добавлением к высоте шрифта является значение GetSystemMetrics (SM_CYBORDER).

Это основано на том, как VCL определяет размер TEdit.Я не думаю, что это совершенно правильно, но поскольку цель состоит в том, чтобы ComboBoxEx имел тот же размер, что и TEdit, он, вероятно, так близок, что мы получим. И он работает при настройках DPI 96, 120, 144 и 192.

Высота ComboBoxEx определяется высотой позиции -1. Таким образом, элементы 0 для count-1 являются фактическими элементами списка, но элемент -1 - это высота, используемая для редактора. Если вы установите эту высоту на 15, высота элемента управления будет скорректирована на 21 пиксель (см. Выше приведенное выше для масштабирования проблем). Я думаю, что Мейсон может быть прав, что размер шрифта здесь играет роль (вероятно, изменяет размер элемента), но вы можете сделать его очень просто, регулируя размер элемента.

Как представляется, новая проблема (на мой взгляд, меньше) заключается в том, что на 96-пиксельных 16-пиксельных изображениях снижается самая нижняя строка, когда отображается в части редактора, но это едва заметно.

Так исправить то, чтобы назвать этот код:

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

TEdit на моем ноутбуке с настройкой DPI 124, безусловно, не высотой 21 пиксель. Жестко закодированные высоты просто неправильны, независимо от того, работают они на вас или нет, а возврат 15 не лучше, чем возврат 16. Как насчет разных шрифтов или настроек DPI? Реальное исправление предполагает получение высоты шрифта и вычисление высоты элемента на основе этого. – mghie

+0

-1 для жестко закодированных констант, таких как mghie. –

+0

Точка, занятая настройкой DPI. Поэтому теперь мне нужно знать, как вычисляется высота поля редактирования. Я посмотрел на вычисление высоты элемента, основываясь на высоте шрифта, но я не вижу, как это добралось до 16 в первую очередь - я на самом деле думаю, что он был выбран так, чтобы соответствовать 16x16 глифам. То, что работает как на 96 DPI, так и на 120, вызывает GetTextMetric и использует tmHeight + 2. Я думал, что использование tmHeight + tmInternalLeading будет правильным, но это работает только при 120 DPI. Я могу начать с 15 и масштабировать, что от 96 до 120, но это тоже не кажется правильным. Любые идеи? –

1

Высота TComboBox не является абсолютной; он привязан к высоте шрифта, который вы используете. TComboBoxEx работает одинаково, но, похоже, у вас есть один дополнительный пиксель «накладных расходов», как вы уже отмечали, и, похоже, нет простого способа его изменения. Если это оболочка для встроенного элемента управления Windows, не может быть никакого способа изменить его на уровне Delphi, периоде.

+0

Если вы не хотите создавать свою собственную версию, но я не думаю, что это правильный вариант ;-). –

1

Два способа изменить высоту TComboBoxEx, к сожалению, не то, что вы хотите.

  • Установить свойство font.size меньше - коробка будет уменьшаться. (однако ваш текст меньше)

  • Установите StyleEx.csExNoSizeLimit: = false, а затем установите Height: = 21 по желанию. К сожалению, это просто заставляет вашу коробку быть обрезанной, поэтому нижняя рамка исчезает.

я бы, вероятно, заменить все TComboBoxes с TComboBoxEx - GExperts имеет блестящий «заменить компоненты» мастера для этого.

Это похоже на ошибку Delphi. Вы сообщили об этом через QC?

+0

Добавлен отчет о контроле качества. Ссылка добавлена ​​к вопросу. –

Смежные вопросы