Динамическая Ничья TRect
Я пытаюсь сделать простую вещь. Но я не мог: (
У меня есть TImage, имя которого-обзор. Я хочу нарисовать прямоугольник, который находится на обзоре, но не зависит от обзора. Поэтому я добавил перед обзором временной интервал и нарисовал прямоугольник. Прямоугольник работает, но я просто могу видеть Таймаж или обзор. Я попытался дать прозрачность ректимгу, но ректимг полностью исчез.
with rectImg.Canvas do
begin
Pen.Color:= clRed;
Rectangle(0, 0, rectImg.Width, rectImg.Height);
end;
Я рисую краской то, что хочу сделать.
Что прямая кишка может быть изменяемый размер независимо от img.
Спасибо за совет.
1 ответ:
Если я правильно понял ваш вопрос, вы фактически хотите визуально обрамить изображение, не рисуя рамку на самой оригинальной графике, т. е.
rectImg.Picture
не должны возвращать обрамленную графику. Сразу же приходят на ум два способа:A) дамп
TImage
и использоватьTPaintBox
, вручную поддерживая основную графику и выполняя любое растяжение или что-либо еще с помощью вызовов методов, а не настроек свойств компонента.B) расширить
TImage
, чтобы иметь событиеOnPaint
, которое возникает послеTImage
сделал свою стандартную роспись.Относительно (b), вы можете сделать это либо как класс interposer, либо как пользовательский компонент. Как класс interposer вы можете сделать следующее:
1) повторно объявите
TImage
непосредственно над классом формы:type TPaintEvent = procedure (Sender: TObject; Canvas: TCanvas) of object; TImage = class(Vcl.ExtCtrls.TImage) //use class(ExtCtrls.TImage) if pre-XE2 strict private FOnPaint: TPaintEvent; protected procedure Paint; override; published property OnPaint: TPaintEvent read FOnPaint write FOnPaint; end; TMyForm = class(TForm) //...
2) реализуйте переопределение
Paint
как so (немного неверно, посколькуTImage
переопределяет свойствоCanvas
базового класса):type TGraphicControlAccess = class(TGraphicControl); procedure TImage.Paint; begin inherited; if Assigned(FOnPaint) then FOnPaint(Self, TGraphicControlAccess(Self).Canvas); end;
3) объявить соответствующий обработчик события в классе форма:
procedure rectImgPaint(Sender: TObject; Canvas: TCanvas);
4) реализовать обработчик типа so-Примечание вам нужно установить
Brush.Style
вbsClear
, чтобы не создавать заполненный прямоугольник:5) назначьте обработчик событий в событии формыprocedure TMyForm.rectImgPaint(Sender: TObject; Canvas: TCanvas); begin Canvas.Brush.Style := bsClear; Canvas.Pen.Color := clRed; Canvas.Rectangle(0, 0, rectImg.Width, rectImg.Height); end;
OnCreate
:procedure TMyForm.ImagePaint.FormCreate(Sender: TObject); begin rectImg.OnPaint := rectImgPaint; end;
Я оставляю преобразования промежуточная класс на пользовательский компонент, в качестве упражнения для читателя...
Postscript
Теперь я думаю о двух других мыслях:
- Как ни странно, FMX на самом деле лучше здесь, потому что его
TImage
обеспечивает событиеOnPaint
как стандарт.- если это буквально просто кадр, который вы хотите, бескодовой альтернативой будет наложение
TImage
сTShape
, установив свойство формыBrush.Style
вbsClear
, как мы сделали в решении для кодирования. В этом случае задайте свойству фигурыEnabled
значениеFalse
, если у вас есть какие-либо обработчикиOnClick
илиOnMouseXXX
, назначенные изображению.