Drawing Shapes (Code)
Go Up to Using Drawing Tools
Drawing shapes is just as easy as drawing lines. Each one takes a single statement; you just need the coordinates.
Here's a rewrite of the OnMouseUp event handler that draws shapes for all four tools:
procedure TForm1.FormMouseUp(Sender: TObject; Button TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case DrawingTool of
dtLine:
begin
Canvas.MoveTo(Origin.X, Origin.Y);
Canvas.LineTo(X, Y)
end;
dtRectangle:
Canvas.Rectangle(Origin.X, Origin.Y, X, Y);
dtEllipse:
Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
dtRoundRect:
Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,
(Origin.Y - Y) div 2);
end;
Drawing := False;
end;
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y) {
switch (DrawingTool) {
case dtLine:
Canvas->MoveTo(Origin.x, Origin.y);
Canvas->LineTo(X, Y);
break;
case dtRectangle:
Canvas->Rectangle(Origin.x, Origin.y, X, Y);
break;
case dtEllipse:
Canvas->Ellipse(Origin.x, Origin.y, X, Y);
break;
case dtRoundRect:
Canvas->Rectangle(Origin.x, Origin.y, X, Y, (Origin.x - X) / 2,
(Origin.y - Y) / 2);
break;
}
Drawing = false;
}
Of course, you also need to update the OnMouseMove handler to draw shapes:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if Drawing then
begin
Canvas.Pen.Mode := pmNotXor;
case DrawingTool of
dtLine:
begin
Canvas.MoveTo(Origin.X, Origin.Y);
Canvas.LineTo(MovePt.X, MovePt.Y);
Canvas.MoveTo(Origin.X, Origin.Y);
Canvas.LineTo(X, Y);
end;
dtRectangle:
begin
Canvas.Rectangle(Origin.X, Origin.Y, MovePt.X, MovePt.Y);
Canvas.Rectangle(Origin.X, Origin.Y, X, Y);
end;
dtEllipse:
begin
Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
end;
dtRoundRect:
begin
Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,
(Origin.Y - Y) div 2);
Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,
(Origin.Y - Y) div 2);
end;
end;
MovePt := Point(X, Y);
end;
Canvas.Pen.Mode := pmCopy;
end;
vvoid __fastcall TForm1::FormMouseMove(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y) {
if (Drawing) {
Canvas->Pen->Mode = pmNotXor; // use XOR mode to draw/erase
switch (DrawingTool) {
case dtLine:
Canvas->MoveTo(Origin.x, Origin.y);
Canvas->LineTo(MovePt.x, MovePt.y);
Canvas->MoveTo(Origin.x, Origin.y);
Canvas->LineTo(X, Y);
break;
case dtRectangle:
Canvas->Rectangle(Origin.x, Origin.y, MovePt.x, MovePt.y);
Canvas->Rectangle(Origin.x, Origin.y, X, Y);
break;
case dtEllipse:
Canvas->Ellipse(Origin.x, Origin.y, MovePt.x, MovePt.y);
Canvas->Ellipse(Origin.x, Origin.y, X, Y);
break;
case dtRoundRect:
Canvas->Rectangle(Origin.x, Origin.y, MovePt.x, MovePt.y,
(Origin.x - MovePt.x) / 2, (Origin.y - MovePt.y) / 2);
Canvas->Rectangle(Origin.x, Origin.y, X, Y, (Origin.x - X) / 2,
(Origin.y - Y) / 2);
break;
}
MovePt = Point(X, Y);
}
Canvas->Pen->Mode = pmCopy;
}
Typically, all the repetitious code that is in the above example would be in a separate routine. The next topic shows all the shape-drawing code in a single routine that all mouse-event handlers can call.