Здравствуйте уважаемые коллеги!
Как рисовать на канве 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.rar
Если есть вопросы — пишите в комментариях или на почту: info@asd-soft.ru