Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
События мыши ⇐ ПредыдущаяСтр 10 из 10
Во все события, связанные с мышью, передаются также координаты курсора X и Y. Эти параметры определяют координаты курсора в клиентской области компонента. Благодаря этому можно обеспечить различную реакцию в зависимости от того, в какой части клиентской области расположен курсор. Ход работы 1. Создадим новое приложение и сохраним его в своей папке. 2. Разместим на форме 4 компонента Button и зададим им соответствующие названия. Далее разместим на форме компонент ScrollBox (вкладка Additional). Выделив этот компонент, разместим на нем компонент Image. В свойстве Align этого компонента выберем alClient
Разместим на форме также два невизуальных компонента – OpenPictureDialog и SavePictureDialog. В этих компонентах свойство Filter уже содержит фильтры для некоторых типов графических файлов. Все эти фильтры, кроме фильтра для bmp-файлов, надо удалить. В свойстве DefaultExt обоих компонентов введем bmp. 3. Создадим еще одну форму и разместим на ней компоненты Button, Label и SpinEdit следующим образом:
Для компонентов SpinEdit здадим следующие свойства: SpinEdit1: MinValue = 10, MaxValue = 800, Increment = 10 SpinEdit2: MinValue = 10, MaxValue = 600, Increment = 10 Первый из них будет определять ширину нового изображения в пикселях, второй – высоту. Для кнопок определим следующие свойства: Button1: ModalResult=mrOK, Default = True. Button2: ModalResult=mrCancel, Cancel = True. 4. Вернемся к первой форме. Создадим обработчик OnClick для кнопки New: with form2 do //устанавливаем значения счетчиков на второй форме равными текущим значениям ширины и высоты компонента Image begin spinedit1.Value:=image1.Width; spinedit2.Value:=image1.Height; end; if form2.ShowModal=mrOK then //если на 2-й форме нажата кнопка ОК with image1 do begin picture:=nil; //очистка прежнего изображения и создание нового с нужными размерами picture.Bitmap.Width:=form2.SpinEdit1.Value; picture.Bitmap.Height:=form2.SpinEdit2.Value; canvas.FillRect(canvas.ClipRect); //заливка созданного изображения цветом фона savepicturedialog1.FileName:=''; form1.Caption:='Image editor'; end; 5. Создадим обработчик OnClick для кнопки Open: with openpicturedialog1 do if execute then begin image1.Picture.LoadFromFile(filename); savepicturedialog1.FileName:=filename; form1.Caption:='Image Editor - '+Filename; //к заголовку окна добавляется название файла filename:=''; end; 6. Аналогичным образом создаем обработчик для кнопки Save: with savepicturedialog1 do if execute then begin image1.Picture.SaveToFile(filename); form1.Caption:='Image Editor -'+ filename; end; 7. Для копки Clear создадим следующий обработчик: with image1.Canvas do fillrect(cliprect); 8. Создадим обработчик события OnCreate для формы: image1.Parent.DoubleBuffered:=true; with image1 do begin picture.Bitmap.Width:=scrollbox1.Width; picture.Bitmap.Height:=scrollbox1.Height; canvas.FillRect(canvas.ClipRect); end; Если первая строка приведенного выше кода будет отсутствовать, при рисовании на компоненте Image изображение будет мерцать. Остальные строки необходимы, чтобы при запуске программы в редакторе присутствовало изображение. 9. Следующим шагом будет реализация возможности рисования линии черного цвета толщиной 1 пиксел. Рисование будет возможным как на созданных, так и на загруженных изображениях. Для Image1 в обработчике OnMouseDown напишем: image1.Canvas.MoveTo(x,y); //точка с координатами X,Y становится текущей точкой канвы. Обработчик OnMouseMove Image1: if ssleft in shift then //если нажата левая клавиша мышки image1.Canvas.LineTo(x,y); //рисуется линия от текущей точки до точки с координатами X,Y и эта точка становится следующей текущей 10. Приступим к следующему этапу. Добавим редактору следующие функции: возможность рисования прямых линий, изменения толщины контура, а также возможность выбора цвета фона и контура. Разместим на форме дополнительные компоненты: GroupBox1 (Capture = ‘Mode’), внутри которого размещены две кнопки: SpeedButton1 (Capture=’Brush’, GroupIndex=1, Down=True) – кнопка для рисования в режиме «free hand» SpeedButton2 (Capture =’Ruler’GroupIndex=1, Tag=1) - кнопка для рисования в режиме «прямой линии» ColorGrid1 (свойство GridOrdering=go16x1 – ячейки расположены в один ряд) SpiEdit1 (MaxValue=22, MinValue=1, Value=1, Increment=3). Label1 (Capture=’Width’) В свойстве Tag будет хранится номер режима рисования.
11. Напишем следующие обработчики: OnChange для ColorGrid1: image1.Canvas.Pen.Color:=colorgrid1.ForegroundColor; //цвет контура image1.Canvas.Brush.Color:=colorgrid1.BackgroundColor; //цвет фона OnChange для SpiEdit1: image1.Canvas.Pen.Width:=spinedit1.Value;// задаем толщину линии 12. Теперь обеспечим возможность рисования во втором режиме – прямые линии. OnClick для SpeedButton1: image1.Tag:=(sender as tspeedbutton).Tag; (sender as Tspeedbutton).Down:=true; Для события OnClick SpeedButton2 выберем из списка SpeedButton1Click Опишем глобальные переменные: startPoint,MovePoint:tpoint; А в секции Implementation (сразу после {$R *.dfm}) опишите следующую процедуру: procedure drawfigure(p1,p2:tpoint; amode:TPenMode); begin with form1.Image1.Canvas do begin pen.Mode:=Amode; MoveTo(p1.X,p1.Y); lineto(p2.X,p2.Y); end; end; 13. Создадим следующие обработчики: Image1 OnMouseUp: if startpoint.X=10000 then exit; if (image1.Tag=1) or (image1.Tag=2) //это условие нам пригодится в будущем для рисования фигур then drawfigure(startpoint,point(x,y),pmCopy); Отредактируем метод Image1MouseMove следующим образом: if ssleft in shift then case image1.Tag of 0: image1.Canvas.LineTo(x,y); 1: begin drawfigure(startpoint,movepoint,pmNotXor); MovePoint:=Point(x,y); DrawFigure(StartPoint,MovePoint,pmNotXor); end; end; В метод Image1MouseDown добавьте: startpoint:=point(x,y); movePoint:=StartPoint; Теперь рисование можно производить в двух режимах: в режиме «Brush» рисуются линии произвольной формы, а в новом режиме «Ruler» рисуются прямые линии. 14. Усложним на редактор. Добавим еще один инструмент – Рисование фигур Добавим в GroupBox1 еще одну кнопку SpeedButton3 (Caption = ‘Figure’). Параметры кнопки – GroupIndex=1, Tag=2 Разместим также в левом нижнем углу формы панель (Panel1) и поместим на нее компонент Shape1. Установите значения Width и Height для Shape1 на 4 пикселя меньше, чем соответствующие значения компонента Panel1. Разместите компонент Shape1 по центру панели. Компонент Shape1 позволяет определить, как будет выглядеть нарисованная фигура. В других режимах рисования данный компонент позволяет визуально оценить текущие цвет и толщину линии. При щелчке левой клавиши мышки на компоненте-образце Shape1 изменяется тип фигуры (прямоугольник, прямоугольник с закругленными углами, эллипс) и происходит автоматический переход в режим «Figure». Щелчок правой клавиши по компоненту позволяет перейти в режим рисования фигур с равными измерениями (квадраты и т.п.).
15. Объявим еще две глобальные переменные: dx,dy:integer; В раздел uses для Unit1 необходимо добавить модуль математических функций Math Измените уже описанную нами процедуру DrawFigure следующим образом (добавить выделенные жирным строки): with form1.Image1.Canvas do begin pen.Mode:=Amode; case form1.Image1.tag of 1: begin MoveTo(p1.X,p1.Y); lineto(p2.X,p2.Y); end; 2: begin dx:=p2.X-p1.X; dy:=p2.Y-p1.Y; if abs(dx)>abs(dy) then dx:=abs(dy)*sign(dx) else dy:=abs(dx)*sign(dy); case form1.shape1.Shape of stRectangle:Rectangle(p1.X,p1.Y,p2.X,p2.Y); stRoundRect:RoundRect(p1.X,p1.Y,p2.X,p2.Y,(p2.Y-p1.X) div 2,(p2.Y-p1.Y) div 2); stEllipse: Ellipse(p1.X,p1.Y,p2.X,p2.Y); stSquare:rectangle(p1.X,p1.Y,p1.X+dx,p1.Y+dy); stRoundSquare:RoundRect(p1.X,p1.Y,p1.X+dx,p1.Y+dy,dx div 2, dy div 2); stCircle:Ellipse(p1.X,p1.Y,p1.X+dx,p1.Y+dy); end; end; end; end; В методе Image1MouseMove замените строку 1:begin на1,2:begin В метод ColorGrid1Change добавьте: shape1.Brush.Color:=colorgrid1.BackgroundColor; shape1.Pen.Color:=ColorGrid1.ForegroundColor; В метод SpinEdit1Change добавьте: shape1.Pen.Width:=spinedit1.Value; 16. Создадим обработчик OnMouseDown для Shape1: procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var i:integer; begin if ssLeft in Shift then i:=(ord(shape1.Shape)+2) mod 6 else if odd(ord(Shape1.Shape)) then i:=ord(shape1.Shape)-1 else i:=ord(shape1.Shape)+1; shape1.Shape:=tshapetype(i); speedbutton3.Down:=true; image1.Tag:=2; end; 17. Реализуем функцию отмены предыдущей операции. Для этого объявим глобальную переменную oldbitmap:tbitmap; Отредактируйте метод FormCreate следующим образом: image1.Parent.DoubleBuffered:=true; oldbitmap:=tbitmap.Create; with image1 do begin picture.Bitmap.Width:=scrollbox1.Width; picture.Bitmap.Height:=scrollbox1.Height; canvas.FillRect(canvas.ClipRect); oldbitmap.Width:=picture.Bitmap.Width; oldbitmap.Height:=picture.Bitmap.Height; end; end; Создадим обработчик OnDestroy для Form1: oldbitmap.Free; Установим свойству KeyPreview формы значение true и напишем обработчик OnKeyPress для формы: if key=#27 then with image1.Canvas do copyrect(cliprect,oldbitmap.Canvas,cliprect); Теперь любую графическую операцию можно отменить сразу после ее выполнения, нажав клавишу Esc. 18. Добавим нашему редактору еще несколько функциональных возможностей. Реализуем возможность использования дополнительных цветов. Разместим на форме компоненты StaticText1 (Caption=’FG’), StaticText2 (Caption=’BG’) (панель Additional) и ColorDialog1. Для компонентов StaticText1 и StaticText2 зададим следующие свойства: Alignment=taCenter; AutoSize=False; BorderStyle=sbsSunken; Font.Color = cllnactiveCaption. В секцию imlementation добавьте следующую процедуру: procedure NewColor (sender:TObject; Acolor:TColor); begin with Form1 do begin if sender = StaticText1 then Colorgrid1.ForegroundIndex:=-1 else Colorgrid1.BackgroundIndex:=-1; // скрытие подписей FG и BG на компоненте ColorGrid1 (sender as TStaticText).Color:=AColor; (sender as TStaticText).Font.Color:=AColor xor $FFFFFF; //цвет текста на компонентах StaticText будет инверсным к фону компонента ColorGrid1Change(Sender); end; end; 19. Напишем обработчик OnMouseDown для StaticText1: with ColorDialog1 do begin if Sender=StaticText1 then Color:=Shape1.Pen.Color else Color:=Shape1.Brush.Color; if execute then //вызов диалогового окна ColorDialog1, если оно было закрыто кнопкой «ОК», Execute=true NewColor(sender,color); end; Для OnMouseDown StaticText2 выберем StaticText1MouseDown Обработчик OnChange для Colorgrid1 изменим следующим образом: with colorgrid1 do begin if ForegroundIndex <>-1 then begin shape1.Pen.Color:=ForegroundColor; StaticText1.Color:=clBtnFace; StaticText1.Font.Color:=clInactiveCaption; end else shape1.Pen.Color:=StaticText1.Color; image1.Canvas.Pen.Color:=shape1.Pen.Color; if BackGroundIndex<>-1 then begin StaticText2.Color:=clBtnFace; StaticText2.Font.Color:=clInactiveCaption; end; if BackGroundIndex<>-1 then Shape1.Brush.Color:=BackgroundColor else shape1.Brush.Color:=StaticText2.Color; image1.Canvas.Brush.Color:=shape1.Brush.Color; end; Для выбора цвета линии или цвета фона, не входящего в палитру ColorGrid1, нужно щелкнуть мышкой по компонентам StaticText1 или StaticText2 соответственно, в появившемся диалоговом окне «Цвет» указать новый цвет и нажать ОК. При этом компонент StaticText окрасится в соответствующий текст, а метка «FG»(«BG») из палитры ColorGrid1 исчезнет. 20. Реализуем задание цветов при помощи «пипетки». Внесем изменения в обработчик OnMouseDown для Image1: with image1.Canvas do begin oldbitmap.Canvas.CopyRect(cliprect,image1.Canvas,cliprect); if ssAlt in Shift then case Button of mbLeft:NewColor(Statictext1,Pixels[x,y]); mbRight:NewColor(StaticText2,Pixels[x,y]); end; end; image1.Canvas.MoveTo(x,y); startpoint:=point(x,y); movePoint:=StartPoint; Теперь новый цвет линии и фона можно получить непосредственно из изображения, щелкнув соответственной левой или правой клавишей мышки в нужном месте при нажатой клавише Alt. 21. Разместим на форме дополнительные компоненты.
Компоненты SpeedButton4 (Cuption=’Roller’, GroupIndex=1, Tag=3), SpeedButton5 (Cuption=’Text’, GroupIndex=1, Tag=4), Label2 (Caption=’Text’), Label3 (Caption=’Style’), Button5 (Caption=’Font’), Edit1 (Text=’’), FontDialog1 (Options.fdEffects=false – отключение возможности настройки цвета шрифта, а также выбора режима подчеркивания и перечеркивания текста), ComboBox1 и ComboBox2 (Style=csOwnerDeawFixed, Text=’’, ItemIndex=0). Для кнопок SpeedButton событие OnClick определите как SpeedButton1Click. 22. Четвертым режимом рисования будет «Валик» (Roller). Этот режим позволяет заливать текущим цветом фона области, ограниченные линиями других цветов. Заливка производится при щелчке мышью внутри нужной области. Внесем изменение в метод Image1MouseDown: if ssAlt in Shift then case Button of mbLeft:NewColor(Statictext1,Pixels[x,y]); mbRight:NewColor(StaticText2,Pixels[x,y]); end else if image1.Tag=3 then FloodFill(x,y,pixels[x,y],fsSurface) 23. Пятый режим – добавление в рисунок текста. В метод Image1MouseDown добавим: if image1.Tag=3 then FloodFill(x,y,pixels[x,y],fsSurface) else if image1.tag=4 then TextOut(x,y,edit1.Text); Создадим обработчик OnEnter для Edit1: SpeedButton5.Down:=true; Image1.Tag:=4; В метод ColorGrid1Change добавьте операторы: image1.Canvas.Pen.Color:=shape1.Pen.Color; image1.Canvas.Font.Color:=shape1.Pen.Color; Новый режим позволяет помещать на изображение текст, содержащийся в поле ввода Edit1. Текст вставляется при нажатии левой кнопки мыши, место нажатия определяет начальную позицию текста. Цвет текста совпадает с текущим фоном. 24. Нажатие кнопки Font позволяет изменить шрифт вставляемой надписи. Для кнопки Button5 напишем обработчик OnClick with FontDialog1 do begin font:=Image1.Canvas.Font; if execute then image1.Canvas.Font:=font; end; 25. Занесем в свойство Items ComboBox1 6 строк, содержащих числа 0,1,2,3,4,5. В компонент ComboBox2 занесем 8 строк (0,1,2,3,4,5,6,7). Опишем OnDrawItem для ComboBox1: with comboBox1.Canvas,Rect do begin brush.Color:=clWhite; Pen.Color:=clBlack; Pen.Style:=TPenStyle(StrToInt(Combobox1.Items[index])); MoveTo(Left,(top+Bottom) div 2); LineTo(Right,(top+Bottom) div 2); end; Создадим для ComboBox1 обработчик OnChange: with ComboBox1, Shape1.pen do begin Style:=TPenStyle(StrToInt(Items[ItemIndex])); Image1.Canvas.Pen.Style:=Style; ColorGrid1Change(Sender); end; Аналогично поступим с ComboBox2: OnDrawItem для ComboBox2: with ComboBox2.Canvas do begin Brush.Color:=clGray; Brush.Style:=TBrushStyle(StrToInt(ComboBox2.Items[Index])); FillRect(Rect); end; ComboBox1 событие OnChange: with ComboBox2, Shape1.Brush do begin Style:=TBrushStyle(StrToInt(Items[ItemIndex])); Image1.Canvas.Brush.Style:=Style; Button4.Enabled:=Style<> bsClear; ColorGrid1Change(Sender); end; В результате мы получим два выпадающих списка, которые позволяют выбрать все возможные стили рисования линии и заливки фона. Варианты стилей отображаются в выпадающих списках в графическом виде. Результатом выполнения данной лабораторной работы являются созданный согласно заданию программный продукт. Выполненное задание должно быть предъявлено преподавателю в электронном виде. В ходе защиты лабораторной работы студент должен продемонстрировать свои навыки работы с изученными компонентами и методами проектирования интерфейса пользователя.
|