Основы создания графического редактора типа Paint в DelphiИсточник: delphisources Роман Радер
Ключевые вопросы этой статьи: Сделаем редактор с 5 инструментами, которые показывают основные технологии: карандаш, прямоугольник, эллипс, ломаная, заливка. Начнем. Фаза 1: Проектируем форму Основным элементом на форме будет, конечно же, картинка. Есть несколько вариантов компонентов для нее. Это Image, PaintBox и другие со свойством Canvas. Итак: Вот то, что вышло у меня после этих действий:
Окно программы в режиме конструктора
Форму мы спроектировали. Теперь можно начать писать непосредственно программу. Для этого объявим глобальные переменные: img, buffer: TBitmap; Также объявим переменную dwn: boolean, которая будет говорить нажата левая кнопка или нет (рисовать или нет). Объявим тип TShape = (sPen, sRect, sEllipse, sPoly, sFill). И глобальную переменную nowdrawing: TShape. В ней будет хранится тип фигуры, которую мы рисуем. В событии формы OnCreate напишем: Img:=TBitmap.Create; buffer:=TBitmap.Create; img.Width:=PaintBox1.ClientWidth; buffer.Width:=PaintBox1.ClientWidth; img.Height:=PaintBox1.ClientHeight; buffer.Height:=PaintBox1.ClientHeight; nowdrawing:=sPen; dwn:=false;
Если мы рисуем ломаную линию, то реагировать нужно и на правую кнопку: для создания нового узла. Т.е. для рисования ломанной нужно держать левую кнопку нажатой, а для создания узлов кликать правую кнопку. Если нажата не левая кнопка, то начальные координаты просто переписываем (x0,y0). if button=mbLeft then begin img.assign(buffer); x0:=x; y0:=y; if SpeedButton1.Down then begin nowdrawing:=sPen; img.canvas.MoveTo(x,y); end else if SpeedButton2.Down then nowdrawing:=sEllipse else if SpeedButton3.Down then nowdrawing:=sRect else if SpeedButton4.Down then nowdrawing:=sPoly else if SpeedButton5.Down then nowdrawing:=sFill; dwn:=true; img.Canvas.Pen.Color:=ColorBox1.Selected; img.Canvas.Brush.Color:=ColorBox2.Selected; if nowdrawing=sFill then begin img.Canvas.FloodFill(x0,y0,img.Canvas.Pixels[x,y],fsSurface); buffer.Assign(img); dwn:=false; end end else begin if (dwn)and(nowdrawing=sPoly) then begin x0:=x; y0:=y; buffer.Assign(img); end; end; paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height), img.Canvas,bounds(0,0,img.Width,img.Height));
if not dwn then exit; img.assign(buffer); case nowdrawing of sPen:begin img.Canvas.LineTo(x,y); buffer.Assign(img); end; sRect:begin img.Canvas.Rectangle(x0,y0,x,y); end; sEllipse:begin img.Canvas.Ellipse(x0,y0,x,y); end; sPoly:begin img.Canvas.MoveTo(x0,y0); img.Canvas.LineTo(x,y); end; sFill:begin //nothing. end; end; paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height), img.Canvas,bounds(0,0,img.Width,img.Height));
if button=mbLeft then dwn:=false; buffer.Assign(img);
paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height), buffer.Canvas,bounds(0,0,img.Width,img.Height));
|