Федеральное агентство по образованию РФ НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ЯДЕРНЫЙ УНИВЕРСИТЕТ «МИФИ» УЧЕБНАЯ КНИГА ЭКОНОМИК...
50 downloads
313 Views
2MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Федеральное агентство по образованию РФ НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ЯДЕРНЫЙ УНИВЕРСИТЕТ «МИФИ» УЧЕБНАЯ КНИГА ЭКОНОМИКО-АНАЛИТИЧЕСКОГО ИНСТИТУТА НИЯУ МИФИ
Н. Г. Волченков, А. К. Троицкий
ПРОЕКТИРОВАНИЕ WINDOWS-ПРИЛОЖЕНИЙ НА ЯЗЫКЕ VISUAL BASIC .NET (2005, 2008)
Учебно-методическое пособие
МОСКВА 2010
УДК 004.4(07) ББК 32.973-018.2я7 В68 Волченков Н.Г., Троицкий А.К. Проектирование Windows-приложений на языке Visual Basic .NET (2005, 2008): Учебно-методическое пособие. – М.: НИЯУ МИФИ, 2010. – 96 с. В пособие включены шесть лабораторных работ по курсу «Высокоуровневые методы информатики и программирования», читаемого студентам Экономико-аналитического института НИЯУ МИФИ. Этот раздел относится к изучению языка Visual Basic .NET (2005, 2008) и его применению при создании Windows-приложений. Каждая лабораторная работа содержит вопросы по изучаемой теме, на которые студентам необходимо ответить перед ее выполнением. На примерах демонстрируется технология создания разнообразных полезных приложений. В качестве инструментального программного средства проектирования Windowsприложений рассматривается среда проектирования Visual Studio 2005 (Express Edition) фирмы Microsoft для языка Visual Basic 2005. Пособие предназначено для студентов, осваивающих теоретические основы и практические навыки проектирования Windows-приложений в процессе изучения основного раздела курса «Высокоуровневые методы информатики и программирования», а также преподавателям, читающим лекции и проводящим лабораторные работы по данному курсу в компьютерных классах. Рецензент – канд. техн. наук, доцент М.Н. Петухов Утверждено к изданию редсоветом НИЯУ МИФИ ISBN 978-5-7262-1248-7
© Национальный исследовательский ядерный университет «МИФИ», 2010.
Редактор Е.Н. Кочубей Подписано в печать 31.03.2010. Формат 60×84 1/16 Объем 6,0 п.л. Уч. изд. л. 6,0. Тираж 100 экз. Изд. № 010-1. Заказ 125. Национальный исследовательский ядерный университет «МИФИ». Типография НИЯУ МИФИ. 115409, Москва, Каширское шоссе, 31.
Содержание Предисловие редактора серии ................................................................. 4 Введение .................................................................................................... 6 Работа № 1. Знакомство со средой разработки Windows-приложений на языке Visual Basic .NET (2005, 2008). Создание проектов: «Приветствие», «Секундомер», «Светофор» ...................................... 8 Работа № 2. Примеры проектирования Windows-приложений на языке Visual Basic .NET (2005, 2008) с использованием встроенных функций: математических, финансовых, обработки строк и преобразования типов ............................................................ 19 Работа № 3. Исследование графических объектов и методов языка Visual Basic .NET (2005, 2008) на примере проектирования приложения «Построение диаграмм» ............................................... 28 Работа 4. Исследование графических объектов и методов 2D-графики языка Visual Basic .NET (2005, 2008) на примере проектирования приложений «Построение графиков функций» и «Построение сложных фигур» ........................................................ 40 Работа 5. Использование особенностей процедур-событий языка VB .NET, применяемых к множествам элементов управления при создании приложений типа «Калькулятор» и «Шахматная доска» ................................................................................................... 57 Работа 6. Использование программных массивов для обработки большого числа однотипных данных (на примере одномерного и двумерного массивов) ....................................................................... 75 Список рекомендуемой литературы ..................................................... 96 ______
3
ПРЕДИСЛОВИЕ РЕДАКТОРА СЕРИИ Глубокоуважаемый читатель! В Ваших руках очередное издание из серии «Учебная книга Экономикоаналитического института МИФИ». Экономико-аналитический институт создан в 1996 году как программноцелевое подразделение государственного университета МИФИ. Задача ЭАИ – на основе высокого учебно-методического и научного потенциалов кафедр МИФИ подготовить экономистов-математиков, экономистовинформатиков и экономистов-менеджеров, владеющих современными математическими методами и информационными технологиями в экономике и управлении, представляющих состояние и перспективы развития наукоемких технологий реального сектора экономики, способных решать сложные социально-экономические задачи. Для обеспечения учащихся ЭАИ МИФИ учебной литературой по тем разделам и дисциплинам, по которым обильный рынок экономической литературы имеет «вакансии», издается с 1998 года серия «Учебная книга Экономико-аналитического института МИФИ». В этой серии уже изданы около 40 книг. Среди последних изданий ЭАИ назовем такие: ¾ Розанов В.Б., Степанов Р.В. Концепции современного естествознания. Что и почему должен знать каждый о физике. М.: МИФИ, 2003. – 232 с. ¾ Скворцов В.И. Технология создания бизнес-моделей. Часть 1. Технологические приемы построения диаграмм в среде ARIS 6.0. М.: МИФИ, 2003. – 92 с. ¾ Экономика ядерной энергетики (конспект лекций). Учебное пособие /Под ред. проф. В.В. Харитонова. М.: МИФИ, 2004. – 280 с. ¾ Новохатько А.Г. История экономических учений. Курс лекций и хрестоматия. М.: МИФИ, 2004. – 484 с. (Часть 1); 2005. – 860 с. (Часть 2). ¾ Мишулина О.А. Статистический анализ и обработка временных рядов. М.: МИФИ, 2004. – 140 с. ¾ Власов В.А. Оценки и доверительные интервалы. М.: МИФИ, 2006. – 104 с. ¾ Фомина А.В. Стратегический менеджмент: Курс лекций. М.: МИФИ, 2006. – 186 с. ¾ Эконофизика//Под ред. А.А. Ежова и В.В. Харитонова М.: МИФИ, 2007. – 624 с. 4
Харитонов В.В. Энергетика. Технико-экономические основы. М.: МИФИ, 2007. – 256 с. (+ 72 с. илл.). Юшков Е.С. и др. Управление интеллектуальными активами предприятия. В 4-х томах. М.: Полиграфикс, 2008. Гусева А.И., Киреев В.С., Тихомирова А.Н., Филиппов С.А. Компетенции работников образования в области информационных и коммуникационных технологий. М.: МИФИ, 2009. – 256 с. Седелев Б.В. Регрессионные модели и методы оценки параметров и структуры экономических процессов. М.: МИФИ, 2009. – 240 с. Нанотехнологии как ключевой фактор нового технологического уклада в экономике / Под ред. С.Ю. Глазьева и В.В. Харитонова. М.: Тровант, 2009. – 256 с. (+ 48 с. илл.). Учебно-методическое пособие «Проектирование Windows-приложений на языке Visual Basic. NET (2005, 2008)» охватывает материал курса «Высокоуровневые методы информатики и программирования», читаемого авторами в ЭАИ НИЯУ МИФИ. Несколько слов об авторах этого учебного пособия. Волченков Николай Геннадьевич, канд. техн. наук, доцент кафедры Кибернетики НИЯУ МИФИ с 1982 г. Автор более 50 научных трудов, нескольких учебных пособий, в том числе выпущенных в центральных издательствах. Специализируется в области логического программирования, искусственного интеллекта, информатики и программирования в визуализированных средах. В настоящее время ведет курсы: «Логическое программирование», «Теория программирования. Объектно-ориентированное программирование» (на кафедре Кибернетики); «Высокоуровневые методы информатики и программирования» (в ЭАИ МИФИ). Является научным руководителем студентов, выполняющих курсовые и дипломные проекты, руководит подготовкой магистерских диссертаций. Троицкий Авенир Клавдиевич, канд. техн. наук, доцент кафедры Кибернетики НИЯУ МИФИ с 1989 г. Автор более 40 научных трудов. Специализируется в области распознавания образов, обработки изображений и звуковой информации. В настоящее время ведет курс по обработке аудиовизуальной информации (на кафедре Кибернетики). Является научным руководителем студентов, выполняющих курсовые и дипломные проекты, руководит подготовкой магистерских диссертаций. Авторы данной книги и редактор серии будут признательны читателям за отзывы и предложения по улучшению содержания учебного пособия.
Директор ЭАИ НИЯУ МИФИ, профессор, академик Академии естественных наук, заслуженный работник высшей школы В. В. Харитонов
5
Введение Язык Visual Basic – прямой потомок Бейсика, универсального языка программирования, которому уже около полувека. Как у почтенного «предка», так и у его молодого «потомка» масса общих достоинств, главное из которых – легкость изучения и освоения людьми самых разных профессий, зачастую далеко не программистами. Именно поэтому Visual Basic – самый распространенный язык в мире. Он приспособлен к работе на самых современных компьютерах и в самых современных операционных системах. Visual Basic .NET (VB 2005, 2008) – это один из последних диалектов языка Visual Basic. Изучению именно этого диалекта, а также среды, созданной для создания работающих программ на этом диалекте, посвящен курс «Высокоуровневые методы программирования», по которому читаются лекции и проводятся лабораторные занятия в компьютерных классах, составляющие предмет настоящего методического пособия. Почему же все-таки авторами пособия выбран именно Visual Basic, а не, допустим, Delphi – диалект Паскаля? Аргументы этого выбора таковы: 1. Сейчас на рынке операционных систем для персональных компьютеров наиболее распространены разработки фирмы Microsoft – это, прежде всего, система Windows последних поколений (2000, XP, Vista, 7). Очень популярны разнообразные программы Microsoft Office. В большинстве этих программ присутствует особый механизм для создания компактных и удобных для пользователя дополнительных средств обработки информации – так называемых макросов. Их можно создавать на языке VBA (Visual Basic for Applications), который очень близок к языку Visual Basic. Во всяком случае, освоив Visual Basic, можно легко переквалифицироваться в программиста на языке VBA. 2. В настоящее время многие пользователи Интернета увлекаются изучением языка гипертекстовой разметки (HTML) для редактирования Web-страниц. Сам по себе этот язык очень прост и ничего общего с Visual Basic не имеет. Но для достижения очень многих заманчивых целей при работе с такими страницами (в частности, для использования на них элементов управления самого 6
разного назначения) можно использовать упрощённый диалект Visual Basic – язык VBScript. Это язык сценариев работы гипертекстовых страниц. С появлением новой платформы .NET фирма Microsoft предоставила более сильный инструмент – технологию ASP (активных серверных страниц). В рамках этой технологии используется не VBScript, а язык Visual Basic .NET в «чистом виде». 3. Специалисты корпорации Microsoft хорошо методически продумали и «обкатали» систему проектирования Visual Basic .NET. Это система может составлять предмет гордости фирмы Microsoft. Она входит в состав легко доступной в наше время системы Microsoft Visual Studio .NET (2005, 2008). Экспресс-версии этих систем распространяются фирмой бесплатно для их использования в учебных целях. По мнению авторов данного учебного пособия справочную систему MSDN устанавливать не обязательно – достаточно черпать справочную информацию из многочисленных книг на русском языке – как отечественных, так и переводных. 4. Последний аргумент авторов пособия чисто эмоциональный и субъективный. По их глубокому убеждению, программирование на Visual Basic доставляет изучающим его людям большое удовольствие, прежде всего, благодаря быстрому и эффективному движению начинающего программиста по маршруту от сложного замысла до готового результата. Этим результатом является действующее Windows приложение для какой-нибудь очень интересной с точки зрения этого программиста задачи. Для аналитиков-экономистов такими задачами могут быть экономические и финансовые расчеты, визуализация результатов решения финансовых и экономических задач. Пособие рассчитано на проведение 6 занятий (лабораторных работ). На каждое занятие студенту отводится время от 2 до 4 академических часов c обязательным чтением лекции перед каждым сеансом самостоятельной работы студента за пультом персонального компьютера. Как показывает опыт, именно такая форма обеспечивает наиболее эффективное усвоение материала данного курса. Для более детального усвоения материала полезно ознакомление с дополнительной литературой из списка, представленного в конце данного пособия. 7
Работа № 1 Знакомство со средой разработки Windows-приложений на языке Visual Basic .NET (2005, 2008). Создание проектов: «Приветствие», «Секундомер», «Светофор» Цель работы: изучение и освоение студентами основных этапов технологии создания Windows-приложений с использованием языка программирования Visual Basic .NET (2005, 2008) и среды Visual Basic 2005, входящей в состав программного пакета Microsoft Visual Studio .NET (2005, 2008). Подготовка к работе В ходе подготовки к работе студенты изучают этапы технологии создания Windows-приложения с использованием языка и среды проектирования Visual Basic 2005 (2008). Указанными этапами являются: 1) проведение подготовительной «ручной» работы, состоящей в разработке «на бумаге»: а) эскиза единственной экранной формы, б) таблиц значений свойств как самой формы, так и элементов управления на форме (тех свойств, для которых необходимо установить «особые», не заданные «по умолчанию» значения), в) алгоритмов и программ для процедур-событий, определяющих логику работы проектируемого Windows-приложения; 2) проведение компьютерного редактирования формы (реализация интерфейса) в среде проектирования – установка на форме всех необходимых элементов управления и всех необходимых значений их свойств; 3) осуществление построчного ввода программного кода процедур-событий модуля формы с выявлением и устранением синтаксических ошибок, допущенных при ручном составлении этого кода; 4) интерпретация (запуск) проекта с целью выявления смысловых ошибок алгоритмов и программ для процедур-событий (если таковые имеются) и, по возможности, исправление этих ошибок; 8
5) проведение завершающих создание Windows-приложения действий: сохранение файлов проекта и компиляция – формирование исполняемого приложения (файла .exe). Порядок проведения работы Работа проводится на примере создания простых проектов, содержащих единственную форму, и компиляции этих проектов в исполняемые Windows-приложения. Освоение студентами «компьютерных» перечисленных выше этапов технологии создания Windows-приложения с использованием языка и среды проектирования Visual Basic 2005 (2008) предполагает изучение и освоение инструментальных средств среды проектирования: команд меню, линеек инструментов и основных окон среды. Эти средства осваиваются по ходу настоящей работы в процессе создания конкретного проекта. Перед выполнением работы необходимо ознакомиться с литературой и материалами лекций, а также проконтролировать свои знания, ответив на следующие контрольные вопросы: 1. Что такое программное приложение и, в частности, Windowsприложение? 2. Что такое проект приложения? Чем отличается работа проекта приложения от работы самого приложения? 3. Что означает термин «разработка интерфейса экранной формы»? 4. Что такое «элемент управления» («объект управления») на экранной форме? Что представляет собой класс элементов управления? 5. Что представляет собой свойство экранной формы и элемента управления на форме? Как задать значение свойства? 6. Что такое программный модуль экранной формы? Что представляют собой составные части («блоки»), из которых состоит модуль формы? 7. Что собой представляет процедура-событие для того или иного элемента управления или для самой формы? 9
Задания В ходе выполнения данной работы студент должен выполнить два задания. 1.1. Создать проект приложения, единственным назначением которого является выдача приветствия пользователю, запустившему это приложение. 1.2. Освоение возможности использования элемента управления Timer, а также применение условного оператора If Then Else (и/или оператора Select Case) языка Visual Basic (по вариантам). Задание 1.1 выполняется фронтально (без вариантов), задания 1.2 – по вариантам. Пример выполнения работы Задание 1.1. Создать проект приложения, единственным назначением которого является выдача приветствия пользователю, запустившему это приложение. Студенту предоставляется свобода выбора формы данного приветствия с помощью: а) стандартного окна сообщения MsgBox; б) печати сообщения на самой форме; в) «выявления» ранее невидимой метки; г) вывода текста сообщения в текстовое поле. Событием, инициирующим появление приветствия, должен быть щелчок мышью по командной кнопке или команде меню. Детально рассмотрим один из указанных вариантов: приветствие появляется после щелчка командной кнопки в текстовом поле, в котором до появления приветствия присутствует текст: «Здесь появится приветствие». После появления приветствия командная кнопка должна «исчезнуть» (стать невидимой). Этапы технологии разработки приложения таковы. 1. «Ручной» этап. На данном этапе продумывается интерфейс. Оцениваются размер, цвет, заголовок формы; положение формы на экране; наличие кнопок минимизации и «распахивания» формы; расположение и размеры элементов управления на форме. Оцениваются значения свойств двух элементов: командной кнопки (вид и размер шрифта) и текстового поля (цвет фона, расположение тек10
ста, вид и размер шрифта). Принимается решение о том, нужно ли изменять имена элементов управления. Имена можно оставить теми, которые даны этим объектам «по умолчанию»: Button1 и TextBox1. Составляется программный код единственной процедуры: Button1_Click(…) для события, вызывающего появление приветствия в текстовом поле и делающего кнопку невидимой. 2. Компьютерный интерфейс. Производится запуск приложения Microsoft Visual Basic 2005 Express Edition – среды проектирования Windows-приложений на языке Visual Basic 2005. На стартовой странице (Start Page) в рамке Recent Projects выбирается режим создания нового проекта (щёлкается кнопка Project справа от слова Create). В появившемся окне New Project выбирается пиктограмма Windows Application, а в текстовом поле вместо заданного «по умолчанию» имени WindowsApplication1 желательно вписать более содержательное имя проекта, например, Приветствие. После чего щёлкается кнопка OK. Появляется Главная панель среды, показанная на рис. 1.1.
Рис. 1.1. Вид окна среды проектирования в начале создания нового проекта 11
На данной панели сначала следует обратить внимание на окно Проводника Решения (Solution Explorer), в котором «по умолчанию» представлена стандартная структура нового проекта. Редактирование формы следует начинать, щёлкнув кнопку View Designer этого окна. При этом в главном окне Главной панели будет располагаться «макет» формы, на которую следует поместить необходимые экземпляры элементов управления из набора Toolbox. Поочерёдно щёлкая форму и эти элементы управления, делаем доступными свойства указанных объектов (в окне Properties). Значения этих свойств устанавливаются в соответствии с пожеланиями, сформулированными на этапе 1. (Например, для удаления кнопок минимизации и «распахивания» формы следует изменить значения её свойств MinimizeBox и MaximizeBox с True на False.) Для реализации компьютерного интерфейса (в данной и во всех последующих работах) рекомендуется заполнять таблицу свойств, подобную следующей: Имя объекта Form1
Класс объекта Form
TextBox1 TextBox
Button1
Button
Свойство объекта Text MinimizeBox MaximizeBox Font TextAlign MultiLine Font
Значение свойства “Приветствие пользователю” False False Name: “Times New Roman” Size: 24 Center True Type: “MS Sans Serif” Size: 14
Отметим, что некоторые свойства являются «потомками» «родительских» свойств (например, свойства-потомки Name и Size родительского свойства Font). Значения некоторых свойств можно менять «на глазок», такие, как размеры формы и положение окна работающего приложения на экране. Эти значения можно установить с помощью мыши, «растягивая» или «сжимая» ширину и высоту формы. Также с помощью мыши можно «на глазок» устанавливать размеры элементов управления и положение их на форме. 12
3. Ввод кода процедур. Для ввода кода процедур программного модуля используется переход к окну программного кода с помощью щелчка кнопки View Code в окне Solution Explorer. В левом раскрывающемся списке в окне программного кода следует найти и щёлкнуть интересующий нас объект (в данном случае Button1). В правом раскрывающемся списке следует найти интересующее нас событие для этого объекта (в данном случае Click). Появятся две строки (первая и последняя) для данной процедурысобытия (рис. 1.2).
Рис. 1.2. Вид окна среды проектирования после щелчка кнопки View Code
Между указанными строками записывается код данной процедуры: Код 1.1 Public Class Form1 Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles _ Button1.Click TextBox1.BackColor = Color.Blue TextBox1.ForeColor = Color.White Button1.Visible = False
13
TextBox1.Text = "Привет, " & _ InputBox("Введитете Ваше имя") & "!" End Sub End Class
В записи данного кода из-за слишком большой длины двух строк использован знак переноса «_». 4. Интерпретация (запуск) проекта. Запуск проекта осуществляется щелчком кнопки Start Debugging (зелёный треугольник на главной линейке инструментов) и вызывает появление окна проектируемого приложения (рис. 1.3, а). После щелчка единственной кнопки на форме появляется стандартное окно ввода системы Windows, в текстовое поле которого пользователь вводит своё имя, например: Николай. После этого вид формы становится таким, как на рис. 1.3, б.
а б Рис. 1.3. Вид окна после запуска приложения (а) и после ввода имени (б)
Остановка выполнения программы осуществляется либо щелчком кнопки Stop Debugging (синий квадратик на главной линейке инструментов), либо кнопкой закрытия приложения. 5. Сохранение проекта и создание исполняемого приложения. Для сохранения проекта и одновременно его компиляции (создания исполняемого приложения) достаточно щелкнуть кнопку Save All главной линейки инструментов среды проектирования. Появляется панель сохранения проекта (рис. 1.4):
14
Рис. 1.4. Вид панели сохранения проекта
Место сохранения проекта «по умолчанию» устанавливается так, как показано в текстовом поле Location, и может быть изменено, но рекомендуется «согласиться» с предлагаемым вариантом. В указанной папке Projects будет создана папка Приветствие, в которой сохранится файл Приветствие.sln данного «решения» (Solution) и папка проекта с тем же именем (рис. 1.5).
Рис. 1.5. Содержимое папки Solution
Рис. 1.6. Содержимое папки проекта Приветствие 15
Папка проекта (рис. 1.6) содержит 3 папки и 4 файла (в том числе файл проекта Приветствие.vbproj). Именно этот файл следует «запускать» для последующей доработки данного проекта. Исполняемый (скомпилированный) файл Приветствие.exe можно найти в папке Debug, которую содержат папки bin и obj. Задание 1.2. Освоение возможности использования элемента управления Timer, а также применение условного оператора If Then Else (и/или оператора Select Case) языка Visual Basic. Вариант 1. Создать приложение «Секундомер». Его назначение то же, что и у обычного (механического) секундомера. Щелчок командной кнопки (процедура Button1_Click) должен запускать «секундомер» – в поле метки (элемент Label1) через равные промежутки времени (например, через 0,1 секунды) должно изменяться число (начиная с 0, увеличиваясь на 0,1). Надпись СТАРТ на командной кнопке после запуска «секундомера» должна меняться на ФИНИШ. И наоборот – после его остановки надпись ФИНИШ должна меняться на СТАРТ. Указание. В начале программного кода должно быть сделано объявление переменной ns как десятичного числа обычной или двойной точности: Dim ns As Single или Dim ns As Double. Включение и выключение таймера (элемента управления Timer1) осуществляется изменением значения его свойства Enabled программно – в процедуре Button1_Click. Значение свойства Interval элемента Timer1 должно быть установлено равным 100, что соответствует 0,1 секунды. Процедура-событие Timer1_Tick должна изменять значение переменной ns на эту величину, а также изменять значение свойства Text элемента Label1. Желательно отображать время в форме: hh:mm:ss,s. Для этого следует использовать функцию форматирования и дополнительные переменные nm и nh типа Integer или Short – целое число – для «минут» и «часов». Тогда процедура Timer1_Tick будет иметь следующей вид: Код 1.2 Private Sub Timer1_Tick(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Timer1.Tick ns = ns + 0.1 16
If nm >= 60 Then ns = 0 nm = 0 nh = nh + 1 End If If ns >= 60 Then ns = 0 nm = nm + 1 End If Label.Text = Format(nh, "00:") & _ Format(nm, "00:") & _ Format(ns, "00.0") End Sub
Вариант 2. Создать приложение «Светофор». Его назначение – демонстрация «логики» работы уличного светофора: правильного чередования включения и выключения огней светофора (красный – жёлтый – зелёный – жёлтый – красный – жёлтый и т.д.) Время горения каждого цвета должно быть задано, например: красный 2,5 с, жёлтый 0,2 с, зелёный 1,5 с. Указание. В начале программного кода должно быть сделано объявление переменной n как небольшого целого числа: Dim n As Byte или Dim n As Short. С помощью таймера эта переменная должна циклически принимать значения: 0, 1, 2, 3, 0, 1, 2, 3, … Это реализуется двумя строками в процедуре Timer1_Tick: Код 1.3 n = n + 1 If n = 4 Then n = 0
Для изображения огней светофора предлагается использовать графические файлы, которые задают значение свойства Image у пяти полей изображения PictureBox1 – PictureBox5 (2 круга чёрного цвета и по одному кругу красного, жёлтого и зелёного цветов). Через промежутки времени, определяемые программно для каждого цвета светофора, следует размещать объекты PictureBox1 – PictureBox5 в нужных местах экранной формы: 3 объекта – один под другим, 2 объекта – за границей видимости. В процедуре 17
Timer1_Tick целесообразно использовать оператор Select Case n для рассмотрения всех случаев – для всех четырёх значений переменной n. В каждом из этих случаев устанавливается значение интервала времени для таймера, а также расположение «огней». Например, пусть высота формы 350 пикселей, а высота графического окна 75 пикселей. Тогда для случая 0 (горит только красный «огонь») фрагмент процедуры следующий: Код 1.4 Select Case n Case 0 Timer1.Interval = 2500 PictureBox1.Top = PictureBox2.Top = PictureBox3.Top = PictureBox4.Top = PictureBox5.Top = ... End Select
125 225 25 350 350
'Black 'Black 'Red 'Yellow 'Green
Отчет о работе Отчет заключается в демонстрации студентом на терминале работы двух самостоятельно отлаженных проектов: 1) проекта «Приветствие»; 2) одного из двух проектов: «Секундомер» или «Светофор» (в соответствии с предложенным вариантом), работающих в режиме отладчика, а также демонстрация двух исполняемых Windows приложений, соответствующих указанным проектам.
18
Работа № 2 Примеры проектирования Windows-приложений на языке Visual Basic .NET (2005, 2008) с использованием встроенных функций: математических, финансовых, обработки строк и преобразования типов Цель работы: изучение студентами основных типов функций Visual Basic на примере создания простых Windows-приложений. В этих приложениях должны быть реализованы встроенные функции различных видов: математические, финансовые, преобразования типов данных, обработки строк. Подготовка к работе Перед выполнением работы студенту необходимо ознакомиться с литературой и материалами лекций, а также проконтролировать свои знания, ответив на следующие вопросы: 1. Назовите основные типы данных языков Visual Basic .NET, 2005, 2008 (укажите, какие из них – числовые). 2. Приведите примеры функций преобразования значения одного типа в соответствующее значение другого типа (числа в строку, строки в число, строки в целое число, в десятичное число, в дату и т.д.). 3. Назовите арифметические операции, используемые в вычисляемых арифметических выражениях языка Visual Basic. Расположите их в порядке возрастания их приоритета. 4. Какие значения возвращают функции Sin, Cos, Tan, Atn, Log, Exp, Sqr, Abs, Sgn, Rnd? 5. Приведите примеры использования функций преобразования строк (вычисление длины строки, склеивания строк, выделения подстроки, поиска в строке данной подстроки и т.д.). 6. Что представляют собой аргументы и возвращаемые значения финансовых функций Nper(rate, pmt, pv, fv, t), Rate(np, pmt, pv, fv, t), PV(rate, np, pmt, fv, t), FV(rate, np, pmt, pv, t), Pmt(rate, np, pv, fv, t)? 19
7. Что возвращает функция InputBox? Какой ее аргумент является обязательным, а какие – необязательными? 8. Какие пиктограммы и как можно устанавливать в окне MsgBox? Какие кнопки и как можно устанавливать в этом окне? Какие значения возвращает функция MsgBox? 9. Как можно определять пользовательские функции? Чем отличаются глобальные пользовательские функции (Public) от локальных (Private)? Задания В ходе выполнения данной работы студент с помощью языка Visual Basic 2005 (2008) должен выполнить три задания. 2.1. Создать проект Windows приложения, в котором используются математические функции. 2.2. Создать проект Windows приложения, в котором используются финансовые функции. 2.3. Создать проект Windows приложения, в котором используются функции обработки строк. Пример выполнения работы Задание 2.1. С помощью языка Visual Basic 2005 (2008) создать проект Windows приложения, в котором используются математические функции. Вариант 1. Создать проект приложения, в котором рассчитывается площадь треугольника по трём сторонам. Значения сторон вводятся через текстовые поля. Используется формула Герона: S = p( p − a)( p − b)( p − c) , где p – полупериметр. Вариант 2. Создать проект приложения, в котором рассчитывается площадь треугольника по координатам вершин. Координаты вводятся через текстовые поля. Используется формула: x ( y − y2 ) + x2 ( y1 − y3 ) + x3 ( y 2 − y1 ) S = Abs 1 3 . 2 20
Рассмотрим создание проекта приложения, в котором рассчитываются оценки математического ожидания и среднеквадратичного отклонения списка чисел, представленного в объекте ListBox (Окно списка) на экранной форме. На данном примере демонстрируются типы данных и арифметические функции языка Visual Basic. Окно приложения показано на рис. 2.1. Отметим, что на форме вместо командных кнопок используются команды меню. Одна из них сразу после запуска недоступна, так как дисперсию нельзя начинать оценивать, не вычислив математического ожидания. Недоступность любого элемента управления достигается установкой значения свойства Enabled данного элемента равным False (Ложь).
а б Рис. 2.1. Окно приложения (а) после загрузки и (б) после получения результата
Будем считать, что в окне списка большие по величине целые числа. Очевидно, что каждое из них может быть значением типа Integer, но не может быть значением типа Short. Но сумма этих чисел, которую надо вычислить при оценивании математического ожидания, выходит за пределы типа Integer. Поэтому в процедурах необходимо выбрать либо тип Long, либо любой тип для десятичных чисел (Single, Double). В окне списка элементы всегда считаются текстовыми (имеют тип String) Поэтому в процедурах их необходимо конвертировать в числа. В зависимости от того, какой тип чисел нами выбран, необходимо использовать ту или иную функцию преобразования типов: CInt, CLng, CSng или CDbl. Вычисленные результаты (числа) помещаются в текстовые поля. Для этого числа конвертируют в строки с помощью функции Str. Делать это не обязательно – надо лишь учитывать, что в таком случае десятичная точка превращается в десятичную запятую. 21
В данном примере список заполняется числами на этапе проектирования – с помощью свойства Items объекта ListBox1. Отметим, что это свойство является коллекцией и неоднократно используется в коде программы: Код 2.1 Imports System.Math Public Class Form1 Dim S As Long 'Integer Dim i, n As Short Dim m, d As Long 'Integer Private Sub МатОжидание_Click(ByVal sender As _ System.Object, ByVal e As _ System.EventArgs) Handles МатОжидание.Click n = ListBox1.Items.Count S = 0 For i = 0 To n - 1 S = S + CLng(ListBox1.Items.Item(i)) Next m = S \ n TextBox1.Text = m СрКвОтклонение.Enabled = True End Sub Private Sub СрКвОтклонение_Click(ByVal sender As _ System.Object, ByVal e As _ System.EventArgs) Handles СрКвОтклонение.Click d = 0 For i = 0 To n - 1 d = d + _ CLng((m - ListBox1.Items.Item(i)) ^ 2) Next d = Sqrt(d \ (n - 1)) : TextBox2.Text = d End Sub End Class
Отметим, что перед объявлением класса данной формы вставлена строка: «Imports System.Math». Эта строка позволяет использовать математические функции – в данном случае, функцию Sqrt – извлечение квадратного корня. Процедура для команды меню «Завершение» содержит единственную строку – оператор End. 22
Задание 2.2. С помощью языка Visual Basic 2005 (2008) создать проект Windows приложения, в котором используются финансовые функции. Перед формулировкой вариантов задания 2.2 рассмотрим пример создания проекта приложения, в котором реализуется действие следующих финансовых функций языка Visual Basic: • Nper(rate, pmt, pv, fv, t), • Rate(nper, pmt, pv, fv, t), • PV(rate, nper, pmt, fv, t), • FV(rate, nper, pmt, pv, t), • Pmt(rate, nper, pv, fv, t). В именах функций и их аргументов используются аббревиатуры: • NPer – число периодов (выплат), • Rate – учётная ставка (банковский процент), • PV – Present Value – инвестиция (кредит), • FV – Future Value – накопление, • Pmt – Payment – выплата. Аргумент t принимает два значения, определяющие, в начале или в конце периода (например, месяца) производится выплата. С помощью данного приложения можно решать различные задачи. Например, определять величину периодической выплаты, если известна величина кредита или инвестиции (функция Pmt), или определять величину накопления, если известна величина выплаты (функция FV). Форма приложения для решения задач с использованием указанных функций может быть такой, которая показана на рис. 2.2. Пользователь заполняет четыре из пяти текстовых полей, щёлкает одну из двух радио кнопок и одну из пяти командных кнопок – в зависимости от того, какой из пяти результатов он хочет получить. С помощью радио кнопок указывается, в начале или в конце периода (например, месяца) производится выплата. Для большей наглядности при проектировании формы использованы два элемента «Рамка». Одна из рамок обрамляет зону ввода/вывода данных, другая – командные кнопки. 23
а б Рис. 2.2. Примеры решения задач с помощью приложения «Финансовые функции»: а – после щелчка кнопки Pmt (Выплата); б – после щелчка кнопки FV (Накопление)
Рассмотрим только две из пяти процедур – для решения двух указанных выше задач: вычисления величины выплаты и вычисления значения накопления. Код 2.2 Dim r, n, v1, v2, p, t As Double Private Sub butFV_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) _ Handles butFV.Click r = CDbl(TextBox1.Text) / (100 * 12) n = CDbl(TextBox2.Text) : v1 = CDbl(TextBox3.Text) p = -CDbl(TextBox5.Text) If RadioButton1.Checked = True Then t = 1 _ 24
Else t = 0 v2 = FV(r, n, p, v1, t) TextBox4.Text = Round(v2, 2) End Sub Private Sub butPmt_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) Handles _ butPmt.Click r = CDbl(TextBox1.Text) / (100 * 12) n = CDbl(TextBox2.Text) v1 = CDbl(TextBox3.Text) v2 = CDbl(TextBox4.Text) If RadioButton1.Checked = True Then t = 1 _ Else t = 0 p = Pmt(r, n, v1, v2, t) TextBox5.Text = -Round(p, 2) End Sub
Перед объявлением класса данной формы, как и в коде 2.1, должна быть вставлена строка: «Imports System.Math», так как в процедурах используется математическая функция Round(x, n) – округление значения x до n знаков после десятичной точки. В ходе выполнения задания 2.2 студент должен дополнить программу, представленную кодом 2.2, процедурой-событием для щелчка одной из кнопок в соответствии с тремя следующими вариантами. Вариант 1. Реализовать процедуру для решения задачи определения учётной ставки (банковского процента) rate при заданных значениях числа периодов nper, выплаты pmt, а также при заданной величине кредита pv (fv = 0) или при заданной величине накопления fv (pv = 0). Вариант 2. Реализовать процедуру для решения задачи определения числа периодов nper при заданных значениях банковского процента rate, выплаты pmt, а также при заданной величине кредита pv (fv = 0) или при заданной величине накопления fv (pv = 0). Вариант 3. Реализовать процедуру для решения задачи определения величины кредита pv (fv = 0) при заданных величинах выплаты pmt, банковского процента rate и числа выплат nper. 25
Задание 2.3. С помощью языка Visual Basic 2005 (2008) создать проект Windows приложения, в котором используются функции обработки строк. Перед формулировкой вариантов задания 2.3 рассмотрим пример создания проекта приложения, в котором элементами одного из четырёх списков формы являются строки, каждая из которых – это фамилия, имя и отчество человека, записанные через пробел. Щелчком команды меню из этих строк выделяются фамилии, имена и отчества и помещаются в три отдельные списка (рис. 2.3).
Рис. 2.3. Приложение, демонстрирующее работу функций обработки строк
В данном проекте реализуется действие двух функций обработки строк языка Visual Basic: • Mid(s, k, [n]) – подстрока строки s, начинающаяся с позиции k, длиной n (n – необязательный аргумент); • Instr(s1, s2) – позиция начала подстроки s2 в строке s1. Задача решается с помощью следующей процедуры: Код 2.3 Dim i, n, k As Short Dim s1, s2, s3, s4 As String Private Sub MenuItem1_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles MenuItem1.Click n = ListBox1.Items.Count For i = 0 To n - 1 s1 = ListBox1.Items.Item(i) k = InStr(s1, " ") 26
s2 = Mid(s1, 1, k - 1) s1 = Mid(s1, k + 1) k = InStr(s1, " ") s3 = Mid(s1, 1, k - 1) s4 = Mid(s1, k + 1) ListBox2.Items.Add(s2) ListBox3.Items.Add(s3) ListBox4.Items.Add(s4) Next End Sub
В ходе выполнения задания 2.3 студент должен дополнить программу, представленную кодом 2.3, процедурой-событием для щелчка кнопки (или команды меню) в соответствии с тремя следующими вариантами. Вариант 1. Найти имя максимальной длины. Вариант 2. Найти фамилию минимальной длины. Вариант 3. Найти среднюю длину отчества. Кроме указанной кнопки (или команды меню) на форму следует поместить элемент для фиксирования результата, например, текстовое поле с соответствующей меткой над ним. Указание: В каждом из трех вариантов использовать функцию Len(s), возвращающую длину строки s. Отчет о работе Отчет заключается в демонстрации студентом на терминале работы трех самостоятельно отлаженных проектов: 1) вычисление площади треугольника; 2) использование финансовых функций; 3) использование функций обработки строк (в соответствии с предложенным вариантом). Проекты должны давать ожидаемые результаты при работе в режиме отладчика. Должна быть также представлена демонстрация трех исполняемых Windows приложений, соответствующих указанным проектам. 27
Работа № 3 Исследование графических объектов и методов языка Visual Basic .NET (2005, 2008) на примере проектирования приложения «Построение диаграмм» Цель работы: изучение возможностей графических методов языка Visual Basic .NET (2005, 2008), которые становятся доступными при использовании класса графических объектов Graphics из пространства имён System.Drawing, входящего в состав .NET Framework – ядра системы MS Visual Studio .NET (2005, 2008). Дополнительной целью работы является изучение полезных свойств и методов элемента управления ListBox на примере создания процедур меню List Editor (Редактор списка), позволяющих добавлять новые элементы в список, удалять и корректировать элементы списка. Подготовка к работе Перед выполнением работы студенту необходимо ознакомиться с литературой и материалами лекций, а также проконтролировать свои знания, ответив на следующие вопросы: 1. Как создаётся объект (экземпляр) класса Graphics, позволяющий применять графические методы к определённому элементу управления (форме, графическому окну и т.д.)? 2. Можно ли использовать один экземпляр класса Graphics для применения графических методов к нескольким элементам управления (например, к форме и к нескольким элементам PictureBox на этой форме)? 3. Как применяется тот или иной графический метод (например, DrawLine, DrawEllipse, DrawRectangle) к элементу управления, для которого создан объект (например, Графика) класса Graphics? 4. Какой вспомогательный объект необходимо определить для изображения отрезков, прямоугольников, эллипсов, дуг, секторов и т.д. с помощью методов DrawLine, DrawRectangle, DrawEllipse, DrawArc, DrawPie и т.д. без закрашивания замкнутых фигур? 28
5. Какой вспомогательный объект необходимо определить для изображения закрашенных замкнутых фигур: прямоугольников, эллипсов, секторов и т.д. с помощью методов FillRectangle, FillEllipse, FillPie и т.д.? 6. С помощью какого графического метода можно делать надписи на форме или на элементах управления (например, на объектах PictureBox), для которых создан экземпляр класса Graphics? 7. Как изобразить оси декартовых координат и напечатать значения координат возле узлов на этих осях? 8. Как повернуть вертикальную ось системы координат на элементе управления на 180° после создания для него экземпляра класса Graphics? 9. Как сместить вертикальную ось системы координат вниз (по направлению этой оси) на элементе управления на h/2 вниз (h – высота этого элемента) после создания для него экземпляра класса Graphics? И как сместить горизонтальную ось вправо на w/2 (w – ширина этого элемента)? Задания В ходе выполнения данной работы студент с помощью языка Visual Basic 2005 (2008) должен выполнить три задания. 3.1. Создать проект приложения с окном списка, в котором содержится список десятичных чисел, а также окно изображения, в котором строится круговая диаграмма, соответствующая этому списку. Для построения диаграммы создать команду меню Диаграмма. Для завершения работы приложения создать команду меню Exit. 3.2. Добавить в меню на экранной форме проекта приложения задания 1 команду Редактирование списка, содержащую команды подменю Добавить, Удалить, Вставить и Изменить в соответствии с вариантами задания. 3.3. Реализовать построение линейной и прямоугольной диаграммы в соответствии с вариантами задания. Задание 3.1 выполняется фронтально (без вариантов), задания 3.2 и 3.3 – по вариантам. 29
Пример выполнения работы В качестве примера применения графических методов рассматривается создание Windows-приложения «Построение круговых, линейных и прямоугольных диаграмм». Задание 3.1. С помощью языка Visual Basic 2005 (2008) создать проект приложения с окном списка, в котором содержится список десятичных чисел, а также окно изображения, в котором строится круговая диаграмма, соответствующая этому списку. Для построения диаграммы создать команду меню Диаграмма. Для завершения работы приложения создать команду меню Exit. Задание 3.1 выполняется фронтально – без вариантов. Ряд графических методов языка Visual Basic 2005 используется при создании проекта приложения «Построение круговой диаграммы». В первом приближении задача ставится так. Имеется список чисел в окне списка (ListBox1). В окне изображения (PictureBox1) после щелчка команды меню Диаграмма строится круговая диаграмма для этого списка так, как показано на рис. 3.1. Круговая диаграмма – это эллипс, расчерченный на закрашенные в разные цвета сектора, углы которых соответствуют числам в списке. Сектора надо рассматривать, двигаясь по часовой стрелке, начиная от оси, направленной вправо. Этап проектирования интерфейса для данного приложения рассматривать не будем, так как он не содержит новых Рис. 3.1. Окно приложения для студентов идей и понятий. «Построение круговой диаграммы» Рассмотрим лишь фрагмент кода модуля формы (код 3.1) с одной процедурой – построения круговой диаграммы: 30
Код 3.1 Public Class Form1 Dim w, h, Dw, Dh As Integer Dim i, n As Short Dim a, s, f1, f2, dx, dy As Single Dim c As Color Dim pen As New Pen(Color.Brown, 1) Private Sub Диаграмма_Click(ByVal _ sender As Object, _ ByVal e As System.EventArgs) _ Handles Диаграмма.Click Dim gr As Graphics = PictureBox1.CreateGraphics w = PictureBox1.Width : h = PictureBox1.Height dx = w / 10 : dy = h / 10 Dw = w - 2 * dx : Dh = h - 2 * dy n = ListBox1.Items.Count s = 0 For i = 0 To n - 1 a = CSng(ListBox1.Items.Item(i)) s = s + a Next gr.Clear(PictureBox1.BackColor) f1 = 0 : f2 = 0 For i = 0 To n - 1 a = CSng(ListBox1.Items.Item(i)) f1 = f1 + f2 f2 = 360 * (a / s) c = Color.FromArgb(255, _ 150 + 100 * Rnd(), 150 + 100 * Rnd(), _ 150 + 100 * Rnd()) Dim br As New SolidBrush(C) gr.FillPie(br, dx, dy, Dw, Dh, f1, f2) gr.DrawPie(pen, dx, dy, Dw, Dh, f1, f2) Next End Sub End Class
В рассмотренной процедуре сначала объявлена переменная gr как объект (экземпляр) класса Graphics, позволяющий применять графические методы к графическому окну PictureBox1. Переменные Dw и Dh – это горизонтальный и вертикальный диаметры эллипса. 31
Переменные dx и dy – это «поля» на графическом окне, чтобы эллипс не касался краёв окна. Переменная s – это сумма чисел в списке длиной n. Переменные f1 и f2 – углы, измеряемые в градусах – параметры методов FillPie и DrawPie – рисования сектора. Цвет сектора – это «случайный» цвет (переменная c) для кисти (переменная br), которая определяется в цикле для каждого сектора. Чтобы цвет был не слишком тёмным, каждая из трёх составляющих цвета получает значение 150 + 100 * Rnd(). Следующий шаг проектирования данного приложения – это ai реализация печати округленных значений ⋅ 100% на секторах ∑ ai диаграммы.
Рис. 3.2. Окно приложения с напечатанными значениями на секторах
Указанные значения печатаются на секторах с помощью графического метода DrawString путем добавления в процедуру (в тело цикла For … Next) вызова данного метода: gr.DrawString(Round(a / s * 100) & "%", Font, brs, _ (w / 2 - 15) + 0.35 * Dw * _ Cos(3.14 * (f1 + f2 / 2) / 180), _ (h / 2 - 5) + 0.35 * Dh * _ Sin(3.14 * (f1 + f2 / 2) / 180))
Числа 5, 15 и 0.35 в значениях параметров метода DrawString подобраны эмпирически – для установки нужных мест печати. 32
Напомним (см. работу № 2), что для успешной работы математических функций перед объявлением класса данной формы необходимо вставить строку Imports System.Math. Необходимо также определить особую кисть для печати – вставить в начало программы строку: Dim brs As New SolidBrush(Color.Black).
Рассмотрим теперь вопрос о редактировании списка чисел – добавлении в меню ещё одной команды: Редактировать список. Создадим для этой команды подменю с 4 командами: Добавить, Вставить, Удалить и Изменить (рис. 3.3).
Рис. 3.3. Добавление в приложение команд меню Редактировать список с подменю
Рассмотрим две из четырёх процедур для команд этого подменю: Код 3.2 Private Sub Добавить_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles Добавить.Click ListBox1.Items.Add(InputBox("Введите значение"), _ "Ввод нового элемента") End Sub Private Sub Удалить_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles Удалить.Click i = ListBox1.SelectedIndex 33
If i < 0 Then MsgBox("Выделите удаляемый элемент!", _ MsgBoxStyle.Critical) Else ListBox1.Items.RemoveAt(i) End If End Sub
Можно модернизировать выполненный проект, изменив параметры методов FillPie и DrawPie так, чтобы сектора немного сместились от центра эллипса (рис. 3.4).
Рис. 3.4. Круговая диаграмма со смещёнными центрами секторов
Для указанной модернизации следует ввести две переменные: px и py – горизонтальное и вертикальное смещение: q = 0.025 'коэффициент "разбегания" (смещения) px = q * Dw * Cos(3.14 * (f1 + f2 / 2) / 180) py = q * Dh * Sin(3.14 * (f1 + f2 / 2) / 180)
Значения 2-го и 3-го параметров указанных методов FillPie и DrawPie надо изменить на значения этих переменных: gr.FillPie(br, dx + px, dy + py, Dw, Dh, f1, f2) gr.DrawPie(pen, dx + px, dy + py, Dw, Dh, f1, f2)
Задание 3.2. Добавить в меню на экранной форме проекта приложения 1-го задания команду Редактирование списка, содержащую команды подменю Добавить, Удалить, Вставить и Изменить в соответствии с вариантами задания. 34
Вариант 1. Написать и отладить процедуру для команды подменю Вставить – включения нового элемента в список – перед выделенным элементом. Указание. Вместо метода Add, рассмотренного в коде 3.2, следует использовать метод Insert, в котором не один, а два аргумента: ListBox1.Items.Insert(i, InputBox("Введите значение", _ "Ввод нового элемента", _ ListBox1.Items.Item(i)))
(3-й аргумент функции InputBox – значение «по умолчанию».) Как и в процедуре для команды Удалить (код 3.2), необходимо предусмотреть случай, когда пользователь не выделил элемент, перед которым вставляется новое значение. Вариант 2. Написать и отладить процедуру для команды меню Изменить – замены старого значения выделенного элемента новым значением. Указание. Использовать последовательное применение двух методов: Insert (см. указание к варианту 1) и RemoveAt (см. код 3.2): ListBox1.Items.Insert(i, InputBox("Введите значение", _ "Ввод исправленного элемента", _ ListBox1.Items.Item(i))) ListBox1.Items.RemoveAt(i + 1)
Как и в процедуре для команды Удалить (код 3.2) необходимо предусмотреть случай, когда пользователь не выделил элемент, значение которого надо изменить. Задание 3.3. Реализовать построение линейной и прямоугольной диаграмм в соответствии с вариантами задания. Вариант 1. Создать проект приложения «Линейная диаграмма» (рис. 3.5), в котором применяются графические методы DrawLine и DrawRectangle. Вариант 2. Создать проект приложения «Прямоугольная диаграмма» (рис. 3.6), в котором применяются графические методы FillRectangle и DrawRectangle. 35
Рис. 3.5. Форма приложения «Линейная диаграмма»
Рис. 3.6. Форма приложения «Прямоугольная диаграмма»
Указание. Для более естественного представления диаграмм целесообразно перенести начало координат вниз и перевернуть направленную вниз ось ординат: dx = w / (n + 2) dy = 0.1 * h gr.ScaleTransform(1, -1) gr.TranslateTransform(dx, -h + dy)
Кроме того здесь проведено масштабирование: • длина оси абсцисс составляет теперь (n + 2) условных единиц. 36
• длина оси ординат устанавливается в зависимости от значе-
ния переменной max – максимального числа в списке чисел, которое надо найти перед циклическим рисованием отрезков (линейная диаграмма) или прямоугольников (прямоугольная диаграмма). На каждом шаге этого циклического процесса: 1) изображение очередного отрезка (в случае линейной диаграммы) строится следующим образом: x2 = (0.5 + i) * dx y2 = CSng(ListBox1.Items.Item(i)) y2 = y2 * (0.8 * h / max) gr.DrawLine(pen, x1, y1, x2, y2) gr.DrawLine(pens.Black, x2, 0, x2, y2) x1 = x2 : y1 = y2
2) изображение очередного прямоугольника (в случае прямоугольной диаграммы) строится следующим образом: x1 = i * dx : y1 = 0 dy = CSng(ListBox1.Items.Item(i)) dy = dy * (0.8 * h / max) gr.FillRectangle(br, x1, y1, dx, dy) gr.DrawRectangle(pen, x1, y1, dx, dy)
Как и для круговой диаграммы (код 3.1) кисть br надо определять на каждом шаге цикла, чтобы закрашивать прямоугольники разными случайными цветами: c = Color.FromArgb(255, _ 150 + 100 * Rnd(), 150 + 100 * Rnd(), _ 150 + 100 * Rnd()) Dim br As New SolidBrush(c)
Для большей выразительности можно сделать прямоугольное обрамление – как у линейной, так и у прямоугольной диаграммы: gr.DrawRectangle(pen, 0, 0, _ w - 2 * dx, h - 2 * dy + 5)
Дополнение к заданию 3.3. Реализовать печать значений: ai ⋅ 100% на диаграммах в соответствии с вариантом. ∑ ai 37
Изображения диаграмм с напечатанными на них указанными значениями показаны на рис. 3.7.
а б Рис. 3.7. Печать значений в окне изображения приложения: «Линейная диаграмма» (а) и «Прямоугольная диаграмма» (б)
Фрагмент кода для варианта 1: gr.ScaleTransform(1, -1) For i = 0 To n - 1 a = CSng(ListBox1.Items.Item(i)) a = Round(100 * a / s) gr.DrawString(a & "%", Font, brs, _ dx * (0.5 + i) - 10, 2) Next
Фрагмент кода для варианта 2: gr.ScaleTransform(1, -1) For i = 0 To n - 1 a = CSng(ListBox1.Items.Item(i)) a = Round(100 * a / s) gr.DrawString(a & "%", Font, brs, dx * i, 0) Next
Отметим, что в данных фрагментах вертикальная ось, перевернутая для построения линейной или прямоугольной диаграммы в традиционной системе координат, опять переворачивается с помощью строки: gr.ScaleTransform(1, -1). Это делается для того, чтобы печатаемые на диаграмме символы (цифры и знак «%») не изображались перевернутыми. 38
Отчет о работе Отчет заключается в демонстрации студентом на терминале работы самостоятельно отлаженного проекта «Построение диаграмм» (в соответствии с предложенным вариантом каждого из трех заданий). Проект должен давать ожидаемые результаты при работе в режиме отладчика. Должна быть также представлена демонстрация исполняемого Windows приложения, соответствующего указанному проекту.
39
Работа № 4 Исследование графических объектов и методов 2D-графики языка Visual Basic .NET (2005, 2008) на примере проектирования приложений «Построение графиков функций» и «Построение сложных фигур» Цель работы: изучение возможностей реализации двумерной (2D) графики с помощью графических объектов и методов языка VB .NET (2005, 2008) на примере проектирования двух приложений «Построение графиков функций» и «Построение сложных фигур». В ходе проведения работы исследуется полезный класс графических объектов – Drawing2D из пространства имён System. Drawing, входящего в состав .NET Framework – ядра системы Visual Studio .NET (2005, 2008). Подготовка к работе Перед выполнением работы студенту необходимо ознакомиться с литературой и материалами лекций, а также проконтролировать свои знания, ответив на следующие контрольные вопросы: 1. Что представляют собой графические объекты-структуры Point (точка), Rectangle (прямоугольник), Size (размер)? К какому пространству имён они принадлежат? Приведите примеры графических методов, в которых они используются. 2. Как с помощью метода Inflate можно изменять размеры изображаемых прямоугольников и эллипсов? 3. Для каких графических методов необходим объект Brush (графическая кисть)? Как определить новую кисть? 4. Какие графические объекты используются в качестве двух аргументов графического метода DrawString? 5. Как с помощью графического метода DrawString можно напечатать на некотором объекте ряд чисел? Как напечатать эти числа разными цветами и/или разными шрифтами? 40
6. Как импортируется двумерная графика (Drawing2D) для того, чтобы на форме или на элементах управления (например, на объектах PictureBox) изображать многогранники, кривые линии, проходящие через заданное множество точек, и т.д.? Какие графические методы становятся доступными для этого? 7. Что представляют собой объекты двумерной графики LinearGradientBrush (линейная градиентная кисть) и HatchBrush (штрихованная кисть)? Задания В ходе выполнения данной работы студенту необходимо выполнить три задания. 4.1. Создать и отладить проект Windows приложения «Построение графиков функций в декартовой системе координат». 4.2. Создать и отладить проект Windows приложения «Построение графиков функций в полярной системе координат». 4.3. Создать и отладить проект Windows приложения «Построение изображений геометрических тел». Проекты создать в системе проектирования Visual Studio 2005 на языке Visual Basic 2005. Для каждого из проектов скомпилировать исполняемый файл приложения. Пример выполнения работы Задание 4.1. Создать и отладить проект Windows приложения «Построение графиков функций в декартовой системе координат». Рассмотрим приложение «Построение графиков функций». На рис. 4.1 показан результат работы данного приложения при выборе одной из трёх математических функций. Перечень формул для всех трёх функций демонстрируется во «фрейме» – элементе класса GroupBox в левой части формы. Каждой формуле соответствует элемент RichTextBox, в который загружается файл формата rtf (созданный в редакторе MS Word) с 41
данной формулой – при старте приложения. Справа от указанных элементов – радиокнопки, с помощью которых выбирается та или иная функция. При этом автоматически, «по умолчанию», в текстовые поля вносятся подходящие для выбранной функции значения параметров a1, a2 и a3.
Рис. 4.1. Форма приложения «Построение графиков функций», работающего в режиме построения синусоиды
График функции строится на объекте класса PictureBox (в графическом окне). В данном приложении четыре команды меню: Сетка, Оси, График и Exit (завершение работы). Продемонстрируем этапы разработки проекта приложения для построения графика только одной функции – синусоиды: y = sin(x). Этап создания интерфейса – это установка на форме указанных элементов: двух элементов GroupBox, трех полей RichTextBox и трех обычных текстовых полей TextBox, трех радиокнопок RadioButton, графического окна PictureBox, а также элементов MenuStrip и OpenFileDialog для команд меню и для открытия файлов с формулами. 42
Более подробно рассмотрим этап построения программного кода – процедур загрузки формы, построения сетки и координатных осей (две команды меню) и графика функции – ещё одной команды меню. 1. Загрузка формы. На этом этапе устанавливаются значения ширины w и высоты h графического окна в пикселях. Для большей наглядности предусматривается выделение более тёмным цветом каждой пятой линии сетки – для этого вводятся переменные nw и nh. 2. Рисование сетки. Рисование линий сетки – это циклическое применение метода DrawLine: два цикла для светлых линий (вертикальных и горизонтальных) пером pen1 и два цикла для более редких тёмных линий (вертикальных и горизонтальных) пером pen2. Для масштабирования окна (изменения направления оси y и перенесения начала координат в центр окна) используются методы: gr.ScaleTransform(1, -1) и gr.TranslateTransform(w / 2, -h / 2). 3. Рисование координатных осей. Чтобы оси выглядели стрелками с заострёнными концами используется 2D-свойство пера: pen3.EndCap = LineCap.ArrowAnchor. Печать чисел вдоль осей координат необходимо проводить только после «обратного масштабирования»: gr.ScaleTransform(1, -1) и gr.TranslateTransform(-w / 2, -h / 2). Иначе числа будут напечатами перевёрнутыми. Для печати используется метод DrawString. 4. Рисование графика функции. Используется метод DrawCurve, аргументом которого является массив точек pp(np), где np – ширина окна в пикселях. Этот метод позволяет рисовать кривую линию, проходящую через заданные точки. Координаты точек pp(i).X и pp(i).Y вычисляются в цикле For x = -w / 2 To w / 2. Код модуля формы следующий: Код 4.1 Imports System.Drawing.Drawing2D Imports System.Math Public Class Form1 Dim w, h, nw, nh, x, y As Integer 43
Dim Dim Dim Dim Dim Dim Dim Dim Dim
i, np As Short gr As Graphics pp() As Point pen1 As New Pen(Color.FromArgb(255, 200, 200, 200)) pen2 As New Pen(Color.FromArgb(255, 150, 150, 150)) pen3 As New Pen(Color.FromArgb(255, 220, 180, 180), 5) penG As New Pen(Color.FromArgb(255, 50, 50, 200), 2) a1, a2, a3 As Double brs As New SolidBrush(Color.Black)
_ _ _ _
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load w = 400 : h = 300 PictureBox1.Width =w : PictureBox1.Height = h nw = w / 10 : nh = h / 10 End Sub Private Sub Сетка_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles СеткаToolStripMenuItem.Click gr = PictureBox1.CreateGraphics gr.Clear(PictureBox1.BackColor) gr.ScaleTransform(1, -1) gr.TranslateTransform(w / 2, -h / 2) For i = -nw To nw gr.DrawLine(pen1, i * 10, -nh * 10, _ i * 10, nh * 10) Next For i = -nh To nh gr.DrawLine(pen1, -nw * 10, i * 10, _ nw * 10, i * 10) Next For i = -nw / 5 To nw / 5 gr.DrawLine(pen2, i * 50, -nh * 50, _ i * 50, nh * 50) Next For i = -nh / 5 To nh / 5 gr.DrawLine(pen2, -nw * 50, i * 50, _ nw * 50, i * 50) Next End Sub 44
Private Sub Оси_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles ОсиToolStripMenuItem.Click gr.ScaleTransform(1, -1) gr.TranslateTransform(-w / 2, -h / 2) pen3.EndCap = LineCap.ArrowAnchor gr.DrawLine(pen3, 5, h \ 2, w - 5, h \ 2) gr.DrawLine(pen3, w \ 2, h - 5, w \ 2, 5) For i = 0 To w Step 50 gr.DrawString(i - w / 2, Font, brs, i, h / 2) Next For i = 0 To h Step 50 gr.DrawString(h / 2 - i, Font, brs, w / 2, i) Next End Sub Private Sub График_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) _ Handles ГрафикToolStripMenuItem.Click gr = PictureBox1.CreateGraphics gr.ScaleTransform(1, -1) gr.TranslateTransform(w / 2, -h / 2) a1 = Val(TextBox1.Text) a2 = Val(TextBox2.Text) a3 = Val(TextBox3.Text) np = w ReDim pp(np) i = 0 For x = -w / 2 To w / 2 y = a1 * Sin(a2 * x + a3) pp(i).X = x : pp(i).Y = y i = i + 1 Next gr.DrawCurve(penG, pp, 0) End Sub
Варианты задания 4.1. В обоих вариантах создать проект приложения для рисования синусоиды, описанный в задании 4.1, а также расширить этот проект – добавить возможность выбора функции. В соответствии с вариантом реализовать выбор одной новой функции и построение графика этой функции (рис. 4.2 и 4.3). Вариант 1. Парабола – график функции y = a1 x 2 + a2 x + a3 . 45
Рис. 4.2. Окно проекта с двумя графиками параболы (a1 = 0,01, a2 = ±1, a3 = –50)
Вариант 2. Гипербола – график функции y =
a1 + a3 . x − a2
Рис. 4.3. Окно проекта с двумя графиками гиперболы (a1 = 2000, a2 = ±50, a3 = 30)
Указания. 1. Для выбора функции использовать радиокнопки. Например: Private Sub RadioButton1_Click1(ByVal _ sender As Object, _ 46
ByVal e As System.EventArgs) _ Handles RadioButton1.Click TextBox1.Text = "120" TextBox2.Text = "0.025" TextBox3.Text = "1.57" nf = 1 End Sub
В процедуре рисования графика функции График_Click следует использовать оператор Select Case для выбора того графика, который имеет номер nf. 2. Для загрузки формулы в поле RichТextBox использовать процедуру RichТextBox_Click – щелчок этого поля. Например: Private Sub RichTextBox1_Click(ByVal _ sender As Object, _ ByVal e As System.EventArgs) _ Handles RichTextBox1.Click OpenFileDialog1.Filter = "RTF-файлы|*.RTF" OpenFileDialog1.ShowDialog() RichTextBox1.LoadFile(OpenFileDialog1.FileName) End Sub
3. Для рисования гиперболы следует использовать не один массив, а два массива точек, учитывая, что функция имеет разрыв при x = a2: np = w / 2 + a2 ReDim pp(np - 1) i = 0 For x = -w / 2 To a2 - 1 y = a1 / (x - a2) + a3 pp(i).X = x : pp(i).Y = y i = i + 1 Next gr.DrawCurve(penG, pp, 0) np = w / 2 - a2 ReDim pp(np - 1) i = 0 For x = a2 + 1 To w / 2 y = a1 / (x - a2) + a3 pp(i).X = x : pp(i).Y = y i = i + 1 Next gr.DrawCurve(penG, pp, 0) 47
Задание 4.2. Создать и отладить проект Windows приложения «Построение графиков функций в полярной системе координат». Рассмотрим особенности проектирования приложения «Рисование графиков функций, определяемых в полярных координатах» на примере рисования спирали – графика функции r = af + b , где f > 0 и f < 2πk. Экранная форма приложения – на рис. 4.4.
Рис. 4.4. Форма приложения для рисования функций в полярных координатах в случае выбора спирали
Фрагмент программного кода для модуля формы следующий: Код 4.2 Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles Me.Load PictureBox1.Width = 400 PictureBox1.Height = 400 w = PictureBox1.Width / 2 48
h = PictureBox1.Height / 2 End Sub Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click gr = PictureBox1.CreateGraphics gr.ScaleTransform(1, -1) gr.TranslateTransform(w, -h) gr.Clear(PictureBox1.BackColor) m = w : d = 10 For i = -m To m Step d gr.DrawLine(pen1, m, i, -m, i) gr.DrawLine(pen1, i, m, i, -m) Next i gr.DrawLine(Pens.Red, -m, 0, m, 0) gr.DrawLine(Pens.Red, 0, -m, 0, m) a = 3 : b = 50 s = 0.05 For f = 0 To 10 * PI Step s r1 = a * f + b r2 = a * (f + s) + b p1.X = r1 * Cos(f) p1.Y = r1 * Sin(f) p2.X = r2 * Cos(f + s) p2.Y = r2 * Sin(f + s) gr.DrawLine(pen2, p1, p2) Next f gr.ScaleTransform(1, -1) gr.TranslateTransform(-w, -h) gr.DrawString(" a = " & a, Font, br, 0, 10) gr.DrawString(" b = " & b, Font, br, 0, 30) gr.DrawString(" fmin = 0", Font, br, 0, 50) gr.DrawString(" fmax = " & "10 * Pi", _ Font, br, 0, 70) End Sub
Комментарий. Для рисования графиков используется метод кусочно-линейной аппроксимации – на каждом шаге цикла построения графика две соседние точки графика соединяются отрезком: r1 = … (значение функции в точке f) r2 = … (значение функции в точке f + s) p1.X = r1 * Cos(f) p1.Y = r1 * Sin(f) p2.X = r2 * Cos(f + s) 49
p2.Y = r2 * Sin(f + s) gr.DrawLine(pen, p1, p2)
Объявления переменных в начале модуля здесь не приводятся (в том числе «графических перьев» pen1, pen2 и «кисти» br). Отметим лишь, что первый аргумент в графическом методе DrawLine – это «графическое перо», а остальные аргументы должны иметь тип Point (если их два) или тип Integer (если их четыре). Переменные s, f, fp1 и fp2 должны иметь тип Double. Варианты задания 4.2. Вариант 1. Создать проект приложения «Рисование графика функции в полярной системе координат» – на примере рисования спирали (пример 4.2) r = af + b , где f > 0 и f < 2πk. Значения параметров a, b, fmin и fmax должны отличаться от тех значений, которые рассматривались в начале задания 4.2 (см. рис. 4.4). Вариант 2. Создать проект приложения «Рисование графика функции в полярной системе координат» – на примере рисования π 3a cos f sin f , где f > arctg( − 1) и f < + arctg ( −1) функции r = 3 3 2 cos f + sin f («лепесток Декарта»). Экранная форма приложения – на рис. 4.5. Указание. Процедуру щелчка кнопки Нарисовать для построения «Декартова листа» следует скопировать с процедуры для рисования спирали, заменив фрагмент циклического построения кусочно-линейной аппроксимации для спирали следующим фрагментом: a = 100 : s = 0.05 fp1 = Atan(-1) + 10 / a ' Правее предельного значения на s/a fp2 = PI / 2 - Atan(-1) - 10 / a ' Левее предельного значения на s/a For f = fp1 To fp2 Step s r1 = 3 * a * Sin(f) * Cos(f) / _ (Sin(f) ^ 3 + Cos(f) ^ 3) r2 = 3 * a * Sin(f + s) * Cos(f + s) / _ (Sin(f + s) ^ 3 + Cos(f + s) ^ 3) p1.X = r1 * Cos(f) p1.Y = r1 * Sin(f) 50
p2.X = r2 * Cos(f + s) p2.Y = r2 * Sin(f + s) gr.DrawLine(pen3, p1, p2) Next f gr.DrawLine(pen2, -2 * a, a, a, -2 * a)
Последняя строка – рисование асимптоты y = -x – 100. Печать числовых характеристик здесь не приводится.
Рис. 4.5. Форма приложения для рисования функций в полярных координатах при выборе «лепестка Декарта»
Задание 4.3. Создать и отладить проект Windows приложения «Построение изображений геометрических тел». Рассмотрим особенности проектирования приложения «Рисование геометрических тел» на примере рисования прямых четырёхугольных призм (прямых параллелепипедов) с окрашенными гранями. Форма приложения показана на рис. 4.6. 51
Рис. 4.6. Форма приложения для изображений прямых прямоугольных призм
Комментарий. Сначала с помощью радиокнопки RadioButton1 во фрейме «Геометрическое тело» выбирается «Призма». При этом появляется диалоговое окно ColorDialog1 – выбора цвета. Этот цвет затем помещается в качестве фонового (BackColor) в окно TextBox1. (Остальные радиокнопки здесь не используются – они предназначены для рисования изображений цилиндров в задании 4.3). Затем заполняются текстовые поля с номерами 2 – 8 во фрейме «Параметры». Это необходимые размеры изображения призмы, смысл которых должен быть ясен по приведённому рисунку (они соответствуют призме, нарисованной справа). Напомним, что оси координат направлены из левого верхнего угла графического поля – «по умолчанию». После установки всех значений щёлкается команда меню Изобразить. Фрагмент программного кода, относящийся к рисованию призмы, процедуры Изобразить_Click следующий: 52
Код 4.3 h0 = Val(TextBox4.Text) w1 = Val(TextBox5.Text) h1 = Val(TextBox6.Text) w2 = Val(TextBox7.Text) h2 = Val(TextBox8.Text) x = Val(TextBox2.Text) + w1 y = Val(TextBox3.Text) + h1 + h2 + h0 Dim Brc1 As New SolidBrush(c1) Dim Brc2 As New SolidBrush(c2) Dim Brc3 As New SolidBrush(c3) ' Построение изображения верхней стороны призмы: pathc1.AddLine(x, y - h0, _ x - w1, y - h0 - h1) pathc1.AddLine(x - w1, y - h0 - h1, _ x - w1 + w2, y - h0 - h1 - h2) pathc1.AddLine(x - w1 + w2, _ y - h0 - h1 - h2, x + w2, y - h0 - h2) pathc1.AddLine(x + w2, y - h0 - h2, x, y pathc1.CloseFigure() gr.FillPath(Brc1, pathc1) ' Построение изображения левой стороны призмы: pathc2.AddLine(x, y, x - w1, y - h1) pathc2.AddLine(x - w1, y - h1, _ x - w1, y - h1 - h0) pathc2.AddLine(x - w1, y - h1 - h0, x, y pathc2.AddLine(x, y - h0, x, y) pathc2.CloseFigure() gr.FillPath(Brc3, pathc2) ' Построение изображения правой стороны призмы: pathc3.AddLine(x, y, x, y - h0) pathc3.AddLine(x, y - h0, x + w2, y - h0 pathc3.AddLine(x + w2, y - h0 - h2, x + w2, y - h2) pathc3.AddLine(x + w2, y - h2, x, y) pathc3.CloseFigure() gr.FillPath(Brc2, pathc3)
h0)
h0)
h2) _
Комментарий. В данном проекте используется двумерная графика. Применяется метод «замкнутых фигур». Эти фигуры заполняются тем или иным цветом. Фигура строится последовательным добавлением отрезков и дуг в объект, который называется «маршрутом». Здесь используются три маршрута: pathc1, pathc2 и pathc3. Они определяются так: 53
Dim pathc1, pathc2, pathc3 As New Drawing2D.GraphicsPath
Замкнутые фигуры заполняются цветом путём применения к указанным маршрутам метода CloseFigure. В коде 4.3 для закрашивания указанных фигур - четырёхугольников призмы (одной верхней и двух боковых граней) - используются 3 цвета. Значения более тёмного цвета c2 и более светлого цвета c3 получаются программно из цвета c1, выбираемого пользователем с помощью окна диалога ColorDialog: a = 200 ' Прозрачность цвета. r1 = c1.R : g1 = c1.G : b1 = c1.B c1 = Color.FromArgb(a, r1, g1, b1) ' Создание более тёмного тона данного цвета: r2 = r1 - 50 : If r2 < 0 Then r2 = 0 g2 = g1 - 50 : If g2 < 0 Then g2 = 0 b2 = b1 - 50 : If b2 < 0 Then b2 = 0 c2 = Color.FromArgb(a, r2, g2, b2) ' Создание более светлого тона данного цвета: r3 = r1 + 50 : If r3 > 255 Then r3 = 255 g3 = g1 + 50 : If g3 > 255 Then g3 = 255 b3 = b1 + 50 : If b3 > 255 Then b3 = 255 c3 = Color.FromArgb(a, r3, g3, b3)
Разумеется, в начале программы необходимо определить переменные для самих цветов и для их составляющих: Dim c1, c2, c3 As Color Dim a, r1, g1, b1, r2, g2, b2, r3, g3, b3 As Integer
Варианты задания 4.3. В обоих вариантах создать проект приложения, назначение которого – рисование изображений «цветных полупрозрачных цилиндров». Взять за основу проект приложения, рассмотренного в примере выполнения задания 4.3. Вариант 1. Создать проект приложения «Рисование изображения стоящих на своих основаниях (вертикальных) цилиндров с окрашенными сторонами» (рис. 4.7). Вариант 2. Создать проект приложения «Рисование изображения лежащих на боковых сторонах (горизонтальных) цилиндров с окрашенными сторонами» (рис. 4.8).
54
а б Рис. 4.7. Форма приложения для рисования вертикально расположенных цилиндров – вид сверху (а) и вид снизу (б)
а б Рис. 4.8. Форма приложения для рисования горизонтально расположенных цилиндров – вид слева (а) и вид справа (б)
Рассмотрим, как устанавливаются значения параметров вертикально расположенных цилиндров (вариант 1). Аналогично эта задача решается и в варианте 2. 1. Как и при выполнении основного задания 4.3, здесь следует преобразовать значения, полученные из текстовых полей: h0 = Val(TextBox4.Text) w1 = Val(TextBox5.Text) / 2 h1 = Val(TextBox6.Text) / 2 w2 = Val(TextBox7.Text) / 2 h2 = Val(TextBox8.Text) / 2 x = Val(TextBox2.Text) + w1 y = Val(TextBox3.Text) + h1 + h0 55
2. Как и при выполнении основного задания 4.3, здесь необходимо использовать двумерную графику, в частности, метод «замкнутых фигур». Здесь эти фигуры заполняются цветом не равномерно, а с помощью градиентной кисти. Эта кисть помогает изменять цвет фигуры – изображение боковой грани цилиндра – от светлого до тёмного: ' Построение изображения верхней стороны _ ' (основания) цилиндра: Dim Brc As New SolidBrush(c1) gr.FillEllipse(Brc, x - w1, y - h0 - h1, _ 2 * w1, 2 * h1) ' Построение изображения боковой стороны цилиндра: pathc1.AddArc(x - w1, y - h0 - h1, _ 2 * w1, 2 * h1, 0, 180) pathc1.AddLine(x - w1, y - h0, x - w1, y) pathc1.AddArc(x - w1, y - h1, _ 2 * w1, 2 * h1, 0, 180) pathc1.AddLine(x + w1, y, x + w1, y - h0) pathc1.CloseFigure() ' Закрашивание изображения боковой стороны _ ' цилиндра градиентной кистью: p1.X = x - w1 - 1 : p2.X = x + w1 + 1 p1.Y = y + h0 / 2 : p2.Y = y + h0 / 2 Dim Brcg As New _ LinearGradientBrush(p1, p2, c3, c2) gr.FillPath(Brcg, pathc1)
Отчет о работе
Отчет заключается в демонстрации студентом на терминале работы трёх самостоятельно отлаженных проектов: «Построение графиков функций в декартовых координатах», «Построение графиков функций в полярных координатах» и «Построение изображений геометрических тел» (в соответствии с предложенным вариантом каждого из трех заданий). Проекты должны давать ожидаемые результаты при работе в режиме отладчика. Должна быть также представлена демонстрация исполняемых Windows приложений, соответствующих трём указанным проектам. 56
Работа № 5 Использование особенностей процедур-событий языка VB .NET, применяемых к множествам элементов управления при создании приложений типа «Калькулятор» и «Шахматная доска» Цель работы: изучение возможностей языка Visual Basic .NET (2005, 2008), позволяющих создавать компактные проекты приложений, которые содержат большие множества элементов, выполняющих примерно одну и ту же функцию (например, кнопки с цифрами и арифметическими действиями на панели «Калькулятора»). Подготовка к работе
Перед выполнением работы студенту необходимо ознакомиться с литературой и материалами лекций, а также проконтролировать свои знания, ответив на следующие контрольные вопросы: 1. Как выглядит заголовок процедуры-события для щелчка командной кнопки? Какая часть этого заголовка указывает на объект (конкретную кнопку), к которой применяется это действие? Можно ли установить несколько объектов (командных кнопок) для одной такой процедуры? 2. Каковы аргументы процедуры-события для щелчка командной кнопки? К каким классам они относятся? 3. Как в тексте процедуры-события (например, для процедуры-события Form1_MouseDown) можно обратиться к тому или иному свойству конкретного объекта, указанного в заголовке, к которому применяется это действие? Например, к свойству Text или Tag объекта Form1? Какой аргумент процедуры надо использовать для этого? 4. Как в тексте процедуры-события (например, для процедурысобытия Form1_MouseDown) можно обратиться к тому или иному свойству данного события? Например, к свойству X или Y – коор57
динатам указателя мыши? Какой аргумент процедуры надо использовать для этого? 5. Как объявить одномерный или двумерный массив объектов, если заранее не известно их число? 6. Можно ли применять действие процедуры-события к объектам, которые представлены массивом? Задания
В ходе выполнения данной работы студенту необходимо выполнить три задания. 5.1. Создать и отладить проект Windows приложения «Калькулятор, управляемый мышью». Данное задание выполняется фронтально – без вариантов. 5.2. Модернизировать проект Windows приложения «Калькулятор, управляемый мышью», заменив все кнопки на форме единственной кнопкой, нажатие которой вызывает появление кнопок приложения, построенного в результате выполнения первого задания. 5.3. Создать и отладить проект Windows приложения «Рисование шахматной доски». Проекты создаются в системе проектирования Visual Studio 2005 на языке Visual Basic 2005. Для каждого из проектов скомпилировать исполняемый файл приложения. Задание 5.1 выполняется фронтально (без вариантов); задания 5.2 и 5.3 – по вариантам. Пример выполнения работы
Во всех примерах данной работы подчеркивается, что использование спецификации Handles в заголовках процедур-событий и массивов элементов управления позволяет существенно сократить объем программного кода, а именно: использовать только одну процедуру-событие вместо множества таких процедур. Задание 5.1. Создать и отладить проект Windows приложения «Калькулятор, управляемый мышью». 58
Рассмотрим проект приложения «Калькулятор», на панели которого видны сразу три поля с числовыми значениями: два поля для операндов выбранной пользователем арифметической операции (сложения, вычитания, умножения и деления) и одно поле для результата. Особенность данного приложения – это запрет на использование клавиатуры для ввода знаков в текстовые поля. В силу этого ограничения приложение может быть названо так: «Калькулятор, управляемый мышью» или «Мышиный калькулятор». Для имитации «светящихся ЖК экранов» цвет фона этих полей желательно сделать чёрным, цвет символов – например, зелёным. Значение свойства TextAlign следует установить равным Right, чтобы числа вводились так, как это принято в «карманных» калькуляторах. Вид панели работающего «Калькулятора» показан на рис. 5.1.
Рис. 5.1. Вид панели «Калькулятора» после выполнения операции деления
Выбор пользователем одного из двух текстовых полей для ввода удобно делать с помощью щелчка одной из двух радиокнопок с надписями N1 и N2. Значения операндов должны вводиться только с помощью щелчков мышью командных кнопок на панели калькулятора (без помощи клавиатуры), поэтому значение свойства ReadOnly всех трёх текстовых полей должно быть установлено равным True (Истина). Это заблокирует пользователю возможность вводить символы с помощью клавиатуры. 59
Следует разместить на форме 20 командных кнопок: • для ввода цифр от 0 до 9 (10 кнопок); • для ввода знаков, необходимых для представления десятичных чисел: запятой «,», символа «Е», знаков «+» и «-» (4 кнопки); • кнопки Backspace – для удаления последнего неудачно введенного символа (1 кнопка); • кнопки Clear – для очистки всех трёх текстовых полей операндов и результата (1 кнопка); • для выполнения арифметических действий (4 кнопки). Перечисленные кнопки и текстовые поля удобно разместить внутри объектов GroupBox (фреймов), которые являются контейнерами – их перемещение и удаление вызывает перемещение и удаление содержимого этих фреймов. Координаты расположения кнопок «по умолчанию» берутся относительно контейнеров, в которых они находятся. Это станет удобным, когда будет решаться задача создания и расположения кнопок автоматически. (Эта задача будет решаться в рамках данной работы.) Разработку проекта данного приложения следует начинать с этапа «ручного» построения формы – размещения на ней всех необходимых элементов управления: трех фреймов (Group Boxes), 20и командных кнопок, трех текстовых полей, двух радиокнопок и одной метки «Результат». В последних версиях систем проектирования MS Visual Studio (2005, 2008) программисту предоставляются удобные средства для быстрого и качественного размещения на форме многочисленных однородных объектов, которые должны располагаться ровными «рядами и колоннами». Освоение этих средств – дело техники. Особый интерес представляет этап разработки программного кода. Для большей лаконичности сократим имена кнопок и текстовых полей – заменим значения их свойства (Name) на следующие: • b0, b1, …, b9 – кнопки с цифрами; • z1, …, z4 – кнопки со знаками «,», «Е», «+», «-»; • u1, u2 – кнопки управления; • d1, …, d4 – копки арифметических действий; • r1, r2 – радиокнопки; 60
• t1, t2, t3 – текстовые поля. При создании процедур проекта данного приложения ограничимся рассмотрением всего двух массивов элементов управления: • массивом N(1)текстовых полей для операндов (2 элемента); • массивом R(1) радиокнопок (Radio Buttons) для фиксации ввода одного из двух чисел (2 элемента). Значение переменной i – это номер операнда или значение индекса соответствующего массива (0 или 1). Щелчок той или другой радиокнопки будет присваивать этой переменной соответствующее значение. Объявление переменной и указанных двух массивов, а также процедуры загрузки формы, двух кнопок управления u1 (очистки всех текстовых полей) и u2 (удаление неудачно введённого символа) следующие: Код 5.1 Public Class Dim i As Dim N(1) Dim R(1)
Form1 Short As TextBox As RadioButton
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load N(0) = t1 : N(1) = t2 R(0) = r1 : R(1) = r2 i = 0 R(0).Checked = True End Sub Private Sub Clear_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) Handles u1.Click N(0).Text = "" : N(1).Text = "" : t3.Text = "" End Sub Private Sub Back_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles u2.Click Dim s As String s = N(i).Text If Len(s) > 0 Then N(i).Text = _ Mid(s, 1, Len(s) - 1) End Sub 61
Основная «изюминка» программы проекта данного приложения – в использовании только одной процедуры для ввода любого из 14 символов – десяти цифр и четырёх других знаков. (Кнопки для ввода этих символов расположены в 1-м фрейме.) Также только одна процедура создаётся и для всех четырёх кнопок арифметических действий. Аналогично только одна процедура – для двух радиокнопок. Код 5.2 демонстрирует три указанные процедуры. Код 5.2 Private Sub b_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles _ b0.Click, b1.Click, b2.Click, b3.Click, _ b4.Click, b5.Click, b6.Click, b7.Click, _ b8.Click, b9.Click, _ z1.Click, z2.Click, z3.Click, z4.Click N(i).Text = N(i).Text & sender.Text End Sub Private Sub D_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles _ d1.Click, d2.Click, d3.Click, d4.Click Dim n1, n2, Res As Double If N(0).Text = "" Then N(0).Text = "0" If N(1).Text = "" Then N(1).Text = "0" n1 = CDbl(N(0).Text) : n2 = CDbl(N(1).Text) Select Case sender.Tag Case 0 : Res = n1 + n2 Case 1 : Res = n1 - n2 Case 2 : Res = n1 * n2 Case 3 : Res = n1 / n2 End Select t3.Text = Res End Sub Private Sub RadioButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles _ r1.Click, r2.Click i = sender.Tag End Sub
Отметим важное обстоятельство: две последние процедуры используют свойство Tag объектов d1, d2, d3 и d4, а также объектов 62
r1 и r2. Значения этого свойства должны быть установлены заранее на этапе проектирования формы. Задание 5.2. Модернизировать проект Windows приложения «Калькулятор, управляемый мышью», заменив все кнопки на форме единственной кнопкой, нажатие которой вызывает появление кнопок приложения, построенного в результате выполнения задания 5.1. Рассмотрим создание проекта приложения «Массив командных кнопок», на панели которого после его старта – только одна командная кнопка и объект GroupBox. Щелчок этой кнопки вызывает «рождение» и построение в строгом порядке тринадцати кнопок, предназначенных для вычисления соответствующих степеней введённого пользователем числа q. Последовательное появление окон в процессе работы данного приложения показано на рис. 5.2–5.5.
Рис. 5.2. Окно приложения сразу после старта
Рис. 5.3. Окно ввода пользователем основания степени 63
Рис. 5.4. Окно приложения с автоматически созданными кнопками
Рис. 5.5. Окно сообщения после щелчка одной из «новых» кнопок
При написании кода проекта данного приложения следует помнить, что в объявлении создаваемых кнопок необходимо использовать ключевое слово WithEvents, без которого эти кнопки не смогут участвовать в событиях. Код проекта приложения следующий: Код 5.3 Public Class Form1 Dim WithEvents B0, B1, B2, B3, B4, B5, B6, B7, _ B8, B9, B10, B11, B12 As New Button Dim C(,) As Button Const m As Integer = 3 Const n As Integer = 4 Const w As Integer = 128 Const h As Integer = 32 Const x0 As Integer = 32 Const y0 As Integer = 16 Const d As Integer = 8 Dim i, j, k As Integer Dim q As Double 64
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load GroupBox1.Width = d * (m + 1) + w * m GroupBox1.Height = d * (n + 5) + h * (n + 1) GroupBox1.Left = x0 : GroupBox1.Top = y0 Me.Width = GroupBox1.Width + 2 * x0 + d Me.Height = GroupBox1.Height + 4 * y0 + d End Sub Private Sub B_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles B0.Click, B1.Click, B2.Click, _ B3.Click, B4.Click, B5.Click, B6.Click, _ B7.Click, B8.Click, B9.Click, B10.Click, _ B11.Click, B12.Click MsgBox(q & "^" & sender.tag & " = " & _ q ^ sender.Tag, _ MsgBoxStyle.Information, "Вычисление степени числа") End Sub Private Sub But1_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click q = InputBox("Введите основание степени q", _ "q^k", "987654321") B0.Width = w : B0.Height = h B0.Left = d + (w + d) B0.Top = 4 * d B0.Text = q & "^" & 0 B0.Tag = 0 GroupBox1.Controls.Add(B0) ReDim C(m - 1, n - 1) For j = 0 To n - 1 For i = 0 To m - 1 C(i, j) = New Button C(i, j).Width = w : C(i, j).Height = h C(i, j).Left = d + i * (w + d) C(i, j).Top = 4 * d + (j + 1) * (h + d) k = i + j * m + 1 C(i, j).Text = q & "^" & k C(i, j).Tag = k GroupBox1.Controls.Add(C(i, j)) Next Next B1 = C(0, 0) : B2 = C(1, 0) : B3 = C(2, 0) 65
B4 = C(0, 1) : B5 = C(1, 1) : B6 = C(2, 1) B7 = C(0, 2) : B8 = C(1, 2) : B9 = C(2, 2) B10 = C(0, 3) : B11 = C(1, 3) : B12 = C(2, 3) Button1.Visible = False End Sub End Class
Варианты задания 5.2. Оба варианта задания 5.2 должны использовать модернизированную форму приложения «Калькулятор», показанную на рис. 5.6.
Рис. 5.6. Приложение «Калькулятор» после запуска – перед созданием кнопок и других элементов управления
Вариант 1. Написать программный код – фрагмент процедуры щелчка кнопки, показанной на рис. 5.6. Щелчок кнопки должен вызывать автоматическое создание в первом фрейме 16 кнопок: • для ввода цифр от 0 до 9, • для ввода других знаков («,», «Е», «+», «-»), • кнопок управления Clear и Backspace. Результат показан на рис. 5.7. Вариант 2. Написать программный код – как фрагмент процедуры щелчка кнопки, показанной на рис. 5.6. Щелчок кнопки должен вызывать автоматическое создание во втором и в третьем фреймах текстовых полей (3 поля), радиокнопок (2 кнопки) и кнопок арифметических действий (4 кнопки). Результат показан на рис. 5.8. 66
Рис. 5.7. Приложение «Калькулятор» после щелчка единственной кнопки по варианту 1 задания 2
Рис. 5.8. Приложение «Калькулятор» после щелчка единственной кнопки по варианту 2 задания 2
Указания (к обоим вариантам). 1. Взять за основу выполнение задания 5.2, в котором рассматривается автоматическое создание во фрейме на экранной форме множества новых командных кнопок, каждая из которых должна решать собственную задачу. 2. Использовать код задания 5.1. В этот код следует внести объявление пока не существующих объектов на форме (код 5.4). Следует обратить внимание на то, что для новых объектов в коде класса формы определены процедуры-события, поэтому при объявлении этих объектов следует использовать ключевое слово WithEvents. 67
Код 5.4 Dim WithEvents b0, b1, b2, b3, b4, _ b5, b6, b7, b8, b9, _ z1, z2, z3, z4, u1, u2, _ d1, d2, d3, d4 As New Button Dim L As New Label Dim WithEvents r1, r2 As New RadioButton Dim t1, t2, t3 As New TextBox Dim i As Short Dim N(1) As TextBox Dim R(1) As RadioButton
3. Для выполнения каждого из двух вариантов можно воспользоваться частью приведенного ниже «объединенного» кода 5.5 для процедуры B_Click – щелчка кнопки с именем B. Код 5.5
Private Sub B_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles B.Click Dim w, h, p, x0, y0 As Integer w = 56 : h = 24 : p = 5 : x0 = 10 : y0 = 20 b0.Left = x0 + w + p : b0.Top = y0 b0.Width = w : b0.Height = h : b0.Text = "0" b1.Left = x0 : b1.Top = y0 + h + p b1.Width = w : b1.Height = h : b1.Text = "1" b2.Left = x0 + w + p : b2.Top = y0 + h + p b2.Width = w : b2.Height = h : b2.Text = "2" b3.Left = x0 + 2 * (w + p) b3.Top = y0 + h + p b3.Width = w : b3.Height = h : b3.Text = "3" b4.Left = x0 : b4.Top = y0 + 2 * (h + p) b4.Width = w : b4.Height = h : b4.Text = "4" b5.Left = x0 + w + p b5.Top = y0 + 2 * (h + p) b5.Width = w : b5.Height = h : b5.Text = "5" b6.Left = x0 + 2 * (w + p) b6.Top = y0 + 2 * (h + p) b6.Width = w : b6.Height = h : b6.Text = "6" b7.Left = x0 : b7.Top = y0 + 3 * (h + p) b7.Width = w : b7.Height = h : b7.Text = "7" b8.Left = x0 + w + p b8.Top = y0 + 3 * (h + p) b8.Width = w : b8.Height = h : b8.Text = "8" b9.Left = x0 + 2 * (w + p) 68
b9.Top = y0 + 3 * (h + p) b9.Width = w : b9.Height = h : b9.Text z1.Left = x0 + 3 * (w + p) + 4 * p z1.Top = y0 z1.Width = w : z1.Height = h : z1.Text z2.Left = x0 + 3 * (w + p) + 4 * p z2.Top = y0 + h + p z2.Width = w : z2.Height = h : z2.Text z3.Left = x0 + 3 * (w + p) + 4 * p z3.Top = y0 + 2 * (h + p) z3.Width = w : z3.Height = h z3.Text = "+" z4.Left = x0 + 3 * (w + p) + 4 * p z4.Top = y0 + 3 * (h + p) z4.Width = w : z4.Height = h : z4.Text u1.Left = 3 * x0 u1.Top = 2 * y0 + 4 * (h + p) u1.Width = 2 * w u1.Height = h : u1.Text = "Clear" u2.Left = 3 * x0 + 2 * w + p u2.Top = 2 * y0 + 4 * (h + p) u2.Width = 2 * w : u2.Height = h u2.Text = "Backspace" GroupBox1.Controls.Add(b0) GroupBox1.Controls.Add(b1) GroupBox1.Controls.Add(b2) GroupBox1.Controls.Add(b3) GroupBox1.Controls.Add(b4) GroupBox1.Controls.Add(b5) GroupBox1.Controls.Add(b6) GroupBox1.Controls.Add(b7) GroupBox1.Controls.Add(b8) GroupBox1.Controls.Add(b9) GroupBox1.Controls.Add(z1) GroupBox1.Controls.Add(z2) GroupBox1.Controls.Add(z3) GroupBox1.Controls.Add(z4) GroupBox1.Controls.Add(u1) GroupBox1.Controls.Add(u2) t1.Left = x0 : t1.Top = y0 t1.Width = 4 * w : t1.Height = h t1.BackColor = Color.Black t1.ForeColor = Color.LightGreen t2.Left = x0 : t2.Top = y0 + h + p t2.Width = 4 * w : t2.Height = h t2.BackColor = Color.Black 69
= "9" = "," = "E"
= "-"
t2.ForeColor = Color.LightGreen t3.Left = x0 : t3.Top = y0 + 2 * (h + p) t3.Width = 4 * w : t3.Height = h t3.BackColor = Color.Black t3.ForeColor = Color.LightGreen t1.TextAlign = HorizontalAlignment.Right t2.TextAlign = HorizontalAlignment.Right t3.TextAlign = HorizontalAlignment.Right r1.Left = x0 + 4 * w + p : r1.Top = y0 r1.Width = w : r1.Height = h : r1.Text = "N1" r2.Left = x0 + 4 * w + p : r2.Top = y0 + h + p r2.Width = w : r2.Height = h : r2.Text = "N2" r1.Tag = 0 : r2.Tag = 1 L.Left = x0 + 4 * w + p L.Top = y0 + 2 * (h + p) L.Width = 1.5 * w : L.Text = "Результат" GroupBox2.Controls.Add(t1) GroupBox2.Controls.Add(t2) GroupBox2.Controls.Add(t3) GroupBox2.Controls.Add(r1) GroupBox2.Controls.Add(r2) GroupBox2.Controls.Add(L) d1.Left = 5 * x0 : d1.Top = y0 d1.Width = w : d1.Height = h d1.Text = "N1+N2" d2.Left = 5 * x0 + w + p : d2.Top = y0 d2.Width = w : d2.Height = h d2.Text = "N1-N2" d3.Left = 5 * x0 + 2 * (w + p) : d3.Top = y0 d3.Width = w : d1.Height = h d3.Text = "N1*N2" d4.Left = 5 * x0 + 3 * (w + p) : d4.Top = y0 d4.Width = w : d2.Height = h d4.Text = "N1/N2" d1.Tag = 0 : d2.Tag = 1 d3.Tag = 2 : d4.Tag = 3 GroupBox3.Controls.Add(d1) GroupBox3.Controls.Add(d2) GroupBox3.Controls.Add(d3) GroupBox3.Controls.Add(d4) B.Visible = False Me.BackColor = _ Color.FromArgb(255, 200, 200, 200) End Sub
70
Задание 5.3. Создать и отладить проект Windows приложения «Рисование шахматной доски». Рассмотрим создание приложения «Шахматная доска». Щелчок единственной командной кнопки на форме после запуска приложения (рис. 5.9, а) должен приводить к «исчезновению» этой кнопки и появлению на форме новых меток (объектов Label) – 64-х клеток «шахматной доски» (рис. 5.9, б).
а б Рис. 5.9. Форма приложения после старта (а) и после щелчка кнопки (б)
Код приложения (код 5.6) содержит объявления динамического массива меток cell(,), всех необходимых констант и переменных, а также процедуру для щелчка единственной кнопки на форме. Код 5.6 Public Class Form1 Dim cell(,) As Label Const n As Integer = 8 Const w As Integer = 25 : Const h As Integer = 25 Const p As Integer = 10 Dim i, j As Short Dim c1, c2 As Color Dim bc As String Private Sub B_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) _ 71
Handles B.Click Me.Width = 2 * p + w * n + 8 Me.Height = 2 * p + h * n + 32 c1 = Color.FromArgb(255, 255, 255, 192) _ ' светло-жёлтый цвет. c2 = Color.FromArgb(255, 128, 64, 0) _ ' тёмно-коричневый цвет. Button1.Visible = False ReDim cell(n - 1, n - 1) For j = 0 To n - 1 For i = 0 To n - 1 cell(i, j) = New Label cell(i, j).Width = w : cell(i, j).Height = h cell(i, j).Left = p + i * w cell(i, j).Top = p + j * h cell(i, j).BorderStyle = BorderStyle.Fixed3D If (i + j) Mod 2 = 0 Then cell(i, j).BackColor = c1 cell(i, j).ForeColor = c2 Else cell(i, j).BackColor = c2 cell(i, j).ForeColor = c1 End If Me.Controls.Add(cell(i, j)) Next Next End Sub End Class
Варианты задания 5.3. Оба варианта задания должны использовать форму приложения «Шахматная доска» (см. рис. 5.9) произвольного размера с единственной командной кнопкой, имеющей имя B, а также код процедуры B_Click для щелчка этой кнопки (код 5.6). Этот код должен быть дополнен операторами для нумерации клеток шахматной доски. Вариант 1. Клетки пронумеровать так, как показано на рис. 5.10, а. Вариант 2. На клетки нанести обозначения, принятые у шахматистов, как показано на рис. 5.10, б. Указания (к обоим вариантам). 1. В теле внутреннего цикла необходимо установить значение свойства cell(i, j).Text очередной метки – клетки «шахмат72
ной доски». При этом цвет символов на клетках должен быть следующим: тёмные символы на светлом фоне и светлые символы на тёмном фоне (например, жёлтые символы на коричневом фоне и коричневые символы на жёлтом фоне).
а б Рис. 5.10. Форма с «шахматной доской» для 1-го (а) и для 2-го (б) вариантов
2. Необходимо ввести две новые переменные: k – для «сквозной» нумерации клеток; bc – для нумерации, принятой у шахматистов. Значение каждой из этих двух переменных на каждом шаге цикла должно вычисляться в соответствии с кодом 5.7. Код 5.7 k = i + j * n Select Case i Case 0 : bc Case 1 : bc Case 2 : bc Case 3 : bc Case 4 : bc Case 5 : bc Case 6 : bc Case 7 : bc
+ 1 = = = = = = = =
"a" "b" "c" "d" "e" "f" "g" "h"
& & & & & & & &
8 8 8 8 8 8 8 8
-
j j j j j j j j
73
End Select cell(i, j).Text = k cell(i, j).Text = bc
' Вариант 1. ' Вариант 2.
Отчет о работе
Отчет заключается в демонстрации студентом на терминале работы трёх самостоятельно отлаженных проектов: «Калькулятор», «Калькулятор с единственной кнопкой» и «Шахматная доска». Проекты должны давать ожидаемые результаты при работе в режиме отладчика. Должна быть также представлена демонстрация исполняемых Windows приложений, соответствующих трём указанным проектам.
74
Работа № 6 Использование программных массивов для обработки большого числа однотипных данных (на примере одномерного и двумерного массивов) Цель работы: изучение и использование понятия программного массива как обобщения понятия переменной при программировании процедур на языке Visual Basic .NET (2005, 2009), создание проектов, в программных модулях которых целесообразно использовать одномерные и многомерные программные массивы. Подготовка к работе
Перед выполнением работы студенту необходимо ознакомиться с литературой и материалами лекций, а также проконтролировать свои знания, ответив на следующие контрольные вопросы: 1. Как объявляется одномерный массив? Что такое индекс массива и диапазон изменения индекса? 2. Как можно находить максимальный (или минимальный) элемент массива чисел? Значение индекса максимального (или минимального) элемента? 3. В чем заключается идея «пузырьковой» сортировки одномерного массива чисел? 4. Приведите примеры алгоритмов сортировки одномерного массива более эффективных, чем алгоритм «пузырьковой» сортировки. 5. В чем заключается идея двумерного (дихотомического) поиска элемента в отсортированном массиве? Как зависит число шагов двумерного поиска от длины массива? 6. Как с помощью двумерного массива можно хранить и обрабатывать матрицу значений функции двух переменных f(x, y)? 7. Как можно использовать понятие динамического массива для загрузки в двумерный массив значений цвета «точек» произвольного изображения? 75
8. Какой объект следует объявить и использовать при обработке изображения с целью дальнейшего сохранения этого изображения в файле графического формата? Задания
В ходе выполнения данной работы студенту необходимо выполнить три задания (по вариантам). 6.1. Создать и отладить проект Windows приложения «Сортировка массива». 6.2. Создать и отладить проект Windows приложения «Быстрый поиск в отсортированном массиве методом дихотомии». 6.3. Создать и отладить проект Windows приложения «Обработка изображения как двумерного массива пикселей». Проекты создаются в системе проектирования Visual Studio 2005 на языке Visual Basic 2005. Для каждого из проектов скомпилировать исполняемый файл приложения. Пример выполнения работы Задание 1. Создать и отладить проект Windows приложения «Сортировка массива». Рассмотрим приложение, демонстрирующее «пузырьковую» сортировку одномерного массива элементов, которыми являются даты рождения. Для определенности будем считать, что даты в этом массиве находятся в диапазоне от 1 января 1971 г. до 31 декабря 1980 г. (в интервале, равном 10 годам). На рис 6.1 показано окно приложения, на котором два поля списка и три команды меню: Генерация списка дат, Сортировка, Выход. Щелчок 1-й команды вызывает заполнение 1-го поля случайными датами, а щелчок 2-й команды – заполнение 2-го поля этими датами, отсортированными по возрастанию. Число n задаётся пользователем с помощью окна ввода, которое появляется после щелчка 1-й команды. 76
Рис. 6.1. Результат генерации заданного числа дат (здесь n = 5000) и «пузырьковой» сортировки массива этих дат
Даты создаются случайно с помощью рандомизации – оператора Randomize и функции Rnd. Идея генерации списка дат заключается в следующем. Сначала с помощью функции DateDiff необходимо определить, сколько дней в указанном интервале: Y = DateDiff("Y", CDate(d1), CDate(d2)) + 1 ' Y = 3653 – число дней в интервале ' с 1.1.1971 г. по 31.12.1980 г.
Затем в цикле от i = 0 до n – 1, с помощью функции DateAdd необходимо создать n элементов массива – случайных дат: d(i) = DateAdd("Y", Y * Rnd(), CDate(d1))
Программный код класса данной формы следующий: Код 6.1 Public Class Form1 Const d1 As String = "1.1.71" Const d2 As String = "31.12.80" Dim Y, i, j, n As Integer Dim d0, d() As Date Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load ListBox1.Items.Clear() 77
ListBox2.Items.Clear() Y = DateDiff("Y", CDate(d1), CDate(d2)) + 1 Randomize() End Sub Private Sub ГенерацияСпискаДат_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles ГенерацияСпискаДат.Click ListBox1.Items.Clear() : ListBox2.Items.Clear() n = CInt(InputBox("Введите число дат", _ "Ввод длины массива", 5000)) ReDim d(n - 1) For i = 0 To n - 1 ListBox1.Items.Add(DateAdd("Y", Y * Rnd(), _ CDate(d1))) d(i) = CDate(ListBox1.Items.Item(i)) Next End Sub Private Sub Сортировка_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles Сортировка.Click For i = 0 To n - 2 For j = i To n - 1 If d(j) < d(i) Then d0 = d(i) : d(i) = d(j) : d(j) = d0 End If Next Next For i = 0 To n - 1 ListBox2.Items.Add(d(i)) Next End Sub End Class
Замечание. Результат сравнения двух дат, которое происходит во внутреннем цикле процедуры сортировки методом «пузырька», отличается от результата лексикографического сравнения строк, представляющих эти даты. Для сортировки строк (например, имён или фамилий), которые помещаются в поле списка, нет необходимости применять тот или иной метод сортировки – достаточно установить значение свойства Sorted этого поля равным True (Истина). 78
Варианты задания 6.1. В обоих вариантах задания 6.1 использовать форму, представленную в примере выполнения задания 6.1. Необходимо лишь заменить рассмотренную в этом примере процедуру сортировки методом «пузырька» другой процедурой, в которой используется иной метод сортировки – в соответствии с вариантом. Вариант 1. Использовать метод сортировки с помощью поиска в массиве максимального (или минимального) элемента. Вариант 2. Использовать метод сортировки с помощью вставки «головы» списка (первого элемента) в отсортированный «хвост» этого списка. (Процедура для данного метода является рекурсивной.) Задание 6.2. Создать и отладить проект Windows приложения «Быстрый поиск в отсортированном массиве методом дихотомии». Рассмотрим приложение «Быстрый поиск в отсортированном массиве», которое демонстрирует метод, известный как «дихотомия» – последовательное разбиение массива на две равные части и сравнение элемента, находящегося в точке разбиения, с искомым элементом. 1. Рассмотрим сначала массив «русских фамилий» строкового типа. Форма работающего приложения показана на рис. 6.2.
Рис. 6.2. Экран приложения «Быстрый поиск в одномерном массиве» с результатом: значением порядкового номера (индекса) фамилии «Васильев» и протоколом поиска 79
На форме одно текстовое поле. В него пользователь вводит фамилию, для которой он хочет найти значение её порядкового номера (индекса). Это так называемый «поисковый запрос». На форме есть также два фрейма: в левом – исходный список фамилий; в правом – два списка с результатами поиска. В первом из них формируется главный результат поиска – значение индекса данной фамилии в отсортированном массиве фамилий. Во втором фиксируются все шаги поиска. Список этих шагов образуют так называемый «протокол» процесса поиска. Есть на форме ещё один, невидимый вспомогательный список с именем РусскиеФамилии, содержащий 100 распространённых русских фамилий. Этот список необходим для генерации массива фамилий произвольной длины. Можно взять за основу, например, следующий список: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
Абрамов Александров Алексеев Алексеев Алехин Алешин Антонов Афанасьев Борин Борисов Валентинов Ванин Варфоломеев Васильев Васильев Вениаминов Викторов Владимиров Володин Ганин Глебов Григорьев Гришин Давыдов Данилов
26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50.
Демин Дмитриев Евграфов Евстигнеев Егоров Зиновьев Иванов Иванов Иванов Иванов Иванов Ильин Ильин Клементьев Климов Константинов Костин Лавров Лазарев Леонтьев Манин Маринин Марьин Михайлов Михайлов
51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75.
Михеев Мишин Никодимов Николаев Николаев Никонов Олегов Онуфриев Павлов Павлов Панин Панин Пантелеев Петров Петров Петров Петров Пронин Пронин Прошин Родионов Романов Ромин Семин Сергеев
76. Сидоров 77. Сидоров 78. Сонин 79. Степанов 80. Терентьев 81. Тимофеев 82. Титов 83. Тихонов 84. Томин 85. Трофимов 86. Ульянов 87. Фадеев 88. Федоров 89. Федоров 90. Филимонов 91. Филиппов 92. Фомин 93. Фомин 94. Харитонов 95. Харламов 96. Юрьев 97. Юрьин 98. Яковлев 99. Яковлев 100. Яшин
Некоторые фамилии в этом списке повторяются, чтобы при рандомизации они встречались чаще (например, фамилия «Иванов»). 80
После старта приложения массив фамилий создаётся с помощью команды меню Генератор слов. Число элементов этого массива, равное числу элементов исходного списка, пользователь задаёт на этапе загрузки формы с помощью окна ввода. После срабатывания команды Генератор слов она должна стать недоступной. Затем выполняется команда Сортировка. В данном случае элементы массива – это данные строкового типа, поэтому для его сортировки достаточно присвоить свойству Sorted окна списка с исходными данными значение True (Истина), а потом в цикле заполнить этот массив. Только после этого пользователь вносит интересующую его фамилию в поле поискового запроса и щёлкает команду Поиск. Код 6.2 содержит процедуры для всех перечисленных этапов работы данного приложения. Код 6.2 Public Class Form1 Dim w, a() As String Dim n, k, i, j, imin, imax, limit As Integer Dim d As Double Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load n = InputBox("Ведите число слов", _ "Объём массива", "100") ReDim a(n - 1) РусскиеФамилии.Visible = False End Sub Private Sub ГенераторСлов_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) _ Handles ГенераторСлов.Click Randomize() For i = 0 To n - 1 w = РусскиеФамилии.Items.Item(CInt(Rnd() * _ (РусскиеФамилии.Items.Count - 1))) If Rnd() > 0.75 Then w = w & "а" ' Женщин будет только 25% ИсходныйСписок.Items.Add(w) Next ГенераторСлов.Enabled = False End Sub 81
Private Sub Сортировка_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles Сортировка.Click ИсходныйСписок.Sorted = True For i = 0 To n - 1 a(i) = ИсходныйСписок.Items.Item(i) Next End Sub Private Sub Поиск_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Поиск.Click ПротоколПоиска.Items.Clear() imin = 0 : imax = n + 1 i = n - 1 : k = 0 k = 0 limit = Math.Log(n) / Math.Log(2) + 1 Do Until k > limit i = (imax + imin) \ 2 If i > n - 1 Then _ РезультатПоиска.Items.Add("Нет") : Exit Sub ПротоколПоиска.Items.Add(Format(k + 1, "00") _ & ":" & Format(i, "0000")) k = k + 1 If a(i) > ИскомыйЭлемент.Text Then imax = i ElseIf a(i) < ИскомыйЭлемент.Text Then imin = i Else Exit Do End If Loop If k <= limit Then РезультатПоиска.Items.Add(Format(i, "0000") & _ ":" & ИсходныйСписок.Items.Item(i)) Else РезультатПоиска.Items.Add("Нет") End If End Sub End Class
2. Можно вместо списка фамилий сгенерировать список дат – так, как было сделано в примере выполнения задания 6.1. Форма изменённого приложения будет выглядеть, как показано на рис. 6.3. 82
Рис. 6.3. Пример бинарного (быстрого) поиска заданной даты
Для перехода от фамилий к датам необходимо несколько откорректировать начало процедуры для команды Поиск: Код 6.3 Dim dx As Date dx = CDate(ИскомыйЭлемент.Text) ПротоколПоиска.Items.Clear() imin = 0 : imax = n + 1 i = n - 1 : k = 0 k = 0 limit = Math.Log(n) / Math.Log(2) + 1 Do Until k > limit i = (imax + imin) \ 2 If i > n - 1 Then _ РезультатПоиска.Items.Add("Нет") : Exit Sub ПротоколПоиска.Items.Add(Format(k + 1, "00") & _ ":" & Format(i, "0000")) k = k + 1 If d(i) > dx Then imax = i ElseIf d(i) < dx Then imin = i Else Exit Do End If Loop 83
Варианты задания 6.2. Оба варианта данного задания предполагают, во-первых, отладку проекта задания 6.2 и, во-вторых, дополнение процедуры бинарного поиска дополнительной возможностью получения всех значений индекса для повторяющихся значений фамилии (или даты). С этой целью необходимо сделать «вставку» в код процедуры для команды меню Поиск. Вариант 1. Найти все индексы (а не только один из индексов) для заданной фамилии – так, как показано на рис. 6.4.
Рис. 6.4. Пример бинарного поиска всех индексов для заданной фамилии
Вариант 2. Найти все индексы (а не только один из индексов) для заданной даты – так, как показано на рис. 6.5.
Рис. 6.5. Пример бинарного поиска всех индексов для заданной даты 84
Указание. Необходимо просмотреть элементы массива a(…) – фамилий, или массива d(…) – дат, которые предшествуют найденному элементу, и добавить их индексы в результат, если они совпадают с найденным элементом: j = i - 1 If j < 0 Then Exit Sub Do While d(j) = dx 'или a(j) = ИскомыйЭлемент.Text РезультатПоиска.Items.Add(Format(j, "0000") _ & ":" & ИсходныйСписок.Items.Item(j)) j = j - 1 If j < 0 Then Exit Sub Loop
Также необходимо просмотреть элементы массива a(…) – фамилий, или d(…) – дат, следующие за найденным элементом, и добавить их индексы в результат, если они совпадают с найденным элементом: j = i + 1 If j >= n Then Exit Sub Do While d(j) = dx 'или a(j) = ИскомыйЭлемент.Text РезультатПоиска.Items.Add(Format(j, "0000") _ & ":" & ИсходныйСписок.Items.Item(j)) j = j + 1 If j >= n Then Exit Sub Loop
Задание 6.3. Создать и отладить проект Windows приложения «Обработка изображения как двумерного массива пикселей». Рассмотрим приложение, которое демонстрирует возможность использования двумерного динамического массива для хранения «точек» растрового изображения произвольного размера с целью его обработки. В данном приложении рассматриваются следующие виды обработки: • преобразование данного цветного изображения в чёрно-белое изображение; • получение негативного изображения; • построение изображения, симметричного данному изображению относительно вертикальной оси; 85
• построение изображения, симметричного данному изображению относительно горизонтальной оси; • построение увеличенного изображения; • построение уменьшенного изображения. Под «точкой» изображения в данном случае понимается цвет отдельного пикселя этого изображения с заданными координатами. На рис. 6.6 показано окно данного приложения после построения негативного изображения. Идея проектирования данного приложения заключается в следующем. На языке Visual Basic .NET (2005, 2008) можно создать и использовать особый виртуальный графический объект, например, с именем Page1, который является «bmp-копией» файла произвольного графического формата. Вместо графического файла можно воспользоваться значением свойства Image объекта класса PictureBox: Dim Page1 As Bitmap Page1 = New Bitmap(PictureBox1.Image)
Рис. 6.6. Окно приложения в процессе работы – после построения негативного изображения и рисования результата
С помощью двойного цикла и метода GetPixel языка VB .NET данный объект может быть «отсканирован» – цвет каждого его 86
пикселя с координатами (x, y) может быть помещён в двумерный массив c(x, y) типа Color (Цвет): For y … For x … c(x, y) = Page1.GetPixel(x, y) Next Next
Цвет каждой точки изображения – каждый элемент массива c(x, y) – может быть программно изменён в соответствии с тем,
какое преобразование выбрано. Этот изменённый цвет записывается в точку с координатами (x, y) другого виртуального объекта – например, с именем Page2 – с помощью метода SetPixel. Этот объект создаётся следующим образом: Dim Page2 As Bitmap Page2 = New Bitmap(PictureBox2.Width, _ PictureBox2.Height)
Рассмотрим преобразование в негативное изображение. Оно реализуется следующим образом: For y … For x … cp = c(x, y) a = cp.A : r = cp.R : g = cp.G : b = cp.B cp = Color.FromArgb(a, 255 - r, 255 - g, 255 - b) Page2.SetPixel(x, y, cp) Next Next
На рис. 6.7 показана форма приложения на этапе проектирования – при построении меню. Меню содержит четыре команды. После загрузки формы (старта приложения) команда Загрузить массив должна быть доступна, а две следующие команды – Обработать изображение и Нарисовать – должны быть недоступными. После загрузки массива первая и вторая команды обмениваются значениями «доступности» (значением свойства Enabled). Но команда Нарисовать остаётся пока недоступной. 87
Рис. 6.7. Форма приложения на этапе проектирования
Объявление переменных и две процедуры (загрузки формы и загрузки массива точек изображения) приведены в коде 6.4. Код 6.4 Public Class Form1 Dim w0, h0, w, h, x, y As Integer Dim Page1, Page2 As Bitmap Dim gr As Graphics Dim cp, c(,) As Color Dim grey, a, r, g, b As Integer Dim k As Single Dim p As String Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load w0 = Me.Width h0 = Me.Height w = PictureBox1.Width - 1 h = PictureBox1.Height - 1 ReDim c(w, h) Page1 = New Bitmap(PictureBox1.Image) ОбработатьИзображение.Enabled = False Нарисовать.Enabled = False End Sub
88
Private Sub ЗагрузитьМассив_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles ЗагрузитьМассив.Click For y = 0 To h For x = 0 To w c(x, y) = Page1.GetPixel(x, y) Next Next ОбработатьИзображение.Enabled = True ЗагрузитьМассив.Enabled = False End Sub
Рассмотрим процедуры для команды меню Обработать изображение, четырёх команд подменю: Черно-белое, Негативное, Увеличенное и Уменьшенное, а также команды меню Нарисовать (код 6.5). Процедуры для команд подменю Слева-направо и Сверху-вниз в данном примере не рассматриваются. Щелчок команды Обработать изображение вызывает не только появление подменю, показанного на рис. 6.7, но и меняет размеры как самой формы, так и окна изображения PictureBox2, на котором будет впоследствии нарисовано новое изображение. Кроме того, создается новый виртуальный объект Page2, в котором будет создаваться это изображение. Размеры объекта Page2 «подгоняются» под размеры окна изображения PictureBox2. Эта же процедура делает доступной команду меню Нарисовать. Щелчок каждой из команд подменю включает соответствующую процедуру обработки изображения, в результате работы которой формируется содержимое виртуального объекта Page2. Завершается этот процесс присвоением строковой переменной p одного из значений: «черно-белое», «негативное», «увеличенное», «уменьшенное» и т.д. Эти значения будут учитываться в дальнейшем, после щелчка команды меню Нарисовать. Код 6.5 Private Sub ОбработатьИзображение_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) _ Handles ОбработатьИзображение.Click
89
Me.Width = w0 Me.Height = h0 PictureBox2.Width = w + 1 PictureBox2.Height = h + 1 Page2 = New Bitmap(PictureBox2.Width, _ PictureBox2.Height) ОбработатьИзображение.Enabled = False Нарисовать.Enabled = True End Sub Private Sub ЧёрноБелое_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles ЧёрноБелое.Click For y = 0 To h For x = 0 To w cp = c(x, y) a = cp.A : r = cp.R : g = cp.G : b = cp.B grey = (r + g + b) / 3 cp = Color.FromArgb(a, grey, grey, grey) Page2.SetPixel(x, y, cp) Next Next MsgBox("Черно-белое - на Page2") p = "черно-белое" End Sub Private Sub Негативное_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles Негативное.Click For y = 0 To h For x = 0 To w cp = c(x, y) a = cp.A r = cp.R g = cp.G b = cp.B cp = Color.FromArgb(a, _ 255 - r, 255 - g, 255 - b) Page2.SetPixel(x, y, cp) Next Next MsgBox("Негативное - на Page2") p = "негативное" End Sub
90
Private Sub Увеличенное_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles Увеличенное.Click k = InputBox("Введите значение k", _ "Ввод коэффициента увеличения", 1.5) Me.Width = w0 + (k - 1) * w Me.Height = h0 + (k - 1) * h PictureBox2.Width = k * (w + 1) PictureBox2.Height = k * (h + 1) For y = 0 To h For x = 0 To w Page2.SetPixel(x, y, c(x, y)) Next Next MsgBox("На Page2 - копия Page1") p = "увеличенное" End Sub Private Sub Уменьшенное_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles Уменьшенное.Click k = InputBox("Введите значение k", _ "Ввод коэффициента уменьшения", 0.5) PictureBox2.Width = k * (w + 1) PictureBox2.Height = k * (h + 1) For y = 0 To h For x = 0 To w Page2.SetPixel(x, y, c(x, y)) Next Next MsgBox("На Page2 - копия Page1") p = "уменьшенное" End Sub Private Sub Нарисовать_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles Нарисовать.Click Select Case p Case "негативное", "черно-белое" gr = PictureBox2.CreateGraphics
91
gr.Clear(PictureBox2.BackColor) For y = 0 To h For x = 0 To w cp = Page2.GetPixel(x, y) Dim br As New SolidBrush(cp) gr.FillRectangle(br, x, y, 1, 1) Next Next Case "увеличенное", "уменьшенное" gr = PictureBox2.CreateGraphics gr.Clear(PictureBox2.BackColor) For y = 0 To h For x = 0 To w cp = Page2.GetPixel(x, y) Dim br As New SolidBrush(cp) gr.FillRectangle(br, _ k * x, k * y, k, k) Next Next End Select Нарисовать.Enabled = False ОбработатьИзображение.Enabled = True End Sub
Пример результата работы процедур построения негативного изображения (команда подменю Негативное) и рисования полученного результата (команда меню Нарисовать) показан на рис. 6.6. Примеры результата работы процедур построения увеличенного и уменьшенного изображения (команды подменю Увеличенное и Уменьшенное) и рисования полученного результата (команда меню Нарисовать) показаны на рис. 6.8 и 6.9. Варианты задания 6.3. Вариант 1. Написать процедуру команды Слева-направо – 3-й команды подменю, показанного на рис. 6.6. Вариант 2. Написать процедуру команды Сверху-вниз – 4-й команды подменю, показанного на рис. 6.6.
92
Рис. 6.8. Окно приложения после построения увеличенного изображения и рисования результата
Рис. 6.9. Окно приложения после построения уменьшенного изображения и рисования результата 93
Изображения, которые должны получиться в результате работы процедур варианта 1 и варианта 2, показаны на рис. 6.10.
Рис. 6.10. Результат преобразования «слева-направо» и «сверху-вниз»
Указания. 1. В обоих вариантах необходимо внести необходимые коррективы в процедуру для команды меню Нарисовать – учесть новые значения переменной p. 2. Использовать следующие «заготовки» для процедур: Private Sub СлеваНаправо_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles СлеваНаправо.Click <Строки процедуры Варианта 1> MsgBox("Зеркальное (слева-направо) - на Page2") p = "слева-направо" End Sub Private Sub СверхуВниз_Click(ByVal sender _ As System.Object, _ ByVal e As System.EventArgs) _ Handles СверхуВниз.Click <Строки процедуры Варианта 2> MsgBox("Зеркальное (сверху-вниз) - на Page2") p = "сверху-вниз" End Sub
94
Отчет о работе
Отчет заключается в демонстрации студентом на терминале работы трёх самостоятельно отлаженных проектов: «Сортировка массива», «Быстрый поиск в отсортированном массиве методом дихотомии» и «Обработка изображения как двумерного массива пикселей». Проекты должны давать ожидаемые результаты при работе в режиме отладчика. Должна быть также представлена демонстрация исполняемых Windows приложений, соответствующих трём указанным проектам.
95
Список рекомендуемой литературы 1. Лукин С.Н. Понятно о Visual Basic .NET. Самоучитель. М.: ДИАЛОГ-МИФИ, 2005. 2. Хальворсон М. Visual Basic .NET. Русская версия. Серия «Шаг за шагом». Практ. пособие. М.: СП ЭКОМ, 2004. 3. Богданов М.Р. Visual Basic 2005 на примерах. СПб.: БХВПетербург, 2007.
96