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