Мне нужно нарисовать на TPanel, в идеале прямо, поэтому у меня нет другого компонента поверх него, мешающего захвату событий mousevent (я хочу нарисовать немного " захват "на нем). Как мне это сделать?Как нарисовать на TPanel
ответ
Для того чтобы действительно сделать это правильно, вы, вероятно, следует написать потомок класса. Переопределите метод Paint
, чтобы нарисовать размерную ручку и переопределить методы MouseDown
, MouseUp
и MouseMove
, чтобы добавить функциональность изменения размера в элемент управления.
Я думаю, что это лучшее решение, чем пытаться рисовать на TPanel
в коде приложения для нескольких причин:
- Свойство
Canvas
защищен вTPanel
, поэтому у вас нет доступа к нему снаружи класс. Вы можете обойти это с типом, но это обман. - «Изменчивость» звучит скорее как функция панели, чем функция приложения, поэтому поместите ее в код для управления панелью, а не в основной код приложения.
Вот что-то, чтобы вы начали:
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;
Спасибо, Роб! То, что вы описываете (и щедро предоставило некоторый «код стартера» для), - это то, что я пытаюсь сделать, но я понял, что мне нужно выяснить часть чертежа/холста, поэтому было изучено это непосредственно в коде приложения. Большое спасибо за ваш вклад здесь - супер полезно! :-) – Jamo
Обратите внимание, что это также мудро, потому что, например, Lazarus на не-окнах (и, возможно, Kylix тоже), не разрешайте рисовать на холсте вне события .PAINT. Таким образом, может быть разумно непосредственно внедрять структуру, которая гарантирует, что единственный рисунок будет выполнен в событии рисования. –
Простейший способ сделать это - просто поместить TImage на панель. Но если вы действительно этого не хотите, введите TCanvas в редактор кода, нажмите F1 и получайте удовольствие от изучения того, как он работает под капотом. (Не говорите, что я вас не предупреждал ...)
На самом деле я думаю, что могу сделать часть TCanvas, учитывая некоторый пример кода, с которым мне приходится работать ... НО, как мне показать TCanvas самой панели? Я нашел это, но похоже, что чего-то не хватает: http://www.mail-archive.com/[email protected]/msg00582.html – Jamo
Код TMyPanel (панель) с этой ссылкой является ключом. Если вы определяете унаследованный класс в том же подразделении, где вы хотите получить доступ к холсту, вы можете получить доступ к любому защищенному свойству класса. Это часть принципа Delphi «классы внутри единицы - друзья». Это тоже взломать.:-) –
Когда вы говорите: «Это тоже хак» - значит ли это, по вашему мнению, неуместно? (Просто пытаясь узнать все, что я могу от этих замечательных ответов, я задаюсь этим вопросом). – Jamo
Это один из многих способов, которыми Raize Components может сделать вашу жизнь проще. Я просто иду в Delphi, падение на TRzPanel и тип:
RzPanel1.Canvas.Rectangle ...
Я уверен, что есть и другие решения - но я не должен ищите их с Raize.
(только удовлетворенный клиент в течение 10 лет ...)
EDIT: Учитывая вашу цель, и ваше утверждение, что у вас есть Raize компоненты уже, я хотел бы также отметить, что TRzSizePanel обрабатывает изменение размеров панели и такие как OnCanResize (чтобы определить, хотите ли вы разрешить изменение размера для определенной новой ширины или высоты).
Great - I * HAVE * Raize, так что посмотрим на это (не раньше по причинам, связанным с желанием начать «как простой/низкий уровень как практический», но это может быть лучший маршрут). Спасибо, что нашли время, чтобы опубликовать это. – Jamo
Как Raize делает это проще, чем рисовать на обычной TPanel? По какой-то причине, если элементы управления Raize не делают свойство Canvas публичным, а не защищенным. –
Из примера кода, казалось бы, именно по этой причине. –
Как добавить Размер Ручка для управления изменением размера в Run-Time: http://delphi.about.com/library/weekly/aa110105a.htm
TAdvPanel: http://www.tmssoftware.com/site/advpanel.asp
Отличные ссылки - спасибо! – Jamo
я удивляюсь, как вам удалось создать compoennts тег? ;) как и ваш вопрос +1 –
Это была опечатка. Я исправил его ... –
Спасибо - @MasterPeter за улыбку и @Mason Wheeler за исправление. – Jamo