2009-05-01 2 views
3

Мне нужно нарисовать на TPanel, в идеале прямо, поэтому у меня нет другого компонента поверх него, мешающего захвату событий mousevent (я хочу нарисовать немного " захват "на нем). Как мне это сделать?Как нарисовать на TPanel

+0

я удивляюсь, как вам удалось создать compoennts тег? ;) как и ваш вопрос +1 –

+0

Это была опечатка. Я исправил его ... –

+0

Спасибо - @MasterPeter за улыбку и @Mason Wheeler за исправление. – Jamo

ответ

9

Для того чтобы действительно сделать это правильно, вы, вероятно, следует написать потомок класса. Переопределите метод Paint, чтобы нарисовать размерную ручку и переопределить методы MouseDown, MouseUp и MouseMove, чтобы добавить функциональность изменения размера в элемент управления.

Я думаю, что это лучшее решение, чем пытаться рисовать на TPanel в коде приложения для нескольких причин:

  1. Свойство Canvas защищен в TPanel, поэтому у вас нет доступа к нему снаружи класс. Вы можете обойти это с типом, но это обман.
  2. «Изменчивость» звучит скорее как функция панели, чем функция приложения, поэтому поместите ее в код для управления панелью, а не в основной код приложения.

Вот что-то, чтобы вы начали:

type 
    TSizablePanel = class(TPanel) 
    private 
    FDragOrigin: TPoint; 
    FSizeRect: TRect; 
    protected 
    procedure Paint; override; 
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; 
     X, Y: Integer); override; 
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; 
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; 
     X, Y: Integer); override; 
    end; 

procedure TSizeablePanel.Paint; 
begin 
    inherited; 
    // Draw a sizing grip on the Canvas property 
    // There's a size-grip glyph in the Marlett font, 
    // so try the Canvas.TextOut method in combination 
    // with the Canvas.Font property. 
end; 

procedure TSizeablePanel.MouseDown; 
begin 
    if (Button = mbLeft) and (Shift = []) 
     and PtInRect(FSizeRect, Point(X, Y)) then begin 
    FDragOrigin := Point(X, Y); 
    // Need to capture mouse events even if the mouse 
    // leaves the control. See also: ReleaseCapture. 
    SetCapture(Handle); 
    end else inherited; 
end; 
+0

Спасибо, Роб! То, что вы описываете (и щедро предоставило некоторый «код стартера» для), - это то, что я пытаюсь сделать, но я понял, что мне нужно выяснить часть чертежа/холста, поэтому было изучено это непосредственно в коде приложения. Большое спасибо за ваш вклад здесь - супер полезно! :-) – Jamo

+0

Обратите внимание, что это также мудро, потому что, например, Lazarus на не-окнах (и, возможно, Kylix тоже), не разрешайте рисовать на холсте вне события .PAINT. Таким образом, может быть разумно непосредственно внедрять структуру, которая гарантирует, что единственный рисунок будет выполнен в событии рисования. –

4

Простейший способ сделать это - просто поместить TImage на панель. Но если вы действительно этого не хотите, введите TCanvas в редактор кода, нажмите F1 и получайте удовольствие от изучения того, как он работает под капотом. (Не говорите, что я вас не предупреждал ...)

+0

На самом деле я думаю, что могу сделать часть TCanvas, учитывая некоторый пример кода, с которым мне приходится работать ... НО, как мне показать TCanvas самой панели? Я нашел это, но похоже, что чего-то не хватает: http://www.mail-archive.com/[email protected]/msg00582.html – Jamo

+1

Код TMyPanel (панель) с этой ссылкой является ключом. Если вы определяете унаследованный класс в том же подразделении, где вы хотите получить доступ к холсту, вы можете получить доступ к любому защищенному свойству класса. Это часть принципа Delphi «классы внутри единицы - друзья». Это тоже взломать.:-) –

+0

Когда вы говорите: «Это тоже хак» - значит ли это, по вашему мнению, неуместно? (Просто пытаясь узнать все, что я могу от этих замечательных ответов, я задаюсь этим вопросом). – Jamo

7

Это один из многих способов, которыми Raize Components может сделать вашу жизнь проще. Я просто иду в Delphi, падение на TRzPanel и тип:

RzPanel1.Canvas.Rectangle ...

Я уверен, что есть и другие решения - но я не должен ищите их с Raize.

(только удовлетворенный клиент в течение 10 лет ...)

EDIT: Учитывая вашу цель, и ваше утверждение, что у вас есть Raize компоненты уже, я хотел бы также отметить, что TRzSizePanel обрабатывает изменение размеров панели и такие как OnCanResize (чтобы определить, хотите ли вы разрешить изменение размера для определенной новой ширины или высоты).

+0

Great - I * HAVE * Raize, так что посмотрим на это (не раньше по причинам, связанным с желанием начать «как простой/низкий уровень как практический», но это может быть лучший маршрут). Спасибо, что нашли время, чтобы опубликовать это. – Jamo

+0

Как Raize делает это проще, чем рисовать на обычной TPanel? По какой-то причине, если элементы управления Raize не делают свойство Canvas публичным, а не защищенным. –

+1

Из примера кода, казалось бы, именно по этой причине. –