【问题标题】:Rectangle drawn always is erased when the next is created绘制的矩形总是在创建下一个时被擦除
【发布时间】:2019-10-10 19:46:54
【问题描述】:

在下面的代码中,我希望在绘制下一个矩形时不擦除先前绘制的矩形。如何做到这一点?

type
  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
    FSelecting: Boolean;
    FSelection: TRect;
    pos1, pos2, pos3, pos4: Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FSelection.Left := X;
  FSelection.Top := Y;
  FSelecting := true;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if FSelecting then
  begin
    FSelection.Right := X;
    FSelection.Bottom := Y;
    Invalidate;
  end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FSelecting := false;
  FSelection.Right := X;
  FSelection.Bottom := Y;
  Invalidate;

  FSelection.NormalizeRect;
  if FSelection.IsEmpty then

  else
  begin
    pos1 := FSelection.Left;
    pos2 := FSelection.Top;
    pos3 := X;
    pos4 := Y;

  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.Brush.Style := bsClear;
  Canvas.Pen.Style := psSolid;
  Canvas.Pen.Color := clRed;
  Canvas.Rectangle(FSelection);
end;

【问题讨论】:

  • 记住集合中的每个矩形,并在要求您绘画时将它们全部绘制出来。系统不记得历史绘画。您的工作是在每次要求您绘画时绘制整个表面。
  • Paint 总是从无到有。如果要绘制多个矩形,则需要存储该信息-TList<TRect> 不是一个坏选择。然后在FormPaint 中枚举列表并绘制每个矩形。当不再需要矩形时,您还需要管理从列表中删除它们。

标签: delphi canvas draw delphi-10.3-rio


【解决方案1】:

当表单的客户区无效时,整个表面都被标记为重绘。下次调用OnPaint 时,绘制的是事件处理程序中的内容。你画了一个矩形,然后你就看到了。

您需要积累与您需要绘制的矩形相关的信息。然后在绘制处理程序中,您可以参考这些信息并将它们全部绘制出来。

以下示例是问题中代码的略微修改版本。它用TQueue 的矩形代替未使用的整数变量(pos1、pos2..)。一个矩形被排队,当鼠标按钮被释放时,任何多余的矩形都会被出列。召回矩形的最大数量由一个常数定义。绘制处理程序枚举队列以绘制矩形。

uses
  ..., generics.collections;

type
  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FSelecting: Boolean;
    FSelection: TRect;
    FRectangles: TQueue<TRect>;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  MAXRECTANGLECOUNT = 2;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FRectangles := TQueue<TRect>.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FRectangles.Free;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FSelection.Left := X;
  FSelection.Top := Y;
  FSelecting := true;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if FSelecting then
  begin
    FSelection.Right := X;
    FSelection.Bottom := Y;
    Invalidate;
  end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FSelecting := false;
  FSelection.Right := X;
  FSelection.Bottom := Y;
  Invalidate;

  FSelection.NormalizeRect;
  if not FSelection.IsEmpty then
  begin
    FRectangles.Enqueue(FSelection);
    if FRectangles.Count > MAXRECTANGLECOUNT then
      FRectangles.Dequeue;
  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  R: TRect;
begin
  Canvas.Brush.Style := bsClear;
  Canvas.Pen.Style := psSolid;
  Canvas.Pen.Color := clRed;
  Canvas.Rectangle(FSelection);

  for R in FRectangles do
    Canvas.Rectangle(R);
end;

end.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-28
    • 2016-09-14
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多