Файл: Справочник для опытных и как пособие для начинающих программистов. Компактдиск содержит исходные коды примеров из книги.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, укажем имя Name — AjaxTimer. К текущему проекту добавим 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.