Я нашел исправление. Delphi, похоже, имеет несколько ошибок, связанных с этим:
- Значение опубликованного свойства ItemHeight должно быть равно 16, потому что класс TComboBoxEx переопределяет функцию GetItemHt, чтобы быть жестко закодированным 16. Независимо от фактического размера элемента - странно, поскольку это прекрасно работает на TComboBox. Я не знаю, почему они решили пойти с этой стратегией. Вероятно, чтобы изображения всегда подходили.
- На самом деле Delphi не вызывает сообщение CB_SETITEMHEIGHT, поэтому даже если вы переопределите эту функцию, ничего не изменится.
Обновление:
Как указал mghie, моя первоначальная идея использовать жестко заданное значение 15 при вызове сообщения не работает при разных настройках DPI. Так что теперь я использую вызов GetTextMetrics для определения высоты. К высоте шрифта добавлено значение GetSystemMetrics (SM_CYBORDER).
Это основано на том, как VCL определяет размер TEdit. Я не думаю, что это совершенно правильно, но поскольку цель состоит в том, чтобы ComboBoxEx был такого же размера, как TEdit, он, вероятно, настолько близок, насколько мы получим. И это работает при настройках DPI 96, 120, 144 и 192.
Высота ComboBoxEx определяется высотой элемента -1. Таким образом, элементы от 0 до count-1 являются фактическими элементами списка, а item-1 - это высота, используемая для редактора. Если вы установите эту высоту равной 15, высота элемента управления будет исправлена на 21 пиксель (проблемы с масштабированием см. В обновлении выше) . Я думаю, что Мейсон может быть прав, что размер шрифта играет здесь роль (возможно, изменяет размер элемента), но вы можете заставить его работать нормально, отрегулировав размер элемента.
Кажется, что это представляет новую (на мой взгляд, меньшую) проблему в том, что при 96 DPI 16-пиксельные изображения теряют самую нижнюю линию при отображении в части редактора, но это едва заметно.
Итак, исправление состоит в том, чтобы вызвать этот код:
GetTextMetrics(Canvas.Handle, TM);
SendMessage(Handle, CB_SETITEMHEIGHT, -1,
GetSystemMetrics(SM_CYBORDER) * 2 + TM.tmHeight);