5

在 Delphi 中,所有的 TEdit 和 TComboBox 控件默认都是 21 像素高。在 TComboBox 的情况下,这个大小是绝对的,试图将它拉伸到更大的东西是行不通的。但是,在 TComboBoxEx 的情况下,默认高度是 22 像素,这使它在您使用它的任何形式上都显得有点突出。现在根据Microsoft 文档,ComboBoxEx 本质上是一个 ComboBox,它处理了所有者绘制的功能以允许图像和缩进。

那么是否可以让我的 TComboBoxEx 控件高 21 个像素?这取决于什么?

更新:按照 Roddy 的建议,我添加了有关该问题的Quality Central 报告。另外,我找到了解决方法。显然,大小取决于组合框中项目 -1 的大小。因此,您将该大小设置为 15(或比默认大小小 1 个像素),并且框会缩小到更熟悉的 21 个像素。

4

3 回答 3

6

我找到了解决办法。Delphi 似乎有几个与此相关的错误:

  1. 发布的 ItemHeight 属性的值被强制为 16,因为 TComboBoxEx 类将 GetItemHt 函数覆盖为硬编码的 16。不考虑项目的实际大小 - 奇怪,因为这在 TComboBox 上完美运行。我不知道他们为什么决定采用这种策略。可能是为了确保图像始终适合。
  2. 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);
于 2009-08-21T14:33:07.630 回答
1

TComboBox 的高度不是绝对的;它与您使用的字体的高度相关。TComboBoxEx 的工作方式相同,但正如您所指出的,它似乎有一个额外的“开销”像素,并且似乎没有任何简单的方法可以改变它。如果这是内置 Windows 控件的包装器,则可能无法在 Delphi 级别更改它。

于 2009-08-21T13:42:08.680 回答
1

改变 TComboBoxEx 高度的两种方法,不幸的是,这两种方法都不是你想要的。

  • 将 font.size 属性设置得更小——盒子会缩小。(但是,您的文字较小)

  • 设置 StyleEx.csExNoSizeLimit := false,然后根据需要设置 Height := 21。不幸的是,这只会导致您的盒子被夹住,因此底部挡板消失了。

我可能会用 TComboBoxEx 替换所有 TComboBoxes - GExperts有一个出色的“替换组件”向导来执行此操作。

这看起来像一个 Delphi 错误。您是否通过 QC 报告过?

于 2009-08-21T13:45:44.980 回答