Delphi-用鼠标绘制一个矩形

Delphi-用鼠标绘制一个矩形,delphi,Delphi,我正在创建一个窗口,用户可以用鼠标在滚动框上绘制形状。首先,我尝试画一个简单的矩形,当鼠标移动时,它消失 以下是我的代码的最低版本: procedure TXXX.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (Button = mbLeft) and MyCondition then begin FStartPlace.X := X; FStartPlace.Y :

我正在创建一个窗口,用户可以用鼠标在滚动框上绘制形状。首先,我尝试画一个简单的矩形,当鼠标移动时,它消失

以下是我的代码的最低版本:

procedure TXXX.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin 
  if (Button = mbLeft) and MyCondition then begin
    FStartPlace.X := X;
    FStartPlace.Y := Y;
    FEndPlace.X := X;
    FEndPlace.Y := Y;
    FCapturing := True;
  end;
end;

procedure TXXX.MouseMove(Shift: TShiftState; X, Y: Integer);
begin   
  if MyCondition and FCapturing then begin
    Canvas.Rectangle(FStartPlace.X, FStartPlace.Y, FEndPlace.X, FEndPlace.Y);
    FEndPlace.X := X;
    FEndPlace.Y := Y;
    Canvas.Rectangle(FStartPlace.X, FStartPlace.Y, FEndPlace.X, FEndPlace.Y);
  end;
end;    

procedure TXXX.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if MyCondition then begin
    FCapturing := False;
    //Canvas.Rectangle(FStartPlace.X, FStartPlace.Y, FEndPlace.X, FEndPlace.Y); // Draw a rectangle on the previous one to make it disapear ?
  end;
end;
问题是,当我在上一个矩形上绘制时,我无法“擦除/删除”它。第二个问题是如何在MouseUp过程中消除它

我很确定我必须使用“Xor”,但我不明白它是如何工作的。我试图实现
Canvas.Pen.Mode:=pmXor但是没有成功。你有什么建议吗

多谢各位

[更新] 在绘制过程中,我在内存中绘制了一个“点网格”,以便它不会引起闪烁

procedure TXXX.Paint();
var
  X, Y: Integer;
  Buffer: TBitmap;
begin
  Buffer := TBitmap.Create;
  try
    Buffer.Width := Width;
    Buffer.Height := Height;   
    X := 0;
    Y := Height;
    while X <= Buffer.Width do begin
      while Y >= 0 do begin
        Buffer.Canvas.Pixels[X, Y]:= clBlack;
        Y := Y - FStep;
      end;
      X := X + FStep;
      Y := Height;
    end;

    Canvas.Draw(0, 0, Buffer);
  finally
    Buffer.free
  end;

  if FCapturing then
    Canvas.Rectangle(FStartPlace.X, FStartPlace.Y, FEndPlace.X, FEndPlace.Y);
end;
程序txx.Paint();
变量
十、 Y:整数;
缓冲区:TBitmap;
开始
缓冲区:=TBitmap.Create;
尝试
缓冲区宽度:=宽度;
缓冲区高度:=高度;
X:=0;
Y:=高度;
当X=0时,开始
Buffer.Canvas.Pixels[X,Y]:=clBlack;
Y:=Y-FStep;
结束;
X:=X+FStep;
Y:=高度;
结束;
画布绘制(0,0,缓冲区);
最后
无缓冲区
结束;
如果是FCapturing那么
Canvas.Rectangle(FStartPlace.X,FStartPlace.Y,FEndPlace.X,FEndPlace.Y);
结束;

不要使用
Paint()
方法从外部在
画布上绘制。您已经在保存图形坐标,只需将
Canvas
调用替换为
Invalidate()
,然后在调用
Paint()
方法时仅执行最新的图形

procedure txx.MouseDown(按钮:TMouseButton;移位:tshift状态;X,Y:整数);
开始
如果(按钮=mbLeft)和MyCondition,则开始
FStartPlace.X:=X;
FStartPlace.Y:=Y;
FEndPlace.X:=X;
Y:=Y;
FCapturing:=真;
使无效
结束;
结束;
程序txx.MouseMove(移位:tshift状态;X,Y:整数);
开始
如果是FCapturing,则开始
FEndPlace.X:=X;
Y:=Y;
使无效
结束;
结束;
程序TXXX.MouseUp(按钮:TMouseButton;移位:tShift状态;X,Y:整数);
开始
如果是FCapturing,则开始
FCapturing:=假;
使无效
结束;
结束;
程序TXXX.油漆;
开始
如果是FCapturing那么
Canvas.Rectangle(FStartPlace.X,FStartPlace.Y,FEndPlace.X,FEndPlace.Y);
结束;

非常感谢您的快速回答!那几乎是完美的。因为我的“点网格”每次都在画画,所以只是在闪烁。是否可能只绘制控件的一个区域?所示代码中没有绘制“点网格”。请将您的问题更新为。抱歉,不准确。我已经用画法更新了我的帖子,展示了我如何构建“点网格”(如屏幕截图所示)。是什么阻止了你简单地将矩形绘制到网格顶部的
TBitmap
?另一方面,为什么要在每幅绘画上创建
TBitmap
,而不是缓存和重用它?除非组件的大小发生变化(或者在其顶部添加矩形),否则其内容不会发生变化。