0

I have an owner-drawn TComboBox in Delphi Seattle which ignores any settings to the DropDownCount property. The height of the individual items is 59 pixels and the width is 311 pixels. I have 5 entries in the Items stringlist. Setting a value below 8 results in no dropdown being shown at all, while any higher values result in only 1 item being shown in the dropdown along with a vertical scrollbar. I need to be able to show all 5 entries in the items list in the dropdown.

Here's the DFM to reproduce the problem:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 223
  ClientWidth = 527
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ComboBox1: TComboBox
    Left = 96
    Top = 16
    Width = 311
    Height = 22
    Style = csOwnerDrawVariable
    ItemIndex = 0
    TabOrder = 0
    Text = 'ITEM ONE'
    OnDrawItem = ComboBox1DrawItem
    OnMeasureItem = ComboBox1MeasureItem
    Items.Strings = (
      'ITEM ONE'
      'ITEM TWO'
      'ITEM THREE'
      'ITEM FOUR'
      'ITEM FIVE')
  end
end

And here's the PAS file:

unit CBBoxBugUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
    procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var Working_String : String;
    Text_Width ,
    Text_Height ,
    Output_X ,
    Output_Y       : Integer;
begin
  ComboBox1.Canvas.Pen.Color := clWhite;
  ComboBox1.Canvas.Brush.Color := clGreen;
  ComboBox1.Canvas.Brush.Style := bsSolid;
  ComboBox1.Canvas.Pen.Style := psSolid;
  ComboBox1.Canvas.Pen.Width := 1;
  ComboBox1.Canvas.Font.Color := clWhite;
  ComboBox1.Canvas.Font.Name := 'ARIAL BLACK';
  ComboBox1.Canvas.Font.Size := 14;
  ComboBox1.Canvas.FillRect( Rect );
  Working_String := self.ComboBox1.Items.Strings[ Index ];
  Text_Width := self.ComboBox1.Canvas.TextWidth( Working_String );
  Text_Height := self.ComboBox1.Canvas.TextHeight( Working_String );
  Output_X := ( Rect.Width - Text_Width ) div 2;
  Output_Y := ( Rect.Height - Text_Height ) div 2;
  ComboBox1.Canvas.TextOut( Output_X , Output_Y , Working_String );
end;

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
begin
  Height := 59;
end;

end.
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • 1
    Recommended reading: [**Welcome to SO**](http://stackoverflow.com/tour) and also [**Help Center**](http://stackoverflow.com/help) especially about asking questions. – Tom Brunberg Feb 01 '16 at 08:10
  • 2
    I can not reproduce the behaviour you describe. Please provide a [**Minimal, Complete, and Verifiable example**](http://stackoverflow.com/help/mcve) – Tom Brunberg Feb 01 '16 at 08:11
  • We can't debug code we can't see. If you want help with your code, we need to be able to see the code. – Ken White Feb 01 '16 at 13:48
  • Apologies. I thought this was a known issue that I somehow couldn't find the fix for online. I'll post a minimum app reproducing the bug in a few minutes. (Actual code causing problem is (a) huge and (b) proprietary so can't post that.) In the meantime, I've found that if I increase the total entries in the Items field I can get more entries in the dropdown but still not the same as in dropdowncount; the docs say that if you enter fewer than the total entries the dropdown is limited to the total so there may be something going on with that... – Nathan Wallace Feb 04 '16 at 11:21
  • I didn't have this problem in Seattle, but I do have it in Berlin. When I compile for FMX Win32. No problem on Android though. – Freddie Bell Apr 27 '16 at 05:49

1 Answers1

0

Even though the documentation for ItemHeight of TComboBox states:

... If Style is csOwnerDrawVariable, ItemHeight is the default height for drawing list items, but this value can be overridden by an OnMeasureItem event handler. ...

VCL has internal calculations that depend on FItemHeight. Set ItemHeight to 59 and DropDownCount will be honored (it is already honored but for the default 16). If you set the value in design time, the combo will also adjust its size to that of at runtime.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169