Рисование на канве (TCanvas) панели (TPanel) в Delphi

Здравствуйте уважаемые коллеги!

Как рисовать на канве TCanvas компонента TPanel — вопрос, на который я постараюсь дать ответ в данной статье.
Известно, что компонент TPanel не позволяет рисовать на своей канве, но есть способ обойти это ограничение…

Компонент TPanel в качестве родительского класса использует TCustomControl, у которого присутствует свойство Canvas и процедура Paint. Оба они находятся в разделе Protected, что означает что мы не можем использовать его напрямую, но можем получить доступ в дочернем классе.

Создадим собственный класс, унаследовав его от стандартного TPanel:

type
  TDrawPanel = class(TPanel)
  private
    FOnPaint: TNotifyEvent;
  protected
    procedure Paint; override;
  public
    property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
    property Canvas;
  end;

Вынесем свойство Canvas в раздел public что бы мы могли использовать его в созданных экземплярах данного класса.
Заменяем виртуальный метод Paint.
И добавляем событие OnPaint, которое будет вызываться в методе Paint, который в свою очередь срабатывает при перерисовке компонента.

В разделе implementation опишем метод Paint:

{ TDrawPannel }

procedure TDrawPanel.Paint;
begin
  inherited;
  if Assigned(FOnPaint) then
    FOnPaint(Self);
end;

if Assigned(FOnPaint) then — Если присвоено событие OnPaint, то вызовем его, передав себя (ключевое слово Self) в качестве параметра.

Пример использования:

type
  TDrawPanel = class(TPanel)
  private
    FOnPaint: TNotifyEvent;
  protected
    procedure Paint; override;
  public
    property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
    property Canvas;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FDrawPanel: TDrawPanel;
    procedure Draw(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TDrawPanel }

procedure TDrawPanel.Paint;
begin
  inherited;
  if Assigned(FOnPaint) then
    FOnPaint(Self);
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  FDrawPanel := TDrawPanel.Create(Self); // Создаем панель
  FDrawPanel.Parent := Self; // В качестве родителя указываем форму
  FDrawPanel.Caption := ''; // Уберем текст caption
  FDrawPanel.Left := 5;
  FDrawPanel.Top := 5;
  FDrawPanel.Width := Self.ClientWidth - 10;
  FDrawPanel.Height := Self.ClientHeight - 10;
  FDrawPanel.OnPaint := Draw; // Определим в качестве процедуры перерисовки процедуру Draw
end;

procedure TForm1.Draw(Sender: TObject);
// Список цветов
const
  Colors: array[0..15] of integer = (clMaroon, clGreen, clOlive, clNavy,
    clPurple, clTeal, clGray, clSilver, clRed, clLime, clYellow, clBlue,
    clFuchsia, clAqua, clLtGray, clDkGray);
var
  i,x,y: integer;
begin
  for i := 0 to 30 do begin
    x := Random(TDrawPanel(Sender).ClientWidth-20)+10; //Берем случайную координату из панели
    y := Random(TDrawPanel(Sender).ClientHeight-20)+10; // отступив от края по 10 пикселей
    with TDrawPanel(Sender).Canvas do begin
      Brush.Color := Colors[Random(Length(Colors))-1]; // Берем случайный цвет заливки 
      Pen.Color := Colors[Random(Length(Colors))-1]; // Берем случайный цвет границы
      Ellipse(x,y,x+10,y+10); // Рисуем круг
    end;
  end;
end;

После запуска можем наблюдать нарисованные кружки на панели:
DrawPanel

Исходники примера можно скачать тут: drawpanel.rar

Если есть вопросы — пишите в комментариях или на почту: info@asd-soft.ru

Статья добавлена в Delphi. Добавить ссылку в закладки.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *