В мир информатики # 95 (1–15 октября).
Школа программирования
Основы программирования на Visual Basic
Продолжение. Начало см. “В мир информатики”
№ 69–73, 78–80, 83, 85–86, 88–89, 91 (“Информатика”
№ 4–8, 19–21, 24/2006, 3–4, 6–7, 9/2007)
Н.М. Тимофеева,
г. Обнинск Калужской обл.
Пример программирования № 12
“Альбом для рисования”
Постановка задачи
Разработайте простейший графический
редактор. Программа должна позволять
пользователю выбирать цвет и толщину линий.
План решения
На рис. 1 показан предлагаемый
дизайн экрана:

Рис. 1
Назначение каждого элемента
управления:
1) элемент PictureBox (Блок картинки)
в правой части формы2 — для показа изображения из
линий;
2) элемент PictureBox (Блок картинки)
в левой части формы3 — для показа текущего цвета;
3) горизонтальные полосы прокрутки (HScrollBar)
— для изменения доли красного, зеленого и
голубого цветов в их “смеси” (цвет “смеси”
будет использоваться для линий в большом блоке
картинки и для фона маленького блока картинки);
4) Shapes (Фигуры) — для указания
цвета, регулируемого той или иной полосой
прокрутки;
5) Lines (Линии) — для показа
возможной ширины линий;
6) массив надписей — для выбора ширины
линий и показа линии выбранной ширины с помощью
стрелки (¬); ширина линии будет использоваться
при рисовании в большом блоке картинки;
7) дополнительные надписи — для
использования в качестве заголовков;
8) кнопка Очистить — для очистки
содержимого большого блока картинки по щелчку на
кнопке;
9) кнопка Выход — для завершения
программы по щелчку на ней.
N–S-диаграммы для разработки
процедур следующие.
Процедура для загрузки формы:

Процедура для установки цвета фона
маленького блока картинки:

Процедура для изменения “красной”
полосы прокрутки:
Установить цвет маленького блока
картинки
Процедура для изменения “зеленой”
полосы прокрутки:
Установить цвет маленького блока
картинки
Процедура для изменения “синей”
полосы прокрутки:
Установить цвет маленького блока
картинки
Процедура для щелчка по массиву
надписей:

Процедура для нажатия левой кнопки
мыши в большом блоке картинки:

Процедура для отпускания левой
кнопки мыши в большом блоке картинки:

Процедура для перемещения мыши в
большом блоке картинки:

Процедура для кнопки Очистить:

Создание интерфейса
Разместите на форме две кнопки, два
элемента управления PictureBox (Блок картинки),
три горизонтальные полосы прокрутки (HScrollBar),
три фигуры (Shape), три надписи (Caption) и четыре
линии (Line) — см. рис. 2.

Рис. 2
Массив надписей для указания линии
выбранной ширины с помощью стрелки следует
создать из надписи Label3. Сначала установите
для нее следующие значения свойств:

После этого выделите эту надпись, в
пункте меню Edit (Правка) выберите подпункт Copy
(Копировать), а затем подпункт Paste (Вставить).
В ответ на появившееся диалоговое окно с
вопросом выберите Yes и продолжайте
копировать, пока не будут созданы четыре надписи
c одним и тем же именем lblСтрелка. В результате у
вас будет массив надписей, каждая с одним и тем же
именем, но с уникальным значением свойства Index.
Проверьте это значение у каждой надписи и
убедитесь, что оно меняется от 0 до 3. Вам нужно
изменить значения свойства так, чтобы было от 1 до
4.
Установка свойств
Установите следующие свойства формы и
остальных элементов управления:




Присвойте значению свойства BorderWidth
первой линии 1, второй линии — 2 и т.д.
Измените размер надписи с именем
lblСтрелка(1) так, чтобы она легла поверх линии 1, и
расширьте ее границы вправо на пару квадратиков
сетки. Удалите заголовок. Так же поместите
надпись с именем lblСтрелка(2)поверх линии 2. Нижняя
граница надписи lblСтрелка(1) должна лежать на
верхней границе надписи lblСтрелка(2). С
оставшимися двумя надписями массива поступите
точно так же (см. рис. 3).

Рис. 3
Написание кода
В разделе кода (General) (Declarations) должны
быть объявлены две переменные уровня формы:
Option Explicit
Dim Толщина As Integer
'Текущая толщина линии
Dim Карандаш As Boolean
Создайте общую процедуру4, которую
будем использовать в процедурах обработки
события Change (Изменение) любой из трех полос
прокрутки:
'Данная процедура устанавливает смесь
'цветов в зависимости от положения
'полос прокрутки
Private Sub Выбор_Цвета()
picЦвет.BackColor = RGB(hsbКрасный.Value,
hsbЗеленый.Value, hsbГолубой.Value)
End Sub
Тогда коды обработки события Change, о
котором речь шла только что, будут такими:
Private Sub hsbКрасный_Change()
Выбор_Цвета
End Sub
Private Sub hsbЗеленый_Change()
Выбор_Цвета
End Sub
Private Sub hsbСиний_Change()
Выбор_Цвета
End Sub
В процедуре загрузки формы
устанавливается начальная ширина линии:
Private Sub Form_Load()
Толщина = 1 'Текущая ширина линии 1
'Символ стрелки (шрифт Wingdings)
lblСтрелка(Толщина).Caption = Chr(239)
End Sub
Этот код выполняется при щелчке по
любой из надписей массива:
Private Sub lblСтрелка_Click(Index As Integer)
'Устанавливаем заголовок (символ
стрелки)
lblСтрелка(Index).Caption = Chr(239)
'Устанавливаем толщину линии
Толщина = Index
picРисунок.DrawWidth = Толщина
End Sub
Код для события MouseDown (Нажатие кнопки
мыши) в большом блоке картинки:
Private Sub picРисунок_MouseDown(Button As Integer, Shift As
Integer, X As Single, Y As Single)
Карандаш = True
picРисунок.CurrentX = X
picРисунок.CurrentY = Y
End Sub
Код для перемещения мыши в этом же
элементе управления:
Private Sub picРисунок_MouseMove(Button As Integer, Shift As
Integer, X As Single, Y As Single)
Dim Цвет_Линии As Long
'Рисовать только при нажатой кнопке
мыши
If Карандаш Then
'Цвет из маленького блока картинки
Цвет_Линии = picЦвет.BackColor
'Рисовать от последней точки
picРисунок.Line -(X, Y), Цвет_Линии
End If
End Sub
Код для события MouseUp (Отпускание кнопки
мыши):
Private Sub picРисунок_MouseUp(Button As Integer, Shift As
Integer, X As Single, Y As Single)
Карандаш = False 'Кнопка мыши отпущена
End Sub
Код для кнопки Очистить:
Private Sub cmdОчистить_Click()
picРисунок.Cls
End Sub
Сохранение проекта
Создайте папку Пример12 и сохраните
в ней форму и проект под именами блокнот.frm и блокнот.vbp.
Тестирование приложения
Попробуйте рисовать в большом блоке
картинки. Изменяйте цвет и ширину линии.
Взгляд назад
Проверьте, что программа выполняет
все, что требуется. Довольны ли вы интерфейсом
приложения? Возможно, вы сможете не получить
какой-то нужный вам цвет. Почему?
Пояснения
1. Эта программа использовала массив
надписей: lblСтрелка(1), lblСтрелка(2),
lblСтрелка(3) и lblСтрелка(4). Только одна
процедура должна была быть написана для щелчка
по любой из четырех надписей:
Private Sub lblСтрелка_Click(Index As Integer)
Аргумент Index в процедуре — это
индекс той надписи, по которой щелкнули. Так что
если щелкнуть по надписи lblСтрелка(2), то Index
будет иметь значение 2.
2. С элементами управления Lines (Линии)
и Shapes (Фигуры) не связаны какие-либо
события. Поэтому поверх линий расположены
прозрачные надписи, по щелчку на которых и
происходят необходимые действия (пользователю
при этом кажется, что он щелкает по линиям).
3. Свойство MousePointer элемента управления PictureBox
определяет тип указателя мыши, когда он
находится в пределах этого элемента. Значение,
равное 2, соответствует указателю в виде
перекрестия (3 — указателю в виде мигающей
вертикальной черточки, 5 — в виде
четырехнаправленной стрелки, 11 — в виде песочных
часов).
4. Инструкция Option Explicit появляется
автоматически в разделе (General) (Declarations) кода, когда
в пункте меню Tools, в подпункте Options…
выбрано Require Variable Declaration5.
5. Это приложение использует две
переменные уровня формы:
— Толщина (целого типа) — хранит
значение текущей ширины линии;
— Карандаш (логического типа) —
указывает, нажата ли кнопка мыши в блоке
картинки.
Так сделано потому, что эти переменные
используются в нескольких процедурах.
6. RGB — это функция, которая возвращает
целое число (типа длинное целое),
представляющее значение текущего цвета для
изображения. У этой функции есть три аргумента
целого типа, которые принимают значения в
промежутке от 0 до 255 и указывают красную, зеленую
и синюю компоненту “смеси”. Заметим, что наличие
всех цветов дает белый цвет, а отсутствие всех
цветов — черный.
7. Значение Chr(239) соответствует символу
стрелки ( ) в
шрифте “Wingdings”.
8. События MouseDown и MouseUp происходят, когда
вы нажимаете или отпускаете кнопку мыши в момент
нахождения ее указателя на объекте. Заголовок
процедуры обработки этих событий содержит
аргументы Button, Shift, X и Y. В нашем случае
используются только аргументы X и Y. Эти аргументы
определяют координаты текущего положения
указателя мыши. Аргумент Button фиксирует, какая из
трех кнопок мыши нажата. Аргумент Shift определяет,
нажаты ли клавиши , и в тот момент, когда
нажата кнопка мыши.
9. Система координат элемента PictureBox
определяется свойствами ScaleLeft, ScaleTop и ScaleMode. В
этом примере значения этих свойств оставлены по
умолчанию: свойству ScaleLeft соответствует значение
0, ScaleTop — значение 0, ScaleMode — значение 1. Это значит,
что точка с координатами (0, 0) находится в верхнем
левом углу, а единицы измерения заданы в твипах
(twips). В одном сантиметре 567 твипов.
10. Метод Line позволяет рисовать линии на
объекте (в нашем случае на элементе PictureBox).
Начальные и конечные координаты линии, а также ее
цвет могут быть заданы. Если начальные
координаты не указаны, линия рисуется от
последней нарисованной точки:
picРисунок.Line –(X, Y), Цвет_Линии
11. У события MouseMove также есть
аргументы Button, Shift, X и Y. При движении мыши с
нажатой кнопкой рисуется серия прямых линий,
каждая начинается там, где заканчивается
предыдущая. При этом значения аргументов X и Y
непрерывно обновляются.
12. Если во время выполнения приложения
размеры формы будут изменены, размеры элемента PictureBox
(Блок картинки) останутся без изменений.
Хорошо, если бы и они менялись пропорционально
изменению размеров формы. Чтобы добиться этого,
необходимо, чтобы такие свойства элемента PictureBox,
как Height и Wight, были изменены во время выполнения
приложения. Изучите следующее дополнение кода:
Option Explicit
'Текущая толщина линии
Dim Толщина As Integer
Dim Карандаш As Boolean 'True или False
'Коэффициенты размеров
Dim Коэффициент_Высоты As Single,
Коэффициент_Ширины As Single
Private Sub Form_Load() 'Текущая ширина линии
равна 1
Толщина = 1
'Символ стрелки (шрифт Wingdings)
lblСтрелка(Толщина).Caption = Chr(239)
'Вычисляем коэффициенты
Коэффициент_Высоты = picРисунок.Height /
Form1.ScaleHeight
Коэффициент_Ширины = picРисунок.Width /
Form1.ScaleWidth
End Sub
Private Sub Form_Resize()
'При изменении размеров формы
изменяются размеры рисунка
'Изменение высоты рисунка
picРисунок.Height = Form1.ScaleHeight *
Коэффициент_Высоты
'Изменение ширины рисунка
picРисунок.Width = Form1.ScaleWidth *
Коэффициент_Ширины
End Sub
Вопросы и задания для проверки знаний
1. Рассмотрите следующую строку кода:
lblСтрелка(Index).Caption = Chr(239). Назовите элемент
управления, имя элемента управления, индекс
элемента массива, свойство и значение свойства.
2. В чем преимущество использования
массива надписей в этом примере по сравнению с
использованием четырех отдельных надписей?
3. Для элемента управления PictureBox (Блок
картинки) установлены следующие значения
свойств:

