Recent

Author Topic: TBCComboBox and event OnDrawSelectedItem  (Read 1333 times)

petevick

  • Sr. Member
  • ****
  • Posts: 427
TBCComboBox and event OnDrawSelectedItem
« on: March 19, 2022, 10:08:41 pm »
I'm looking at using the above event as I think it may be useful in my project, but when I create the event, even with no code in it, the text on control disappears. I've queried it and the .Text property for the control shows what I would expect to be displayed. I have to admit I don't really know what this event is supposed to do, I was just trying to find out by trial and error. With no OnDrawSelectedItem event the control displays the text property as expected.

Also if I try to remove the OnDrawSelectedItem event by selecting (none) from the drop down list, it is ignored. All very odd.
Pete Vickerstaff
Linux Mint 21.3 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

dseligo

  • Hero Member
  • *****
  • Posts: 1686
Re: TBCComboBox and event OnDrawSelectedItem
« Reply #1 on: March 19, 2022, 10:38:41 pm »
Not sure about that control, but usually you are supposed to draw on your own when using ondraw event.
Try to put
Code: Pascal  [Select][+][-]
  1. Inherited;
in the body - that way you will call original method.

lainz

  • Hero Member
  • *****
  • Posts: 4743
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: TBCComboBox and event OnDrawSelectedItem
« Reply #2 on: March 19, 2022, 11:52:39 pm »
That event is to override the drawing of the items. Please check the demos. I can't remember the name of the demo folder just browse.

petevick

  • Sr. Member
  • ****
  • Posts: 427
Re: TBCComboBox and event OnDrawSelectedItem
« Reply #3 on: March 20, 2022, 08:09:14 am »
That event is to override the drawing of the items. Please check the demos. I can't remember the name of the demo folder just browse.
Hi lainz, where will I find the demos?, I found a local folder called test but the combobox example doesn't include the OnDrawSelectedItem event.
Pete Vickerstaff
Linux Mint 21.3 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Re: TBCComboBox and event OnDrawSelectedItem
« Reply #4 on: March 29, 2022, 09:27:29 am »
@Petevick

  • Create a new program
  • Add BGRABitmapPack to the required packages
  • Drop a TComboBox on the form.

The use clause of the interface and the declaration of the class TForm1 should look like this:
Code: Pascal  [Select][+][-]
  1. uses
  2.    Classes , SysUtils , Forms , Controls , Graphics , Dialogs , StdCtrls, Types,
  3.    BGRABitmapTypes, BGRABitmap;
  4.  
  5. type
  6.  
  7.    { TForm1 }
  8.  
  9.    TForm1 = class(TForm)
  10.       ComboBox1: TComboBox;
  11.       procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState);
  12.       procedure FormCreate(Sender: TObject);
  13.    private
  14.       Procedure LoadDaysOfTheWeek;
  15.    public
  16.  
  17.    end;
  18.  

Basically, there are two steps to manage here:
  • Loading the items in the combo box: that's handled by LoadDaysOfTheWeek which is called from FormCreate
  • Displaying the items in the combo box which is managed by ComboBox1DrawItem

To load the items, you would call a method from the FormCreate event handler (or the constructor of a frame). The method might look something like this:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.LoadDaysOfTheWeek;
  2. begin
  3.   With ComboBox1 do
  4.   begin
  5.     Style := csOwnerDrawEditableVariable;
  6.     With Items do
  7.     begin
  8.       Clear;
  9.       Add('Sunday');
  10.       Add('Monday');
  11.       Add('Tuesday');
  12.       Add('Wednesday');
  13.       Add('Thursday');
  14.       Add('Friday');
  15.       Add('Saturday');
  16.     end;
  17.   end;
  18. end;
  19.  

Note that we set the style of the combobox to csOwnerDrawEditableVariable so that the elements are properly drawn.

Next, in the DrawItem even handler, we draw these items. This might look like this:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState);
  2. var aColor : TBGRAPixel;
  3.     B      : TBGRABitmap;
  4.     S      : String     ;
  5. //If the item is selected or focused, draw it in bold white on a purple background,
  6. //otherwise draw it with its own color as indicated below.
  7. begin
  8.   S := ComboBox1.Items[Index];
  9.   B := TBGRABitmap.Create(aRect.Width, aRect.Height, BGRAWhite);
  10.   B.FontHeight := 12;
  11.   If [odSelected, odFocused] * State <> []
  12.   then begin
  13.     B.FillRect(1,1,aRect.Width,aRect.Height,VGAPurple);
  14.     B.FontStyle := [fsBold];
  15.     B.TextOut(1, 1 ,S,BGRAWhite);
  16.   end
  17.   else begin
  18.     case Index of
  19.        0 : aColor := VGABlue    ;
  20.        1 : aColor := VGARed     ;
  21.        2 : aColor := VGAGreen   ;
  22.        3 : aColor := VGAFuchsia ;
  23.        4 : aColor := VGAMaroon  ;
  24.        5 : aColor := VGANavy    ;
  25.        6 : aColor := VGAOlive   ;
  26.     end;
  27.     B.TextOut(1,1,S,aColor);
  28.   end;
  29.   B.Draw(ComboBox1.Canvas,aRect);
  30.   B.Free;
  31. end;
  32.  

Note that in this case, you do not invoke the FormPaint event since the painting will take place after the DrawItem event handler has been called.

Cheers,


 

TinyPortal © 2005-2018