Файл: Справочник для опытных и как пособие для начинающих программистов. Компактдиск содержит исходные коды примеров из книги.doc

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.01.2024

Просмотров: 924

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


// Размеры изображения в точках:

int Width = 136; int Height = 40;

// Создаем точечный рисунок:

Bitmap РАСТР = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);

// Создаем экземпляр класса Graphics из точечного рисунка:

Graphics Графика = Graphics.Fromlmage(РАСТР);

// Рисуем прямоугольник, заполненный цветом фона:

Графика.FillRectangle(ЦветФона, 0, 0, Width, Height);

// Искажаем рисунок сеткой линий и случайно разбросанными точками:

Сетка_и_точки(Графика, ЦветПера, ЦветРисования, Случай, Width, Height);

// В прямоугольнике рисуем шесть случайно выбранных символов:

РисованиеСимволов(Графика, ЦветРисования);

Графика.Dispose();

return РАСТР;

}

private void ВыборЦвета(Random Случай, ref Color ЦветПера, ref Brush ЦветФона, ref Brush ЦветРисования)

{ // Выбираем случайным образом "комплект" цветов из двух вариантов

//и передаем их как параметры по -ссылке reference

int R = Случай.Next(100);

// Определяем, является ли случайное число R четным или нечетным:

if (Четное(R) == true)

{ // Первый вариант:

ЦветПера = Color.Black;

ЦветФона = Brushes.White;

ЦветРисования = Brushes.Black;

}

else // Если R - нечетно:

{ // Второй вариант:

ЦветПера = Color.White;

ЦветФона = Brushes.Black;

ЦветРисования = Brushes.White;

}

}

private bool Четное(int k)

{ // Функция определяет, число К является четным или нечетным:

if (К % 2 == 0) return true;

// Оператор % возвращает целочисленный остаток от деления

return false;

}

private void Сетка_и_точки(Graphics Графика, Color ЦветПера, Brush ЦветРисования, Random Случай,

int Width, int Height)

{ // Искажаем рисунок сеткой линий и случайно разбросанными точками.

// Создание пера для рисования им фигур:

Pen Перо = new Pen (ЦветПера, 1F);

// Рисование сетки линий на рисунке:

for (int х = 0; х <= Height; х += 15)

Графика.DrawLine(Перо, 0, х, Width, х);

for (int х = 0; х <= Width; х += 15)

Графика.DrawLine(Перо, х, 0, х, Height);

// Рисование случайно расположенных точек, их плотность равна одной точке на 10 квадратных пикселов:

int Кол_во_точек = (int)Math.Round((decimal)(Width * Height / 10), 0);

for (int i = 0; i < Кол_во_точек; i++)

{

int x1 = Случай.Next(Width);

int y1 = Случай.Next(Height);

// Ширина эллипса - 1 пиксел, а его высота - 2 пиксела:

Графика.FillEllipse(ЦветРисования, x1, y1, 1, 2);

}

}

private void РисованиеСимволов(Graphics Графика, Brush Цвет_Рис)

