2

How do I put a bitmap in a combobox with style set to simple? For example, Google Chrome has the star on the right, Firefox has the arrow on the right. I tried this code:

procedure TForm2.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
ComboBox: TComboBox;
bitmap: TBitmap;
begin
ComboBox := (Control as TComboBox);
Bitmap := TBitmap.Create;
try
ImageList1.GetBitmap(0, Bitmap);
with ComboBox.Canvas do
begin
  FillRect(Rect);
  if Bitmap.Handle <> 0 then Draw(Rect.Left + 2, Rect.Top, Bitmap);
  Rect := Bounds(Rect.Left + ComboBox.ItemHeight + 2, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top);
  DrawText(handle, PChar(ComboBox.Items[0]), length(ComboBox.Items[0]), Rect, DT_VCENTER+DT_SINGLELINE);
end;
finally
Bitmap.Free;
  end;
end;

works, but only with style: csOwnerDrawFixed and csOwnerDrawVariable, also the bitmaps are only visible on the items.

Thanks.

Giacomo King Patermo
  • 829
  • 3
  • 13
  • 25
  • 1
    Don't know about Chrome, but Firefox does not use a native control. – Sertac Akyuz Jan 11 '13 at 17:46
  • Thank you, you know any component where you can do this? – Giacomo King Patermo Jan 11 '13 at 17:53
  • What's wrong with owner draw combo? – David Heffernan Jan 11 '13 at 19:57
  • Chrome and Firefox do not use standard combo boxes. They're entirely custom controls. If you write a custom control, you can make it look however you want, just like the Google and Mozilla developers did. – Rob Kennedy Jan 11 '13 at 20:24
  • 1
    Yes, you have to use one of the OwnerDraw styles in order to customize the look of the ComboBox items. If that is not doing what you need it to do, then please provide a screenshot of what you are actually trying to accomplish (for those of us who don't use Chrome or Firefox). – Remy Lebeau Jan 11 '13 at 20:33

1 Answers1

7

... also the bitmaps are only visible on the items.

To draw your bitmap in the editor of an owner drawn combo box, check for odComboBoxEdit in the owner draw state:

enter image description here

type
  TComboBox = class(StdCtrls.TComboBox)
  private
    FBmp: TBitmap;
    FBmpPos: TPoint;
  protected
    procedure DrawItem(Index: Integer; Rect: TRect;
      State: TOwnerDrawState); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

constructor TComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FBmp := TBitmap.Create;
  FBmp.Canvas.Brush.Color := clGreen;
  FBmp.Width := 16;
  FBmp.Height := 16;
end;

destructor TComboBox.Destroy;
begin
  FBmp.Free;
  inherited Destroy;
end;

procedure TComboBox.DrawItem(Index: Integer; Rect: TRect;
  State: TOwnerDrawState);
begin
  TControlCanvas(Canvas).UpdateTextFlags;
  if Assigned(OnDrawItem) then
    OnDrawItem(Self, Index, Rect, State)
  else
  begin
    Canvas.FillRect(Rect);
    if Index >= 0 then
      Canvas.TextOut(Rect.Left + 2, Rect.Top, Items[Index]);
    if odComboBoxEdit in State then
    begin
      Dec(Rect.Right, FBmp.Width + Rect.Left);
      FBmpPos.X := Rect.Right + Rect.Left;
      FBmpPos.Y := (Height - FBmp.Height) div 2;
      if ItemIndex > -1 then
        Canvas.TextOut(Rect.Left + 2, Rect.Top, Items[ItemIndex]);
      Canvas.Draw(FBmpPos.X, FBmpPos.Y, FBmp);
    end;
  end;
end;

In order to draw a bitmap on non-owner drawn combo boxes, you will have to paint in the window of the combo box itself by using a customized WM_NCPAINT handler.

NGLN
  • 43,011
  • 8
  • 105
  • 200