簡単なお絵かきソフトを作成してみましょう。ここで作るお絵かきソフトでは、 以下の機能を持つ事になります。
注意すべき点は、描画面上(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.