I found a fix. Delphi seems to have a couple of bugs relating to this:
- 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.
- 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);