{ //В прямоугольнике рисуем шесть случайно выбранных символов.

// Задаем строку из шести случайно выбранных символов:

string СтрокаШести = СлучайнаяСтрока();

// Запоминаем эту строку на время текущей сессии:

Page. Session .Add ("Символы", СтрокаШести);

// Копируем символы из строки в массив символов:


char[] МассивШести = СтрокаШести.ToCharArray();

// Задаем два шрифта: один обычный, а другой - наклонный (Italic):

Font Шрифт1 = new Font("Arial", 20);

// 20 - это размер самой широкой буквы

Font Шрифт2 = new Font(“Arial", 20, FontStyle.Italic);

// Размер массива равен шести:

int len = СтрокаШести.Length;

// Цикл по каждой букве (их шесть):

for (int i = 0; i < len; i++)

{ // Point - координаты левого верхнего угла прямоугольника:

Rectangle Прямоугольник = new Rectangle(new Point(i * 22, 2), new Size(24, 36));

// Размер прямямоугольника - Size(24 x 36)

string ОдинСимвол = МассивШести[i].ToString();

// Рисую один символ из тех самых шести символов:

if (Четное(i) == true)

Графика .Drawstring (ОдинСимвол, Шрифт1, Цвет_Рис, Прямоугольник);

Else

Графика.Drawstring(ОдинСимвол, Шрифт2, Цвет_Рис, Прямоугольник);

}

Шрифт1.Dispose(); Шрифт2.Dispose();

}

private string СлучайнаяСтрока()

{ // Эта функция возвращает строку с шестью случайно выбранными

// символами из набора "СтрокаСимволов":

string СтрокаСимволов = "23456789ERYUPADFHKZXVBNM";

// В этом наборе нет ни нуля, ни буквы "0"("Q"), ни единицы, ни буквы "I", чтобы их не путать

char[] МассивСимволов = СтрокаСимволов.ToCharArray();

// Генератор псевдослучайных чисел:

Random Случай = new Random();

// SS - строка, сформированная случайным образом:

string SS = string.Empty;

// Цикл от 0 до 5 заполняет строку SS шестью случайно выбранными символами из массива "МассивСимволов": for (int i = 0; i <= 5; i++)

SS = SS + МассивСимволов[Случай.Next(МассивСимволов.Length)];

return SS;

}

protected void Buttonl_Click(object sender, EventArgs e)

{ // Вспоминаем строку из шести случайно выбранных символов, записанную в текущую сессию:

string СтрокаШести = (Page.Session["Символы"]).ToString();

// Удаление всех пробелов и невидимых управляющих символов:

TextBox1.Text = TextBox1.Text.Trim();

if (TextBox1.Text == СтрокаШести)

{ Label1.Text = "Верно"; Label1.ForeColor = Color.Black; }

Else

{ Label1.Text = "Попробуйте еще раз"; Label1.ForeColor = Color.Red; }

}

}

}

Как видно из программного кода, в процедуре загрузки страницы Page_Load про­исходит вызов ключевой функции Генерировать Рисунок только при первичной загрузке страницы, т. е. когда IsPostBack = false. Эта функция возвращает растровый рисунок в формате Bitmap, который мы сохраняем (Save) на сервере. Далее для элемента управления Image1 указываем виртуальный путь к сохраненному рисунку.

Функция Генерировать Рисунок создает объект класса Graphics из точечного рисунка формата Bitmap, с помощью функции ВыборЦвета выбирает случайным образом из двух вариантов цвет фона и цвет рисования. Затем рисует заполненный цветом фона прямоугольник, который мы искажаем сеткой линий и случайно разбросанными точками, и выводит в этот прямоугольник шесть случайно выбранных символов, которые подлежат распознаванию пользователем.



Как видно, программа имеет иерархическую структуру с большой глубиной вложенности. Заслуживает обсуждения функция СлучайнаяСтрока. В ней мы задaем набор символов в строковой переменной СтрокаСимволов. В этом наборе отсут­ствуют цифра "1", буквы "I", "J", "Т", поскольку их начертание похоже, а это может затруднять пользователю их распознавание. По этой же причине в наборе отсутст вуют цифра "0", буквы "О", "Q", "G", "С". Данную строку символов с помощью функции ToCharArray преобразуем в массив символов. Пользуясь этим массивом, в цикле легко заполнить строку шестью случайно выбранными символами.



Рис. 14.16. Тестирование с помощью капча

Теперь нам требуется запомнить строку с шестью выбранными символами, что­бы ее сравнить со строкой тестового поля TextBox1, которое заполнит пользователь. Воспользоваться внешними переменными мы не можем, поскольку они стираются из оперативной памяти при перезагрузке страницы. Для этой цели воспользуемся объек­том Page.Session. В технологии ASP.NET каждое Web-приложение при обращении к нему пользователя (клиента) создает объект Page.Session, этот объект называют сессией или сеансом пользователя. Объект Session содержит в себе методы для создания коллекции данных. Причем созданная коллекция данных на одной странице Web-приложения оказывается доступной на любой другой странице данного приложения. Даже если пользователь перешел на другое Web-приложение (на другой Web-узел), а затем вернулся в текущее приложение, то исходная коллекция данных сессии будет сохранена. Она будет сохранена до тех пор, пока пользователь не закрыл свой Web-браузер. Однако время жизни (лимит времени) сессии все же ограничено параметром Timeout. По умолчанию время жизни равно 20 минутам, его можно регулировать в файле программной поддержки свойством объекта Session.Timeout или прямо в тексте программы. Таким образом, в процедуре РисованиеСимволов запоми­наем строку с шестью выбранными символами, используя объект Page.session.

