簡単なお絵かきソフトを作成してみましょう。ここで作るお絵かきソフトでは、 以下の機能を持つ事になります。
注意すべき点は、描画面上(TPaintBox)で、マウスボタンを押し下げた位置に 始点(ペン先)をもっていき、マウスボタンを離した位置を終点に設定することです。
たとえば、ライン(直線)を引く場合には、マウスボタン押下位置を始点にして、 マウスボタンが離された位置を終点にセットし、始点から終点の位置までラインを 引くようになっています。円や四角を描く場合も同様の操作を行います。
サンプルプログラムは、以下のようになります。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Spin;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
ColorDialog1: TColorDialog;
GroupBox1: TGroupBox;
Button1: TButton;
SpinEdit1: TSpinEdit;
Label1: TLabel;
Button2: TButton;
RadioGroup1: TRadioGroup;
procedure Button1Click(Sender: TObject);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure RadioGroup1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TDrawMode = (dmFreeCurve, dmLine, dmCircle, dmSquare);
var
Drawing: Boolean;
DrawMode: TDrawMode;
OldPos: TPoint;
StartPos: TPoint;
procedure TForm1.Button1Click(Sender: TObject);
begin
PaintBox1.Canvas.Brush.Color := clWhite;
PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
end;
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if not (Button = mbLeft) then exit;
Drawing := true;
PaintBox1.Canvas.MoveTo(X, Y);
StartPos := Point(X, Y);
OldPos := Point(X, Y);
case DrawMode of
dmLine:
begin
PaintBox1.Canvas.MoveTo(X, Y);
PaintBox1.Canvas.LineTo(X, Y); // 視点の塗りつぶし
PaintBox1.Canvas.Pen.Mode := pmNotXor;
end;
dmCircle, dmSquare:
begin
PaintBox1.Canvas.Pen.Mode := pmNotXor;
end
end;
end;
procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if Drawing then
begin
case DrawMode of
dmFreeCurve: PaintBox1.Canvas.LineTo(X, Y);
dmLine:
begin
PaintBox1.Canvas.MoveTo(StartPos.X, StartPos.Y);
PaintBox1.Canvas.LineTo(OldPos.X, OldPos.Y);
PaintBox1.Canvas.MoveTo(StartPos.X, StartPos.Y);
PaintBox1.Canvas.LineTo(X, Y);
end;
dmCircle:
begin
PaintBox1.Canvas.Brush.Style := bsClear;
PaintBox1.Canvas.Ellipse(StartPos.X, StartPos.Y, OldPos.X, OldPos.Y);
PaintBox1.Canvas.Ellipse(StartPos.X, StartPos.Y, X, Y);
end;
dmSquare:
begin
PaintBox1.Canvas.Brush.Style := bsClear;
PaintBox1.Canvas.Rectangle(StartPos.X, StartPos.Y, OldPos.X, OldPos.Y);
PaintBox1.Canvas.Rectangle(StartPos.X, StartPos.Y, X, Y);
end;
end;
OldPos := Point(X, Y);
end;
end;
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Drawing := false;
case DrawMode of
dmLine:
begin
PaintBox1.Canvas.Pen.Mode := pmCopy;
PaintBox1.Canvas.MoveTo(StartPos.X, StartPos.Y);
PaintBox1.Canvas.LineTo(X, Y);
end;
dmCircle:
begin
PaintBox1.Canvas.Pen.Mode := pmCopy;
PaintBox1.Canvas.Ellipse(StartPos.X, StartPos.Y, X, Y);
end;
dmSquare:
begin
PaintBox1.Canvas.Pen.Mode := pmCopy;
PaintBox1.Canvas.Rectangle(StartPos.X, StartPos.Y, X, Y);
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// FormCreate に記述されている全ての設定は、
// オブジェクトインスペクタで設定可能です。
SpinEdit1.MinValue := 1;
SpinEdit1.MaxValue := 9;
SpinEdit1.Value := 1;
Button1.Caption := 'クリア';
Button2.Caption := '色選択';
Label1.Caption := 'ペンの色';
Label1.Font.Color := PaintBox1.Canvas.Pen.Color;
RadioGroup1.Items.Add('自由曲線');
RadioGroup1.Items.Add('直線');
RadioGroup1.Items.Add('円');
RadioGroup1.Items.Add('四角');
RadioGroup1.ItemIndex := 0;
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
PaintBox1.Canvas.Pen.Width := SpinEdit1.Value
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if ColorDialog1.Execute then
begin
PaintBox1.Canvas.Pen.Color := ColorDialog1.Color;
Label1.Font.Color := ColorDialog1.Color;
end;
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
case RadioGroup1.ItemIndex of
0: DrawMode := dmFreeCurve;
1: DrawMode := dmLine;
2: DrawMode := dmCircle;
3: DrawMode := dmSquare;
end;
end;
end.