[ главная ]   [ рейтинг статей ]   [ справочник радиолюбителя ]   [ новости мира ИТ ]



Ответов: 0
25-02-12 07:01







   Web - программирование
PHP


ASP






XML



CSS

SSI





   Программирование под ОС











   Web - технологии








   Базы Данных









   Графика






Данные




Программирование под ОС / Pascal - Delphi /

Основы создания графического редактора типа Paint в Delphi

Ключевые вопросы этой статьи:
1. Что использовать для редактора?
2. Какими инструментами пользоваться?
3. Какие приемы используются?

Сделаем редактор с 5 инструментами, которые показывают основные технологии: карандаш, прямоугольник, эллипс, ломаная, заливка.

Начнем.

Фаза 1: Проектируем форму

   Основным элементом на форме будет, конечно же, картинка. Есть несколько вариантов компонентов для нее. Это Image, PaintBox и другие со свойством Canvas.
   Остановим свой выбор на PaintBox"е.
   Так же нужно не забывать, что картинка может быть больше, чем размеры формы. Для решения этой проблемы, используем ScrollBox.
   Для панели инструментов выберем нижнюю часть окна - установим Panel.
   Кнопки на панели - SpeedButton.

Итак:
1. Устанавливаем Panel, свойства Align=alBottom, Height=65.
2. На панель ставим 5 штук SpeedButton. У всех свойство GroupIndex=1 или другому числу. Главное, чтоб было одинаково. Одной из кнопок назначим Down=True
3. 2 штуки ColorBox на панель инструментов, в свойстве Style - cbPrettyNames=True. Второму присвоим Selected=clWhite.
4. Подпишем их "Цвет" и "Фон" соответственно с помощью Label.
5. Устанавливаем на форму ScrollBox, ставим у него свойство Align=alClient.
6. Внутрь ScrollBox ставим PaintBox. Ставим свойства Top=0 и Left=0, Align=alNone.
7. Также сделаем меню. Поставим MainMenu, сделаем в нем 1 меню - "Файл" с пунктами: Открыть, Сохранить, Выход.

Вот то, что вышло у меня после этих действий:
 

Окно программы в режиме конструктора

Окно программы в режиме конструктора
 


Фаза 2: Программирование

   Форму мы спроектировали. Теперь можно начать писать непосредственно программу.
   Рисовать мы будем не на холсте PaintBox"a, как можно подумать сначала, а в памяти. На холст будем выводить лишь результат работы.

Для этого объявим глобальные переменные:

img, buffer: TBitmap;
x0,y0: integer;

   Также объявим переменную 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;


   В событии OnMouseDown PaintBox"a проверяем, нажата ли левая кнопка. Если да, то устанавливаем значение nowdrawing"a в нужное, а также сохраняем текущую картинку и начальные координаты мыши. Если это заливка, то нам не нужно учитывать движение мыши, нам достаточно одного нажатия. Поэтому, если заливка, то снимаем флаг dwn, чтоб не реагировать на движения.

   Если мы рисуем ломаную линию, то реагировать нужно и на правую кнопку: для создания нового узла. Т.е. для рисования ломанной нужно держать левую кнопку нажатой, а для создания узлов кликать правую кнопку.

Если нажата не левая кнопка, то начальные координаты просто переписываем (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));
 


   В событии OnMouseMove самое интересное: если флаг dwn не включен, то выходим сразу же из процедуры.
   Восстанавливаем старый холст и по выбору рисуемой фигуры в nowdrawing соответственно рисуем линию, прямоугольник, эллипс или отрезок - часть ломаной на картинке img. В конце рисования, переносим его на холст PaintBox"a.
 

 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));


В событии OnMouseUp:
 

 if button=mbLeft then dwn:=false;
 buffer.Assign(img);


   И, в заключение, в событии OnPaint PaintBox"a напишем прорисовку картинки из буфера:
 

 paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),
                 buffer.Canvas,bounds(0,0,img.Width,img.Height));
 


   Вот и все! У нас есть костяк редактора. Можно легко добавлять новые функции, модифицировать старые.




Комментарии

Gulka...
11-12-2010   
А кто разработчик этой программы???

 Ваш комментарий к данному материалу будет интересен нам и нашим читателям!



Последние статьи: Программирование под ОС / Pascal - Delphi /

Работа со шрифтами на Win API
06-06-2010   

Сегодня поговорим о шрифтах, и о том, каким образом работать с ними на Win API. Нам потребуется переменная типа HFONT. Изменить стиль шрифта можно у любого компонента, я покажу это на примере кнопки... подробнее

Кол. просмотров: общее - 3808 сегодня - 0

Работа с таймером на Win API
06-06-2010   

Таймер - вещь в хозяйстве очень полезная. Если некое действие нужно повторять с определенной периодичностью, то таймер, это как раз то, что нужно... подробнее

Кол. просмотров: общее - 3801 сегодня - 0

Работа с мультимедийным таймером на Win API
06-06-2010   

Мы уже знакомы с системным таймером, сегодня познакомимся с мультимедийным, основное отличие которого, более высокая скорость (точность) работы... подробнее

Кол. просмотров: общее - 3920 сегодня - 2

Создание CheckBoxов средствами Win API
06-06-2010   

Сегодня наша программа научится работать с CheckBoxами. CheckBox можно представить как флаг, который можно установить или сбросить, и в зависимости от его состояния выполнять определенные действия... подробнее

Кол. просмотров: общее - 4062 сегодня - 0

Создание группы RadioButton средствами Win API
06-06-2010   

В прошлый раз мы сделали несколько радио-кнопок, которые автоматически объединялись в одну группу. Сейчас рассмотрим, как создавать несколько независимых групп радио-кнопок... подробнее

Кол. просмотров: общее - 3849 сегодня - 0



  WWW.COMPROG.RU - 2009-2012 | Designed and Powered by Zaipov Renat | Projects