我找到了解决办法。Delphi 似乎有几个与此相关的错误:
- 发布的 ItemHeight 属性的值被强制为 16,因为 TComboBoxEx 类将 GetItemHt 函数覆盖为硬编码的 16。不考虑项目的实际大小 - 奇怪,因为这在 TComboBox 上完美运行。我不知道他们为什么决定采用这种策略。可能是为了确保图像始终适合。
- Delphi 实际上并没有调用 CB_SETITEMHEIGHT 消息,所以即使你重写了这个函数,也没有任何改变。
更新:
正如mghie 所指出的,我最初在调用消息时使用硬编码值15 的想法在不同的DPI 设置下效果不佳。所以我现在使用对 GetTextMetrics 的调用来确定高度。添加到字体高度的是 GetSystemMetrics(SM_CYBORDER) 的值。
这是基于 VCL 确定 TEdit 大小的方式。我认为这不太对,但由于目标是使 ComboBoxEx 的大小与 TEdit 相同,因此它可能与我们将得到的一样接近。它适用于 96、120、144 和 192 的 DPI 设置。
ComboBoxEx 的高度由项目-1 的高度决定。所以项目 0 到 count-1 是实际的列表项目,但项目 -1 是用于编辑器的高度。如果将该高度设置为 15,则控件的高度将被更正为 21 像素(有关缩放问题,请参见上面的更新)。我认为 Mason 可能是正确的,字体大小在这里起作用(可能会调整项目的大小),但是您可以通过调整项目大小使其正常工作。
它似乎确实引入了一个新的(在我看来,较小的)问题,即在 96 DPI 16 像素高的图像在编辑器部分显示时最底线松动,但这几乎不引人注意。
因此,修复方法是调用此代码:
GetTextMetrics(Canvas.Handle, TM);
SendMessage(Handle, CB_SETITEMHEIGHT, -1,
GetSystemMetrics(SM_CYBORDER) * 2 + TM.tmHeight);