В мир информатики # 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-диаграммы для разработки процедур следующие.

Процедура для загрузки формы:

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

Процедура для изменения “красной” полосы прокрутки:

 

Установить цвет маленького блока картинки

Процедура для изменения “зеленой” полосы прокрутки:

Установить цвет маленького блока картинки

Процедура для изменения “синей” полосы прокрутки:

Установить цвет маленького блока картинки

Процедура для щелчка по массиву надписей:

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

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

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

39-3.gif (12370 bytes)

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

Создание интерфейса

Разместите на форме две кнопки, два элемента управления 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 Напомним, что эта инструкция предусматривает, что все используемые переменные величины и константы должны быть объявлены (описаны). — Прим. ред.