Опишите линию, которая будет
нарисована в результате выполнения следующей
строки кода: picРисунок.Line(1500, 800) – (5000, 2200), RGB(0,0,0)
4. К чему обязывает программиста
инструкция Option Explicit?
5. Почему в этом примере
программирования используются переменные
уровня формы?
6. Объясните назначение переменных
уровня формы Толщина и Карандаш?
7. Используйте приведенные
рекомендации по изменению кода, которые
позволяют изменять размеры рисунка
соответственно изменению размеров формы.
Правильные ответы на вопросы,
опубликованные в одном из предыдущих выпусков
серии статей “Основы программирования на Visual
Basic”, прислали:
— Деминцев Борис, средняя школа села
Сердар, Республика Марий Эл, учитель Чернова
Л.И.;
— Зенкина Наталья, Омская обл., поселок
Марьяновский, школа № 3, учитель Кичигина М.Л.;
— Клипов Игорь, г. Балашов Саратовской
обл., гуманитарно-педагогический лицей-интернат,
учитель Сухорукова Е.В.;
— Приходько Марина, средняя школа села
Дохновичи Брянской обл., учитель Клопова Е.В.
Эти учащиеся разработали также приложение для
вывода таблицы синусов углов от 0° до 90° с шагом
10° (в программе Игоря Клипова предусмотрен и
вывод графика соответствующей функции).
2 В дальнейшем этот элемент будем
условно называть “большой блок картинки”.
3 В дальнейшем этот элемент будем
условно называть “маленький блок картинки”.
4 О так называемых “общих” процедурах см.
“В мир информатики” № 78 (“Информатика” №
19/2006). — Прим. ред.
5 Напомним, что эта инструкция
предусматривает, что все используемые
переменные величины и константы должны быть
объявлены (описаны). — Прим. ред. |