Sizing Owner-draw Items

From RAD Studio
Jump to: navigation, search

Go Up to Adding Graphics to Controls


Before giving your application the chance to draw each item in a variable owner-draw control, the control receives a measure-item event, which is of type TMeasureItemEvent. TMeasureItemEvent tells the application where the item appears on the control.

The product determines the size of the item (generally, it is just large enough to display the item's text in the current font). Your application can handle the event and change the rectangle chosen. For example, if you plan to substitute a bitmap for the item's text, change the rectangle to the size of the bitmap. If you want a bitmap and text, adjust the rectangle to be large enough for both.

To change the size of an owner-drawn item, attach an event handler to the measure-item event in the owner-drawn control. Depending on the control, the name of the event can vary. List boxes and combo boxes use OnMeasureItem. Grids have no measure-item event.

The sizing event has two important parameters: the index number of the item and the height of that item. The height is variable: the application can make it either smaller or larger. The positions of subsequent items depend on the size of preceding items.

For example, in a variable owner-draw list box, if the application sets the height of the first item to five pixels, the second item starts at the sixth pixel down from the top, and so on. In list boxes and combo boxes, the only aspect of the item the application can alter is the height of the item. The width of the item is always the width of the control.

Owner-draw grids cannot change the sizes of their cells as they draw. The size of each row and column is set before drawing by the ColWidths and RowHeights properties.

The following code, attached to the OnMeasureItem event of an owner-draw list box, increases the height of each list item to accommodate its associated bitmap.

 procedure TFMForm.ListBox1MeasureItem(Control: TWinControl; Index: Integer;
   var Height: Integer);  { note that Height is a var parameter}
 var
   BitmapHeight: Integer;
 begin
   BitmapHeight := TBitmap(ListBox1.Items.Objects[Index]).Height;
   { make sure the item height has enough room, plus two }
   Height := Max(Height, Bitmap Height +2);
 end;
void __fastcall TForm1::ListBox1MeasureItem(TWinControl *Control, int Index,
		int &Height) // note that Height is passed by reference
{
	int BitmapHeight = ((TBitmap*)ListBox1->Items->Objects[Index])->Height + 2;
	// make sure list item has enough room for bitmap (plus 2)
	if (BitmapHeight > Height)
		Height = BitmapHeight;
}

Note: You must typecast the items from the Objects property in the string list. Objects is a property of type TObject so that it can hold any kind of object. When you retrieve objects from the array, you need to typecast them back to the actual type of the items.

See Also