При щелчке пользователем на кнопке Регистрация читаем строку с шестью выбранными символами из объекта Page.session. Теперь мы можем сравнить ее со строкой символов, полученной от пользователя в текстовом поле
TextBox1. Фрагмент работы капча представлен на рис. 14,16. Убедиться в работоспособности данной программы можно, открыв соответст­вующее решение в папке Капча.

Пример 109. Отображение времени в Web-форме с использованием технологии AJAX

Мы уже обсуждали вопрос отображения времени в Windows-приложении (см. пример 86 в главе 12). Тогда для того чтобы время обновлялось каждую секунду, на­ми был использован элемент управления Timer. При обработке события Tick (собы­тия, когда прошел заданный интервал времени Interval, равный 1000 миллисекунд, т. е. 1 с) элемента управления Timer в метку Label копировалось новое значение времени, при этом изображение формы обновлялось (перерисовывалось). Когда речь вдет о Web-форме, технология ASP.NET предполагает операции обратной отправки данных. Когда пользователь щелкает на кнопке или делает выбор в окне списка с включенной функцией AutoPostBack, серверу отсылается соответствующий запрос, после чего с него обратно клиенту передается целая страница. Если такое обращение к серверу будет происходить каждую секунду, то возрастет объем сетевого трафика и вследствие инерции Сети пользователь будет ощущать дискомфорт. Кроме того, если на этой странице предусмотрено заполнение пользователем полей, то серверу будет отсылаться страница с частично заполненными полями.

Решение этой проблемы состоит в использовании технологии AJAX, которая обеспечивает возможность выполнения частичного визуального обновления стра­ницы посредством поддерживаемой ASP.NET AJAX-операции обратной отправки.

продемонстрируем возможность технологии AJAX на примере, когда мы имеем метку Label в Web-форме. На эту метку каждую секунду копируем новое время, но обновляем при этом не всю форму, а только метку с помощью технологии AJAX.

Решая эту задачу, запустим Visual Studio 2010 и закажем новый проект из шабло­на Empty ASP.NET Web Application, укажем имя NameAjaxTimer. К текущему проекту добавим Web-форму. Для этого в пункте меню Project выберем команду Add New Item и в появившемся окне дважды щелкнем по шаблону Web Form.

Далее, попав на вкладку конструктора Web-формы, перетащим в форму из раздела AJAX Extensions панели ToolBox элементы управления ScriptManager, UpdatePanel. Затем на вкладке файла программной поддержки WebForm1.aspx.cs напишем программный код, приведенный в листинге 14.11.

Листинг 14.11. Отображение времени в
Web-форме

// Web-страница демонстрирует время на текстовой метке Labell. На эту метку каждую секунду копируем новое время,

//но обновляем при этом не всю форму, а только метку с помощью технологии AJAX

using System;

// Другие директивы using удалены, поскольку они не используются в данной программе

namespace AjaxTimer

{

public partial class WebForm1 : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

Timer1.Interval = 1000; // 1000 миллисекунд = 1 секунда

Label1.Text = "Текущее время: " + DateTime.Now.ToLongTimeString();

}

protected void Timer1_Tick(object sender, EventArgs e)

{ // Обновление содержимого метки каждую секунду:

Label1.Text = "Текущее время: " + DateTime.Now.ToLongTimeString();

}

}

}

Как видно из программного кода, при загрузке страницы задаем интервал вре­мени, равный одной секунде. При обработке события Tick — события, когда про­шел заданный интервал времени, в метку Label1 копируется новое значение вре­мени. При этом благодаря использованию технологии AJAX обновляется не вся Web-форма, а только те элементы, которые расположены на элементе UpdatePanel. Фрагмент работы программы показан на рис. 14.17.

Рис. 14.17. В форме обновляется только AJAX-элемент UpdatePanel

Убедиться в работоспособности Web–страницы можно открыв решение AjaxTimer.sln в папке AjaxTimer.