The Study

home |  about

Programming

Introduction

Delphi

Java

Projects

Graphics

Introduction

POV-Ray

Terragen

Music

Introduction

Work in Progress

Oddments

Library

Miscellaneous

How to mimic an Outlook bar

Back to How to index

A Cautionary Note

The title of this 'How to' is 'how to mimic an Outlook bar...'. The end result is a long way from being a true outlook bar. It's main drawbacks are that the group button and the group items are the same size, and that you should be careful not let the caption become too wide, or horizontal scrollbars will appear, and the caption will become corrupted if the scrollbar is used.

This version does not include bitmaps, but if you know how to draw bitmaps onto a canvas (not hard - the Delphi TreeView help gives a good example) you can rectify this. Or maybe I will add this myself in a future update...

Code

This code assumes that TreeView component is called OutlookTree. Create a CustomDrawItem event-handler for it, and enter the code listed below.

The TreeView component should only include top level and first level items - the top level items will become the groups, and the first level items beneath them will become the group items.

Set the TreeView colour to clAppWorkSpace. For best effect, the TreeView component should have the RowSelect and AutoExpand options set to True.

procedure TForm1.OutlookTreeCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  NodeRect: TRect;
  X, Y, W: integer;
begin
  with OutlookTree.Canvas do
  begin
    { Set DefaultDraw to False -- we will do *all* the drawing ourselves. }
    DefaultDraw := False;
    { Get the rectangle enclosing the area for the current. }
    NodeRect := Node.DisplayRect(False);
    if (Node.Level = 0) then
    begin
      { Draw the top-level buttons: grey, with a 'button' border. }
      Brush.Color := clBtnFace;
      FillRect(NodeRect);
      Pen.Color   := clBtnHighlight;
      MoveTo(NodeRect.Right, NodeRect.Top);
      LineTo(NodeRect.Left, NodeRect.Top);
      LineTo(NodeRect.Left, NodeRect.Bottom - 1);
      Pen.Color := clBlack;
      LineTo(NodeRect.Right - 1, NodeRect.Bottom - 1);
      LineTo(NodeRect.Right - 1, NodeRect.Top);
      Pen.Color := clWindowText;
      Font.Color := clWindowText;
    end
    else
    begin
      { Draw the 'items': use the workspace colour, and mark the selected
        item (if any) by displaying it 'pressed' }
      NodeRect := Node.DisplayRect(False);
      Brush.Color := clAppWorkSpace;
      Brush.Style := bsSolid;
      FillRect(NodeRect);
      if cdsSelected in State then
      begin
        Pen.Color   := clBlack;
        MoveTo(NodeRect.Right, NodeRect.Top);
        LineTo(NodeRect.Left, NodeRect.Top);
        LineTo(NodeRect.Left, NodeRect.Bottom - 1);
        Pen.Color := clBtnHighlight;
        LineTo(NodeRect.Right - 1, NodeRect.Bottom - 1);
        LineTo(NodeRect.Right - 1, NodeRect.Top);
        Pen.Color := clWindowText;
      end;
    end;
    { Draw the caption, centred. }
    W := TextWidth(Trim(Node.Text));
    X := ((NodeRect.Right - NodeRect.Left) div 2) - (W div 2);
    Y := NodeRect.Top + 1;
    TextOut(X - 8, Y, Node.Text);
  end;
end;