Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get TComboBoxEx to be the same Height as TComboBox?

Tags:

height

delphi

In Delphi, all the TEdit and TComboBox controls are 21 pixels high by default. In the case of TComboBox, this size is absolute and trying to stretch it to something bigger doesn't work. In the case of TComboBoxEx though, the default height is 22 pixels, which makes it stand out a little on any form where you use it. Now according to the Microsoft docs, ComboBoxEx is essentially a ComboBox with owner-drawn functionality being handled to allow images and indentation.

So is it possible to make my TComboBoxEx controls 21 pixels high? What does this depend on?

Update: I added a Quality Central report on the issue, as suggested by Roddy. Also, I found a fix. Apparently, the size depends on the size of item -1 in the combobox. So you set that size to 15 (or one pixel less than the default size) and the box shrinks to the more familiar 21 pixels.

like image 332
Cobus Kruger Avatar asked Aug 21 '09 13:08

Cobus Kruger


2 Answers

I found a fix. Delphi seems to have a couple of bugs relating to this:

  1. The value of the published ItemHeight property is forced to be 16, because the TComboBoxEx class overrides the GetItemHt function to be a hard-coded 16. No regard whatsoever for the actual size of the item - strange, as this works perfectly on TComboBox. I don't know why they decided to go with this strategy. Probably to ensure the images will always fit.
  2. Delphi doesn't actually call the CB_SETITEMHEIGHT message, so even if you override this function nothing changes.

Update:

As pointed out by mghie, my initial idea of using a hard-coded value of 15 in calling the message doesn't work well at different DPI settings. So I am now using a calll to GetTextMetrics to determine the height. Added to the height of the font is the value of GetSystemMetrics(SM_CYBORDER).

This is based on the way the VCL determines the size of a TEdit. I don't think it is quite right, but since the goal is to have the ComboBoxEx the same size as TEdit it is probably as close as we'll get. And it works at DPI settings of 96, 120, 144 and 192.

The height of the ComboBoxEx is determined by the height of item -1. So items 0 to count-1 are the actual list items, but item -1 is the height used for the editor. If you set that height to 15, the height of the control is corrected to be 21 pixels (see update above for scaling issues). I think Mason may be right that the font size plays a part here (probably resizes the item), butyou can make it work just fine by adjusting the item size.

It does seem to introduce a new (in my view, smaller) problem in that at 96 DPI 16-pixel high images loose the bottom-most line when shown in the editor portion, but that's hardly noticeable.

So the fix then, is to call this code:

GetTextMetrics(Canvas.Handle, TM);
SendMessage(Handle, CB_SETITEMHEIGHT, -1, 
  GetSystemMetrics(SM_CYBORDER) * 2 + TM.tmHeight);
like image 180
Cobus Kruger Avatar answered Nov 15 '22 06:11

Cobus Kruger


The height of a TComboBox isn't absolute; it's tied to the height of the font you use. TComboBoxEx works the same way, but it seems to have one extra pixel of "overhead", as you've noted, and there doesn't seem to be any simple way to change that. If this is a wrapper for a built-in Windows control, there may not be any way to change it at the Delphi level, period.

like image 34
Mason Wheeler Avatar answered Nov 15 '22 06:11

Mason Wheeler