Возможности:
• печать рисунка
• увеличение листа
• уменьшение листа
• точка
• отрезок
• дуга
• ластик
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
// инициализация главной формы
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TYPE = point; // устанаваливаем по умолчанию режим - точка
poly = new TPoint[4]; // создаем массив точек для рисования дуги
ZOOM = 10; // начальный масштаб
port = true; // по умалчанию портретный лист
Start(A4PW, A4PH, A4h); // уставнавливаем портретный лист
ScrollBox1->DoubleBuffered = true; // включаем двойную буферизацию
// инициализация кистей и перьев
pn = new TPen; // промежуточное перо
PB->Canvas->Pen->Width = 4; // устанавливаем толщину линий при рисовании точки
// прирасваиваем настройки текущего пера промежуточному
pn->Color = PB->Canvas->Pen->Color; // цвет
pn->Style = PB->Canvas->Pen->Style; // стиль
pn->Width = 2; // толщина линий(по умолчанию)
PB->Canvas->Brush->Style = bsClear; // устанавливем прозрачную заливку
Modified = false; // флаг модификации - рисунок не менялся
}
//---------------------------------------------------------------------------
// обработываем событие, когда мышь была нажата в зависимости от режима
void __fastcall TForm1::PBMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if( TYPE != scale ) Modified = true; // произошли изменения в рисунке, если режим отличный от масштабирования
switch(TYPE) // режимы
{
case point : move_pt = Point(X, Y); // присваеваем начальные координаты точки
DrawPoint(move_pt, pmNotXor); // рисуем точку в начальных координатах
break;
case line : if( orig_pt.x != X && orig_pt.y != Y && orig_pt.x != -1 && orig_pt.y != -1 ) // проверяем - это начальная точка отрезка или нет, если нет, то:
{
DrawLine(orig_pt, Point(X, Y), pmCopy); // рисуем отрезок
orig_pt = Point(-1, -1); // и обнуляем координаты
}
else orig_pt = Point(X, Y); // если нет - указываем начальные координаты
break;
case polyline : poly[polyNUMpoint] = Point(X, Y); // указываем координаты текущей точки полилинии
break;
case circle : orig_pt = Point(X, Y); // указываем
move_pt = orig_pt; // начальные координаты окружности
break;
case arc : poly[polyNUMpoint] = Point(X, Y); // указываем координаты текущей точки полилинии
break;
case rect : orig_pt = Point(X, Y); // указываем начальные
move_pt = orig_pt; // координаты прямоугольника
break;
case eraser : PB->Canvas->MoveTo(X,Y); // стираем ластиком
break;
}
}
//---------------------------------------------------------------------------
// манипуляции при движении мыши
void __fastcall TForm1::PBMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
// если зажата левая кнопка мыши
if( Shift.Contains(ssLeft) )
{
switch(TYPE) // режим
{
case point : DrawPoint(move_pt, pmNotXor); // стираем точку по предыдущим координатам,
move_pt = Point(X, Y); // указываем текущие
DrawPoint(move_pt, pmNotXor); // и рисуем по новым
break;
case polyline : DrawLine(orig_pt, move_pt, pmNotXor); // стираем предыдущий отрезок
move_pt = Point(X, Y); // указываем текущие координаты конца отрезка
DrawLine(orig_pt, move_pt, pmNotXor); // и трисовываем по новым координатам
break;
case circle : DrawCircle(orig_pt, move_pt, pmNotXor); // стираем окружность по старым координатам
move_pt = Point(X, Y); // указываем текущие
DrawCircle(orig_pt, move_pt, pmNotXor); // и рисуем новую по ним
break;
case rect : DrawRect(orig_pt, move_pt, pmNotXor); // стираем старый прямоугольник
move_pt = Point(X, Y); // новые координаты
DrawRect(orig_pt, move_pt, pmNotXor); // отрисовываем по ним
break;
case eraser : PB->Canvas->LineTo(X, Y); // стираем ластиком
break;
}
}
}
//---------------------------------------------------------------------------
// выбор режима работы
void __fastcall TForm1::N4Click(TObject *Sender)
{
int i;
polyNUMpoint = 0; // начальная точка дуги или полилинии
orig_pt = Point(-1, -1); // обнуляем начальные координаты отрезка
if( !((TMenuItem*)Sender)->Checked ) // если пункт меню не отмечен чекером
{
if( TYPE == scale ) // обнуляем масштабирование
{
N15->Enabled = false; // пункт меню "Исходный размер" заблокирован
N19->Enabled = false; // пункт меню "Увеличить на 10%" заблокирован
N20->Enabled = false; // пункт меню "Уменьшить на 10%" заблокирован
}
if( TYPE == eraser ) // приводим свойства пера к умолчаниям после режима Ластик
{
PB->Canvas->Pen->Color = pn->Color; // цвет
PB->Canvas->Pen->Style = pn->Style; // стиль
PB->Canvas->Pen->Width = pn->Width; // толщина
}
if( TYPE == point ) PB->Canvas->Pen->Width = pn->Width; // приводим к умолчаниям толщину пера после режима точка
for(i=0; iItems->Items[2]->Count ; i++) // перебираем пункты меню
{
if( TYPE == StrToInt(&MM->Items->Items[2]->Items[i]->Name.c_str()[1]) ) // ищем по названию пункт меню соответствующий режиму
{
MM->Items->Items[2]->Items[i]->Checked = false; // убираем чекер
break; // выходим из цикла
}
}
((TMenuItem*)Sender)->Checked = true; // устанавливаем чекер на выбранном пункте меню
TYPE = StrToInt(&((TMenuItem*)Sender)->Name.c_str()[1]);// в зависимости от имени пункта меню - устанавливаем режим
if( TYPE == eraser ) // если ластик
{
// запоминаем текущие настройки пера
pn->Color = PB->Canvas->Pen->Color; // цвет
pn->Style = PB->Canvas->Pen->Style; // стиль
pn->Width = PB->Canvas->Pen->Width; // толщина
// устанавливаем новые
PB->Canvas->Pen->Color = clWhite; // цвет
PB->Canvas->Pen->Width = 30; // толщина
}
if( TYPE == point ) // если точка
{
pn->Width = PB->Canvas->Pen->Width; // запоминает толщину линий по умолчанию и
PB->Canvas->Pen->Width = 4; // устанавливаем новую
}
if( TYPE == scale ) // если режим масштабирования
{
N15->Enabled = true; // пункт меню "Исходный размер" активен
N19->Enabled = true; // пункт меню "Увеличить на 10%" активен
N20->Enabled = true; // пункт меню "Уменьшить на 10%" активен
}
}
}
//---------------------------------------------------------------------------
// обрабатываем отжатие кнопки мыши
void __fastcall TForm1::PBMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
switch(TYPE) // режим
{
case point : DrawPoint(Point(X, Y), pmCopy); // окончательно рисуем точку
break;
case polyline : if( poly[polyNUMpoint].x != X || poly[polyNUMpoint].y != Y ) // если текущие координаты не равны координатам текущей точки
{
DrawLine(orig_pt, Point(X, Y), pmCopy); // рисуем линию
poly[0] = Point(X, Y); // устанавливаем текущие координаты как начальные
polyNUMpoint = 1; // переходим к следующей точке
}
else // если это конечная точка дуги
if( polyNUMpoint == 2 )
{
poly[2] = Point(X, Y); // заполняем массив координат
poly[3] = Point(X, Y); // до конца
PB->Canvas->PolyBezier(poly, 3); // рисуем дугу
polyNUMpoint = 1; // переходим ко второй точке
poly[0] = Point(X, Y); // указывая текущие координаты начальными для следующих дуги или отрезка
}
else polyNUMpoint++; // если не все из вышеперечисленного, то просто переходим к следующей точке
orig_pt = Point(X, Y); // запоминаем
move_pt = orig_pt; // текущие координаты
break;
case circle : DrawCircle(orig_pt, Point(X, Y), pmCopy); // рисуем окончательно окружность
break;
case arc : if( polyNUMpoint == 2 ) // если конечная точка дуги
{
poly[2] = Point(X, Y); // заполняем массив
poly[3] = Point(X, Y); // до конца
PB->Canvas->PolyBezier(poly, 3); // рисуем дугу
polyNUMpoint = 0; // переходим к начальной точке новой дуги
}
else polyNUMpoint++; // переходим к следующей точке
break;
case rect : DrawRect(orig_pt, Point(X, Y), pmCopy); // окончательно выводим на экран прямоугольник
break;
}
}
//---------------------------------------------------------------------------
// деструктор формы
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
delete [] poly; // удаляем массив точек
}
//---------------------------------------------------------------------------
// рисуем линию
void __fastcall TForm1::DrawLine(const TPoint &pt1, const TPoint &pt2, TPenMode pm)
{
PB->Canvas->Pen->Mode = pm; // устанавливаем тип пера
PB->Canvas->MoveTo(pt1.x, pt1.y); // переходим по координатам
PB->Canvas->LineTo(pt2.x, pt2.y); // и от них рисуем линию
}
//---------------------------------------------------------------------------
// рисуем четырехугольник
void __fastcall TForm1::DrawRect(const TPoint &pt1, const TPoint &pt2, TPenMode pm)
{
PB->Canvas->Pen->Mode = pm; // устанавливаем тип пера
PB->Canvas->Rectangle(pt1.x, pt1.y, pt2.x, pt2.y); // рисуем прямоугольник
}
//---------------------------------------------------------------------------
// рисуем окружность
void __fastcall TForm1::DrawCircle(const TPoint &pt1, const TPoint &pt2, TPenMode pm)
{
PB->Canvas->Pen->Mode = pm; // устанавливаем тип пера
PB->Canvas->Ellipse(pt1.x, pt1.y, pt2.x, pt2.y); // рисуем окружность
}
//---------------------------------------------------------------------------
// выводим на экран точку
void __fastcall TForm1::DrawPoint(const TPoint &pt1, TPenMode pm)
{
PB->Canvas->Pen->Mode = pm; // устанавливаем тип пера
PB->Canvas->MoveTo(pt1.x, pt1.y); // переходим по координатам
PB->Canvas->LineTo(pt1.x, pt1.y); // и от них рисуем линию
}
//---------------------------------------------------------------------------
// завершение работы
void __fastcall TForm1::N14Click(TObject *Sender)
{
Close(); // закрываем приложение
}
//---------------------------------------------------------------------------
// создание нового документа
void __fastcall TForm1::N11Click(TObject *Sender)
{
IsNeedSave(); // если были изменения, то нужно сохранить их
Start(A4PW, A4PH, A4h); // устанавливаем портретный лист
N4Click(((TMenuItem*)N4)); // переходим в режим точка
PB->Stretch = true; // растягиваем лист
}
//---------------------------------------------------------------------------
// проверяем: если произошли изменения, то пользовтелю предлагается сохранить рисунок
void __fastcall TForm1::IsNeedSave()
{
String str;
if( Modified && MessageBox(Handle, "Сохранить изменения в файл?", "Произошли изменения...", MB_YESNO | MB_ICONQUESTION ) == IDYES )
if( SD->Execute() ) // если диалог открыт
{
// проверяем ввел ли пользователь расширение фафла
if( !AnsiCompareText(ExtractFileExt(SD->FileName), ".bmp") ) str = SD->FileName; // если да
else str = SD->FileName + ".bmp"; // если нет, то добавляем
PB->Picture->Bitmap->SaveToFile(str); // сохраняем рисунок
}
Modified = false; // отключаем флаг модификации
}
//---------------------------------------------------------------------------
// загружаем рисунок из файла
void __fastcall TForm1::N12Click(TObject *Sender)
{
IsNeedSave(); // проверяем - нужно ли сохранить текущий рисунок
if( OD->Execute() ) //если диалог открыт
{
TImage* img = new TImage(Owner); // создаем промежуточный рисунок
img->AutoSize = true; // авторазмер
img->Picture->Bitmap->LoadFromFile(OD->FileName); // загружаем в него выбранный файл
if( img->Width >= img->Height ) // если ширина больше или равна высоте
{
Start(A4AW, A4AH, A4h); // устанавливаем альбомный лист
port = false; // указываем что лист альбомный
}
else // если ширина меньше высоты
{
Start(A4PW, A4PH, A4h); // устанавливаем портретный лист
port = true; // указываем, что он портретный
}
delete img; // удаляем промежуточный рисунок
PB->Picture->Bitmap->LoadFromFile(OD->FileName); // открываем нужный файл
N4Click(((TMenuItem*)N4)); // переходим в режим точка
PB->Stretch = true; // растягиваем рисунок на весь лист
}
}
//---------------------------------------------------------------------------
// сохранение рисунка
void __fastcall TForm1::N13Click(TObject *Sender)
{
String str;
Modified = false; // указываем, что модификаций уже нет
if( SD->Execute() ) // открываем диалог сохранения
{
// проверяем наличие расширения
if( !AnsiCompareText(ExtractFileExt(SD->FileName), ".bmp") ) str = SD->FileName; // если присутствует
else str = SD->FileName + ".bmp"; // если нет, то добавляем
PB->Picture->Bitmap->SaveToFile(str); // сохраняем
}
}
//---------------------------------------------------------------------------
// закрытие формы
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
IsNeedSave(); // прверяем - надо ли сохранять?
}
//---------------------------------------------------------------------------
// обрабатываем прокрутку документа
void __fastcall TForm1::MyWndProc(TMessage &msg)
{
OldWndProc(msg); // вызов стандартного обработчика
if( msg.Msg == WM_VSCROLL ) // вертикальный скролинг
{
Himg->Top = 0; // верхние точки горизонтальной шкалы и
Panel1->Top = 0; // и панели
}
if( msg.Msg == WM_HSCROLL ) // горизонтальный скролинг
{
Vimg->Left = 0; // левые точки вертикальной шкалы и
Panel1->Left = 0; // панели
}
}
//---------------------------------------------------------------------------
// инициализация формы
void __fastcall TForm1::FormCreate(TObject *Sender)
{
OldWndProc = ScrollBox1->WindowProc; // сохраняем оригинальный обработчик событий скролинга
ScrollBox1->WindowProc = MyWndProc; // и устанавливаем новый
}
//---------------------------------------------------------------------------
// устанавливаем ориентацию листа
void __fastcall TForm1::Start(int width, int height, int h)
{
WIDTH = width; // ширина
HEIGHT = height; // высота
PB->Picture->Assign(NULL); // обнуляем картинку
PB->Width = WIDTH; // ширина листа
PB->Height = HEIGHT; // высота листа
PB->Canvas->Pen->Color = clWhite; // цвет пера - белый
PB->Canvas->Rectangle(0,0,WIDTH, HEIGHT); // рисуем прямоугольник по всему листу, тем самым инициализируем его
PB->Canvas->Pen->Color = clBlack; // возвращаемся к стандартному черному перу
SetScale(10); // устанавливаем нулевой масштаб
}
//---------------------------------------------------------------------------
// при изменении размеров формы - указываем координаты линеек
void __fastcall TForm1::FormResize(TObject *Sender)
{
Himg->Top = 0; // верхняя точка горизонтальной шкалы
Panel1->Top = 0; // верхняя точка панели
Vimg->Left = 0; // левая точка вертикальной шкалы
Panel1->Left = 0; // левая точка панели
}
//---------------------------------------------------------------------------
// печать текста под углом в 90 град.
void __fastcall TForm1::DrawAngleText(TCanvas* cnv, int X, int Y, String S)
{
LOGFONT lf; // новый шрифт
cnv->Brush->Style = bsClear; // стиль кисти
ZeroMemory(&lf, sizeof(LOGFONT)); // выделяем память
lf.lfHeight = 12; // высота
lf.lfEscapement = 900 ; // угол
lf.lfOrientation = 900; // наклона
lf.lfCharSet = DEFAULT_CHARSET; // стандартная кодировка
cnv->Font->Handle = CreateFontIndirect(&lf); // создаем новый шрифт
cnv->TextOut(X, Y, S); // печатаем новым шрифтом
}
//---------------------------------------------------------------------------
// печать документа
void __fastcall TForm1::SetPrintIMG(double k)
{
if( PrintDialog1->Execute()) // открываем диалог печати
{
TImage* img = new TImage(NULL); // создаем новую картинку
img->Width = WIDTH; // ширина
img->Height = HEIGHT; // высота
TRect dest; // координаты рисунка
dest.left = 0; // левая точка
dest.top = 0; // верхняя
dest.bottom = HEIGHT * k; // нижняя с учетом кооэффициента увеличения/уменьшения
dest.right = WIDTH * k; // правая с учетом кооэффициента увеличения/уменьшения
img->Canvas->StretchDraw(dest, PB->Picture->Bitmap); // растягивем наш рисунок в новом
TPrinter *p = Printer(); // инициализируем принтер
// создаём в памяти контекст для картинки
HDC h_dc = img->Picture->Bitmap->Canvas->Handle;
int bmp_w = WIDTH, bmp_h = HEIGHT; // ширина и высота
HDC h_mem_dc = ::CreateCompatibleDC (h_dc); // создаем новый контекст на основе старого
HBITMAP h_mem_bmp = ::CreateCompatibleBitmap (h_dc, bmp_w, bmp_h); // создаем рисунок совместимый с первым контекстом
HBITMAP h_old_bmp = ::SelectObject (h_mem_dc, h_mem_bmp); // выбираем объект в заданный контекст
// фиксируем ошибки видео драйверов
bool is_pal_dev = false; // флаг создания новой палитры
LOGPALETTE *pal; // логическая палитра
HPALETTE h_pal, h_old_pal; // описание палитры
if( ::GetDeviceCaps(img->Canvas->Handle, RASTERCAPS) & RC_PALETTE ) // проверяем информацию утройства и заполняем палитры
{
pal = static_cast(malloc(sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256))); // выделяем память
memset(pal, 0, sizeof (LOGPALETTE) + (sizeof(PALETTEENTRY) * 256)); // заполняем буфер
pal->palVersion = 0x300; // версия
pal->palNumEntries = ::GetSystemPaletteEntries(img->Canvas->Handle, 0, 256, pal->palPalEntry); // диапазон записей палитры
if (pal->palNumEntries != 0) // если число записей не равно нулю
{
h_pal = ::CreatePalette(pal); // создаем новую палитру
h_old_pal = ::SelectPalette(h_mem_dc, h_pal, false); // вибираем
is_pal_dev = true; // указываем, что новая палитра создана
}
else free(pal); // освобождаем память
}
// копируем картинку на dc в памяти
::BitBlt(h_mem_dc, 0, 0, bmp_w, bmp_h, h_dc, 0, 0, SRCCOPY); // копируем картинку
if( is_pal_dev ) // если новая палитра создана
{
::SelectPalette(h_mem_dc, h_old_pal, false);// выбираем палитру
::DeleteObject(h_pal); //удаляем ненужную
}
// удаляем dc в памяти
::SelectObject (h_mem_dc, h_old_bmp); // выбираем объект в заданный контекст
::DeleteDC (h_mem_dc);//удаляем ненужный
// выделяем память для структуры BITMAPIFO
HANDLE h_bmp_info = ::GlobalAlloc(GHND, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 256)); //выделяем память
BITMAPINFO* bmp_info = static_cast(::GlobalLock(h_bmp_info)); // фиксируем
//Заполняем структуру
memset(bmp_info, NULL, sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * 255)); // заполняем
bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // размер
bmp_info->bmiHeader.biPlanes = 1; // число плоскостей
bmp_info->bmiHeader.biBitCount = 8; // число битов на пиксель
bmp_info->bmiHeader.biWidth = bmp_w; // ширина
bmp_info->bmiHeader.biHeight = bmp_h; // высота
bmp_info->bmiHeader.biCompression = BI_RGB; // сжатие
// определяем размер памяти для битов
::GetDIBits(h_dc, h_mem_bmp, 0, bmp_h, NULL, bmp_info, DIB_RGB_COLORS);
// Выделяем память для битов
HANDLE h_bits = GlobalAlloc(GHND, bmp_info->bmiHeader.biSizeImage);
void *bits = ::GlobalLock(h_bits);
// получаем биты
::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, bits, bmp_info, DIB_RGB_COLORS);
// фиксируем ошибки видео драйверов
if (is_pal_dev)
{
for (int i = 0; ipalNumEntries; i++)// перечисляем диапазон записей
{
bmp_info->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed; // красный
bmp_info->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen; // зеленый
bmp_info->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue; // синий
}
free(pal); // освобождаем память
}
// начинаем печать
p->BeginDoc ();
// устанавливаем палитру печати
is_pal_dev = false; // отключаем флаг
if( ::GetDeviceCaps(h_dc, RASTERCAPS) & RC_PALETTE ) // проверяем информацию устройства
{
pal = static_cast(malloc(sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256))); // выделяем память
memset(pal, 0, sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256)); //заполняем буфер
pal->palVersion = 0x300; // версия
pal->palNumEntries = 256; // диапазон записей
for (int i = 0; ipalNumEntries; i++) // пролистываем их
{
pal->palPalEntry[i].peRed = bmp_info->bmiColors[i].rgbRed; // красный
pal->palPalEntry[i].peGreen = bmp_info->bmiColors[i].rgbGreen; // зеленый
pal->palPalEntry[i].peBlue = bmp_info->bmiColors[i].rgbBlue; // синий
}
h_pal = CreatePalette(pal); // создаем палитру
free(pal); // освобождаем память
h_old_pal = SelectPalette(p->Canvas->Handle, h_pal, false); // выбираем палитру для принтера
is_pal_dev = true; // включаем флаг
}
// посылаем биты на принтер
StretchDIBits(p->Canvas->Handle, 0, 0,WIDTH*6, HEIGHT*6/*, scale_x, scale_y*/, 0, 0, bmp_w, bmp_h, bits,bmp_info, DIB_RGB_COLORS, SRCCOPY);
// конец печати
p->EndDoc ();
// освобождаем ресурсы
::DeleteObject (h_mem_bmp);
if( is_pal_dev ) // если флаг включен
{
::SelectObject(p->Canvas->Handle, h_old_pal); // выбираем
::DeleteObject(h_pal); // удаляем
}
::GlobalUnlock (bits); // освобождаем память
::GlobalFree (h_bits); // освобождаем память
::GlobalUnlock (bmp_info); // освобождаем память
::GlobalFree (h_bmp_info); // освобождаем память
delete img; // удаляем промежуточную картинку
}
}
//---------------------------------------------------------------------------
// меняем ориентацию листа
void __fastcall TForm1::test1Click(TObject *Sender)
{
IsNeedSave(); // если нужно сохраниться
if( MessageBox(Handle, "Изменить положение листа?", ( port ? "Портретный" : "Альбомный"), MB_YESNO | MB_ICONQUESTION) == IDYES )
{
N4Click(((TMenuItem*)N4)); // включаем режим точка
if( port ) // если лист портретный
{
port = false; // говорим, что он альбомный
Start(A4AW, A4AH, A4h); // и меняем на альбомный
}
else // если он альбомный
{
port = true; // то указываем, что теперь он портретный
Start(A4PW, A4PH, A4h); // и меняем на портретный
}
}
}
//---------------------------------------------------------------------------
// выводим на принтер
void __fastcall TForm1::N18Click(TObject *Sender)
{
double k = (double)ZOOM / 10; // коэффициент уменьшения/увеличения
if( k < 1 ) ShowMessage("Коэффициент уменьшения равен " + FloatToStr(k)); // если у нас уменьшение
else ShowMessage("Коэффициент увеличения равен " + FloatToStr(k)); // если увеличение
SetPrintIMG(k); // печатаем с учетом коээфициента
}
//---------------------------------------------------------------------------
// увеличение масштаба
void __fastcall TForm1::N19Click(TObject *Sender)
{
if( ZOOM != 100 ) // если масштаб не превышает 1000%
{
ZOOM += 1; // увеличиваем на 10%
SetScale(ZOOM); // отрисовываем новую шкалы
}
}
//---------------------------------------------------------------------------
// уменьшение масштаба
void __fastcall TForm1::N20Click(TObject *Sender)
{
if( ZOOM != 1 ) // если масштаб не меньше 10%
{
ZOOM -= 1; // уменьшаем на 10%
SetScale(ZOOM);// отрисовываем шкалы
}
}
//---------------------------------------------------------------------------
// инициализация линеек
void __fastcall TForm1::SetScale(int z)
{
int i, j;
Panel1->Width = 30; // ширина панели
Panel1->Height = 30; // высота панели
Himg->Height = 30; // высота горизонтальной линейки
Vimg->Width = 30; // ширина вертикальной линейки
PB->Left = 30; // левая точка листа
PB->Top = 30; // верхняя точка листа
Himg->Left = 30; // левая точка горизонтальной линейки
Vimg->Top = 30; // верхняя точка вертикальной линейки
Himg->Width = PB->Width; // ширина горизонтальной линейки
Vimg->Height = PB->Height; // высота вертикальной линейки
Himg->Picture->Assign(NULL); // обнуляем горизонтальную линейку
Vimg->Picture->Assign(NULL); // обнуляем вертикальную линейку
j = 0;
for(i=0; iWidth; i=i+40) // рисуем шкалу горизонтальной линейки
{
Himg->Canvas->MoveTo(i, 20); // перемещаемся
Himg->Canvas->LineTo(i, 30); // отрисовываем деление
Himg->Canvas->MoveTo(i+20, 25); // перемещаемся
Himg->Canvas->LineTo(i+20, 30); // отрисовываем промежуточное деление
DrawAngleText(Himg->Canvas, i-5, 18, IntToStr(j)); // печатаем значение
j+=z; // шаг
}
j=0;
for(i=0; iHeight; i=i+40) // рисуем шкалу вертикальной линейки
{
Vimg->Canvas->MoveTo(20, i); // перемещаемся
Vimg->Canvas->LineTo(30, i); // отрисовываем деление
Vimg->Canvas->MoveTo(25, i+20); // перемещаемся
Vimg->Canvas->LineTo(30, i+20); // отрисовываем промежуточное деление
Vimg->Canvas->TextOutA(0, i-5, IntToStr(j)); // печатаем значение
j+= z; // шаг
}
}
//---------------------------------------------------------------------------
// устанавливаем исходные размеры
void __fastcall TForm1::N15Click(TObject *Sender)
{
ZOOM = 10; // начальный масштаб
SetScale(ZOOM); // перерисовываем шкалы
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// режимы
#define point 4 //рисование точек(точки рисуются начиная с толщины линии = 2)
#define line 5 // отрезки
#define polyline 6 // полилиния
#define circle 7 // окружность
#define arc 8 // дуга(рисуется по трем точкам)
#define rect 9 // четырехугольник
#define eraser 10 // ластик
#define scale 21 // масштабирование
// размеры страницы
#define A4PW 840 // портретная ширина
#define A4PH 1188 // портретная высота
#define A4AW 1188 // альбомная ширина
#define A4AH 840 // альбомная высота
#define A4h 20 // шаг
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMainMenu *MM;
TMenuItem *N1;
TMenuItem *N2;
TMenuItem *N3;
TMenuItem *N4;
TMenuItem *N5;
TMenuItem *N7;
TMenuItem *N8;
TMenuItem *N9;
TMenuItem *N6;
TMenuItem *N10;
TImage *PB;
TMenuItem *N11;
TMenuItem *N12;
TMenuItem *N13;
TMenuItem *N14;
TOpenPictureDialog *OD;
TSavePictureDialog *SD;
TMenuItem *test1;
TPrintDialog *PrintDialog1;
TScrollBox *ScrollBox1;
TImage *Vimg;
TImage *Himg;
TPanel *Panel1;
TMenuItem *N18;
TMenuItem *N19;
TMenuItem *N20;
TMenuItem *N21;
TMenuItem *N15;
void __fastcall PBMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y);
void __fastcall PBMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y);
void __fastcall N4Click(TObject *Sender);
void __fastcall PBMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall N14Click(TObject *Sender);
void __fastcall N11Click(TObject *Sender);
void __fastcall N12Click(TObject *Sender);
void __fastcall N13Click(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormResize(TObject *Sender);
void __fastcall test1Click(TObject *Sender);
void __fastcall N18Click(TObject *Sender);
void __fastcall N19Click(TObject *Sender);
void __fastcall N20Click(TObject *Sender);
void __fastcall N15Click(TObject *Sender);
private: // User declarations
int polyNUMpoint, WIDTH, HEIGHT, ZOOM; // количество выбранных точек дуги; текущие ширина и высота страницы; коэффмцмент масштабирования
TPoint* poly; // массив точек для создания дуги
TPoint orig_pt, move_pt, pos; // координаты мыши - изначальная и текущая, а также начальное положение листа
TPen* pn; // временное перо
bool Modified, port; // флаг о том, что произошли изменения; ффлаг указывающий на расположение листа
TWndMethod OldWndProc; // функция для стандартной обработки прокрутки
void __fastcall DrawLine(const TPoint &pt1, const TPoint &pt2, TPenMode pm); // функция рисования линии
void __fastcall DrawRect(const TPoint &pt1, const TPoint &pt2, TPenMode pm); // функция рисования четырехугольника
void __fastcall DrawCircle(const TPoint &pt1, const TPoint &pt2, TPenMode pm); // функция рисования окружности
void __fastcall DrawPoint(const TPoint &pt1, TPenMode pm); // функция рисования точки
void __fastcall IsNeedSave(); // проверка на необходимость сохранеия документа
void __fastcall MyWndProc(TMessage &msg); // обработчик событий прокрутки
void __fastcall Start(int width, int height, int h); // инициализация листа
void __fastcall DrawAngleText(TCanvas* cnv, int X, int Y, String S); // функция вывода текста на горизонтальной линейке под углом 90град.
void __fastcall SetPrintIMG(double k); //функция вывода на печать рисунка
void __fastcall SetScale(int z); // инициализация линеек
public: // User declarations
int TYPE; // количество углов/лучей; режим; свойство указывающее на то какие окружности рисовать; радиусы описанной и вписанной окружностей
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_VSCROLL, TMessage, MyWndProc)
END_MESSAGE_MAP(TComponent)
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
|