动态TRect绘制

Dynamic TRect Draw

我正在尝试简单的事情。但我不能:(

我有一个TImage,名字是overview。 我想绘制一个矩形,它在概览上但独立于概览。所以我在概述的前面添加了一个 TImage 并绘制了一个矩形。矩形有效,但我只能看到 TImage 或概览。我试图给 rectImg 一个透明度,但 rectImg 完全消失了。

   with rectImg.Canvas do
      begin
        Pen.Color:= clRed;
        Rectangle(0, 0, rectImg.Width, rectImg.Height);
      end;

我在颜料上画画,我想画什么。

该矩形可以独立于 img 调整大小。

谢谢指教。

如果我对您的问题的理解正确,您实际上是想在视觉上给图像加框,而不是在原始图形本身上画框,即 rectImg.Picture 不应该 return 带框的图形。立即想到两种方法:

a) 转储 TImage 并使用 TPaintBox,手动维护核心图形并通过方法调用而不是组件上的 属性 设置进行任何拉伸或其他操作。

b) 扩展 TImage 以在 TImage 完成其标准绘画后引发 OnPaint 事件。

关于 (b),您可以将其作为插入器 class 或自定义组件来完成。作为中介 class 你可以这样做:

1) 在您的表格 class:

正上方重新声明 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 重写(由于 TImage 重新定义了基数 class 的 Canvas 属性,所以有点笨拙):

type
  TGraphicControlAccess = class(TGraphicControl);

procedure TImage.Paint;
begin
  inherited;
  if Assigned(FOnPaint) then
    FOnPaint(Self, TGraphicControlAccess(Self).Canvas);
end;

3) 以 class:

的形式声明合适的事件处理程序
procedure rectImgPaint(Sender: TObject; Canvas: TCanvas);

4) 像这样实现处理程序 - 注意您需要将 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;

我将插入器 class 转换为自定义组件作为 reader...

的练习

后记

现在我想到了另外两个想法:

  • 奇怪的是,FMX 实际上在这里更好,因为它 TImage 提供了一个 OnPaint 事件作为标准。
  • 如果它实际上只是您想要的框架,无代码替代方案是用 TShape 覆盖 TImage,将形状的 Brush.Style 属性 设置为bsClear 就像我们在编码解决方案中所做的那样。在这种情况下,如果您为图像分配了任何 OnClickOnMouseXXX 处理程序,请将形状的 Enabled 属性 设置为 False