Динамическая Ничья TRect


Я пытаюсь сделать простую вещь. Но я не мог: (

У меня есть TImage, имя которого-обзор. Я хочу нарисовать прямоугольник, который находится на обзоре, но не зависит от обзора. Поэтому я добавил перед обзором временной интервал и нарисовал прямоугольник. Прямоугольник работает, но я просто могу видеть Таймаж или обзор. Я попытался дать прозрачность ректимгу, но ректимг полностью исчез.

   with rectImg.Canvas do
      begin
        Pen.Color:= clRed;
        Rectangle(0, 0, rectImg.Width, rectImg.Height);
      end;
Я рисую краской то, что хочу сделать. Введите описание изображения здесь

Что прямая кишка может быть изменяемый размер независимо от img.

Спасибо за совет.

1 2

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, чтобы не создавать заполненный прямоугольник:

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;
5) назначьте обработчик событий в событии формы 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, назначенные изображению.