using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.IO;
namespace
StackOverflowTest
{
public partial
class MainForm
: Form
{
///
<summary>
///
Записывает отладочную информацию в файл.
///
</summary>
protected
StreamWriter loggerStreamWriter;
///
<summary>
///
Указатель на область рисования.
///
</summary>
protected
Bitmap pictureBitmap;
///
<summary>
///
Счётчик итераций.
///
</summary>
protected
uint iterationUint = 1;
///
<summary>
///
Цвет границы.
///
</summary>
protected
Color borderColor =
Color.White;
///
<summary>
///
Цвет, которым заполняем область.
///
</summary>
protected
Color fillingColor;
///
<summary>
///
Буфер для эмуляции переполнения стека
///
</summary>
unsafe
struct Foo
{
public
fixed int
emulationBufferArrayFixedInt[200];
}
///
<summary>
///
Конструктор формы, в которой происходит рисование.
///
</summary>
public
MainForm()
{
//Инициализирует компоненты формы
InitializeComponent();
//Открывает
потковый ввод-вывод, инициализирует фоновый рисунок с областью, которую
нужно залить.
loggerStreamWriter =
new StreamWriter("log.log");
var
strStreamReader = new
StreamReader("D:\\1\\pict5.png");
main_panel.BackgroundImage =
Bitmap.FromStream(strStreamReader.BaseStream);
//Связывает
указатель с физической областью заливки
pictureBitmap = (Bitmap)main_panel.BackgroundImage;
}
///
<summary>
///
Задаёт выбранному пикселю цвет.
///
</summary>
///
<param name="xCoordInt">Координата
по оси Х</param>
///
<param name="yCoordInt">Координата
по оси У</param>
protected
void SetPixel(int
xCoordInt, int yCoordInt)
{
//С помощью
встроенных средств рисования на объекте Bitmap выполняем смену цвета
pictureBitmap.SetPixel(xCoordInt,
yCoordInt, fillingColor);
}
///
<summary>
///
Сравнивает цвет границы и цвет выбранной точки.
///
</summary>
///
<param name="xCoordInt">Координата
по оси Х</param>
///
<param name="yCoordInt">Координата
по оси У</param>
///
<returns>Истина
- если цвета не совподают, иначе - возвращает ложь.</returns>
protected
bool CompareBool(int
xCoordInt, int yCoordInt)
{
//С помощью
встроенных средств рисования на объекте Bitmap получаем цвет нужного
пикселя.
//Для удобства
сравнения конвертируем их в число.
return
pictureBitmap.GetPixel(xCoordInt, yCoordInt).ToArgb() != borderColor.ToArgb();
}
///
<summary>
///
Метод выполняет рекурсивную заливку ограниченной области,
///
при этом вызывается переполнение программного стека.
///
</summary>
///
<param name="xCoordInt">Координата
по оси Х</param>
///
<param name="yCoordInt">Координата
по оси У</param>
protected
void RecursiveFill(int
xCoordInt, int yCoordInt)
{
try
{
//Создаем
большой буфер для эмуляции переполнения стека
//var
tempvarForEmulationStackOverflowFoo = new Foo();
//Записываем в лог-файл строку с отладочной информацией
loggerStreamWriter.WriteLine(iterationUint
+ ":" + xCoordInt +
"," + yCoordInt);
//Увеличиваем счётчик итераций
iterationUint++;
//Если
дошли до границы, то выходим
if (CompareBool(xCoordInt,
yCoordInt)) return;
//Иначе
меняем цвет пикселя на нужный
SetPixel(xCoordInt, yCoordInt);
//Заставляем элемент перерисовать свою область
main_panel.Refresh();
//Идём в
глубь рекурсии
RecursiveFill(xCoordInt, yCoordInt +
1);
RecursiveFill(xCoordInt, yCoordInt -
1);
RecursiveFill(xCoordInt - 1,
yCoordInt);
RecursiveFill(xCoordInt + 1,
yCoordInt);
}
//Пытаемся
отловить ошибки
catch (System.Exception
e)
{
//Выводим
сообщение и прервем выполнение
MessageBox.Show(e.Message, e.Source,
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
///
<summary>
///
Обработчик кликания мышкой
///
</summary>
///
<param name="sender">Источник</param>
///
<param name="e">Параметры</param>
private void
main_panel_MouseClick(object sender,
MouseEventArgs e)
{
//задаём
цвет
для
рисования
fillingColor = Color.Red;
//вызывем рекурсивную заливку ограниченной
области из точки, где находится указатель мыши.
RecursiveFill(e.X, e.Y);
}
}
} |