2.5.2 Функция отрисовки графика
Метод DrawFuncitons класса TChart перебирает по очередности все графики из списка графиков и по очередности отрисовывает каждый из них используя для этого вызов процедуры TChart.DrawFunction. Листинг данной процедуры представлен на рис. 6.
procedure TChart.DrawFunction(funct: TChartFunction);
var
x, y: real;
x1,y1,x2,y2: integer;
a,b: boolean;
f: GraphFunction;
begin
x:=-(x0/FScale);
a:=false;
f:=funct.MainFunction;
while (x0+x*FScale)<(Width-BorderRight) do
begin
if f(x,y) then
begin
x1:=round(x0+x*FScale);
y1:=round(y0-y*FScale);
if (x1>BorderLeft) and (x1<width-BorderRight) and (y1>BorderTop) and (y1<height-BorderBottom) then
begin
PutPixel(x1,y1, funct.Color);
end;
end;
x:=x+0.01;
end;
end;
В данной процедуре используя вызов функции MainFunction объекта класса TChartFunction определяются абсолютные координаты каждой точки графика в диапазоне значений, отображаемых на области отрисовки графика. Используя предварительно заданные масштаб и абсолютные координаты начала координат графика просчитываются координаты каждой точки графика.
2.5.3 Описание методики сохранения графика в графический файл
Для сохранения созданного графика в графический файл используется метод SaveToFile класса TChart. В качестве параметра в данный метод передается имя файла в который необходимо сохранять изображение.
Данная процедура создает временный объект класса TPicture, копирует канвас графика в канвас вновь созданного объекта и после этого, используя метод TPicture.SaveToFile сохраняет изображение в файл. Полный листинг данного метода представлен на рисунке 7.
procedure TChart.SaveToFile(filename: string);
var
temporary: TPicture;
begin
temporary:=TPicture.Create;
temporary.Bitmap.Width:=width;
temporary.Bitmap.Height:=height;
Temporary.Bitmap.Canvas.CopyRect(Temporary.Bitmap.Canvas.ClipRect,MainCanvas, MainCanvas.ClipRect);
Temporary.SaveToFile(filename);
temporary.Destroy;
end;
2.6 Описание модулей и форм
MainForm (MainUnit.pas) – главная форма программы на которой отображаются вычисления интегралов, а также происходит построение графиков функций
AboutForm (Abut.unit) – форма содержащая сведения о разработчике программы
EvalForm (EvalFormUnit.pas) – форма для ввода произвольных математических функций
SystemInfoForm (SysInfo.pas) – форма отображающая результат выполнения API-функции GetSystemInfo
Рисунок 8 – Схема взаимодействия форм приложения
2.7 Вызовы API-функций
В качестве задания к курсовому проекту необходимо описать и использовать в программе две API-функции: ClipCursor и GetSystemInfo.
1. Функция ClipCursor содержится в стандартной библиотеке user32.dll
Описаниефункции:
functionClipCursor(Rect: TRect);
Эта функция заключает курсор в Rect. Если Rect имеет значение nil, то курсор является неограниченным.
Параметры:
Rect: ограничивающий TRect в координатах экрана.
Пример использования данной функции в программе приведен в листинге на рисунке 9.
procedure TMainForm.ClipCursor1Click(Sender: TObject);
var
R: TRect;
begin
ClipCursor1.Checked:=not ClipCursor1.Checked;
if ClipCursor1.Checked then
beginGetClipCursor(ClipRect);
Left:=MainForm.Left;
Right:=MainForm.Left+MainForm.Width;
Bottom:=MainForm.Top+MainForm.Height;
end;
ClipCursor(@R);
end else ClipCursor(@ClipRect);
end;
2. ФункцияGetSystemInfo
Описаниефункции:
procedure GetSystemInfo(lpSystemInfo: TSystemInfo);
Функция в качестве параметра получает указатель на структуру SystemInfo, которую она заполняет. Структуру SystemInfo содержит информацию о текущей системе.
dwOemId: DWord
Устаревший элемент, предназначенный для совместимости с предыдущими версиями Windows NT (3.5 и ранее). Начиная с Windows 3.51 приложения должны использовать переход wProcessorArchitecture объединения. Windows 95/98/Me: система всегда устанавливает этот элемент, чтобы обнулить значение, определенное для PROCESSOR_ARCHITECTURE_INTEL.
wProcessorArchitecture:Word
Определяет архитектуру процессора системы. Этим элементом может быть одно из следующих значений:
PROCESSOR_ARCHITECTURE_UNKNOWN
PROCESSOR_ARCHITECTURE_INTEL
PROCESSOR_ARCHITECTURE_MIPS - Windows NT 3.51
PROCESSOR_ARCHITECTURE_ALPHA - Windows NT 4.0 иранее
PROCESSOR_ARCHITECTURE_PPC - Windows NT 4.0 иранее
PROCESSOR_ARCHITECTURE_IA64 - 64-битнаяверсия Windows
PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 - 64-битнаяверсия
Windows PROCESSOR_ARCHITECTURE_AMD64 - 64-битнаяверсия
Зарезервирован для будущего использования.
dwPageSize : DWord
Определяет размер страницы и степень детализации защиты страницы и блокирования. Это - размер страницы, используемый функцией VirtualAlloc.
lpMinimumApplicationAddress: Pointer
Указатель на самый низкий адрес памяти, доступный для приложений и библиотек динамической связи (DLLs).
lpMaximumApplicationAddress: Pointer
Указатель на самый высокий адрес памяти, доступный для приложений и DLLs.
dwActiveProcessorMask: DWord
Определяет маску, представляющую набор процессоров, конфигурированных в систему. Бит 0 - процессор 0; бит 31 - процессор 31.
dwNumberOfProcessors: DWord
Определяет количество процессоров в системе.
dwProcessorType: DWord
Устаревший элемент, предназначенный для совместимости с предыдущими версиями Windows NT (3.5 и ранее). Windows 95/98/Me: Определяет тип процессора в системе. Windows NT: Этот элемент больше не имеет значения, но сохранен для совместимости с Windows 95 и предыдущими версиями Windows NT. Необходимо использовать wProcessorArchitecture, wProcessorLevel, и wProcessorRevision элементы, чтобы определить тип процессора. Этимэлементомможетбытьодноизследующихзначений: PROCESSOR_INTEL_386 PROCESSOR_INTEL_486 PROCESSOR_INTEL_PENTIUM PROCESSOR_MIPS_R4000 - Windows NT PROCESSOR_ALPHA_21064 - Windows NT
dwAllocationGranularity: DWord
Определяет степень детализации распределения виртуальной памяти.
wProcessorLevel : Word
Windows 95 - этот элемент не поддерживается. Windows NT - определяет архитектурный уровень процессора.
2.8 Методика смешанного программирования
При запуске нескольких экземпляров одного приложения, Windows загружает в оперативную память только одну копию кода и ресурсов - модуль приложения, создавая несколько отдельных сегментов данных, стека и очереди сообщений, каждый набор которых представляет из себя задачу, в понимании Windows. Копия приложения представляет из себя контекст, в котором выполняется модуль приложения. DLL - библиотека также является модулем. Она находится в памяти в единственном экземпляре и содержит сегмент кода и ресурсы, а также сегмент данных. DLL - библиотека, в отличие от приложения не имеет ни стека, ни очереди сообщений. Функции, помещенные в DLL, выполняются в контексте вызвавшего приложения, пользуясь его стеком. Но эти же функции используют сегмент данных, принадлежащий библиотеке, а не копии приложения.
В силу такой организации DLL, экономия памяти достигается за счет того, что все запущенные приложения используют один модуль DLL, не включая те или иные стандартные функции в состав своих модулей.
Часто, в виде DLL создаются отдельные наборы функций, объединенные по тем или иным логическим признакам, аналогично тому, как концептуально происходит планирование модулей ( в смысле unit ) в Pascal. Отличие заключается в том, что функции из модулей Pascal компонуются статически - на этапе линковки, а функции из DLL компонуются динамически, то есть в run-time.
Таким образом, DLL позволяют:
- избежать громоздкости исполняемого кода прикладной программы;
- улучшить структурированность и модульность приложения;
- уменьшить занимаемый приложением объем памяти за счет того, что несколько одновременно выполняющихся программ могут использовать одну и ту же копию подпрограммы из DLL, при этом в памяти будет физически загружена только одна копия библиотеки;
- использовать любую библиотеку в любых программах, не зависимо от того, на каком языке была написана программа и библиотека.
DLL являются одними из наиболее важных ключевых элементов при написании любого приложения Windows. Само ядро Windows представлено тремя большими по объему динамическими библиотеками: KERNEL.DLL, USER.DLL и GDI.DLL. Файл KERNEL.DLL, например, отвечает за управление памятью, процессами и потоками; USER.DLL содержит функции интерфейса пользователя, необходимые для создания окон и обработки сообщений Windows; на GDI.DLL возложена работа с графикой. Общее количество используемых самой Windows динамических библиотек составляет порядка двух тысяч.
В курсовом проекте также используется методика смешанного программирования. Так подынтегральные функции, используемые для расчета интегралов вынесены в отдельную динамическую библиотеку functions.dll. Численные методы вынесены также в отдельную библиотеку integrals.dll.
В основной программе используется динамическая загрузка dll-библиотек. Весь процесс загрузки библиотек вынесен в отдельную процедуру, листинг которой приведен на рисунке 10.
procedure TMainForm.LoadDlls;
var
x: real;
begin
IntegralsDll:=LoadLibrary('Integrals.dll');
FunctionsDll:=LoadLibrary('Functions.dll');
if IntegralsDll=0 then
begin
Application.MessageBox('Ненайденмодуль ''Integrals.dll''.
Работа приложения будет прекращена',
'Ошибка!!!', MB_Ok or MB_ICONERROR);
Application.Terminate;
end;
if FunctionsDll=0 then
begin
Application.MessageBox('Ненайденмодуль ''Functions.dll''. Работаприложениябудетпрекращена',
'Ошибка!!!', MB_Ok or MB_ICONERROR);
Application.Terminate;
end;
@Simpson:=GetProcAddress(IntegralsDLL,'Simpson');
@CountTrap:=GetProcAddress(IntegralsDLL,'CountTrap');
if (@CountTrap=nil) or (@Simpson=nil) then
begin
Application.MessageBox('Ошибкавмодуле ''Integrals.dll''.
Работа приложения будет прекращена',
'Ошибка!!!', MB_Ok or MB_ICONERROR);
Application.Terminate;
end;
@Integral1Function:=GetProcAddress(FunctionsDLL,'Integral1Function');
@Integral2Function:=GetProcAddress(FunctionsDLL,'Integral2Function');
if (@Integral1Function=nil) or (@Integral1Function=nil) then
begin
Application.MessageBox('Ошибкавмодуле ''Functions.dll''.
Работа приложения будет прекращена',
'Ощибка!!!', MB_Ok or MB_ICONERROR);
end;
2.9 Контроль неквалифицированных действий пользователя
В приложении предусмотрен контроль за неквалифицированными действиями пользователя. Программа разработана таким образом, чтобы при любых действиях пользователя не возникало сбоя в программе.
Выполнение данной задачи достигалось путем использования структурной обработки исключительных ситуаций- системы, позволяющей программисту при возникновении ошибки (исключительной ситуации) связаться с кодом программы, подготовленным для обработки такой ошибки. Это выполняется с помощью языковых конструкций, которые как бы “охраняют” фрагмент кода программы и определяют обработчики ошибок, которые будут вызываться, если что-то пойдет не так в “охраняемом” участке кода. В данном случае понятие исключительной ситуации относится к языку и не нужно его путать с системными исключительными ситуациями (hardware exceptions), такими как General Protection Fault. Исключительные ситуации в Delphi же независимы от “железа”, не используют прерываний и используются для обработки ошибочных состояний, с которыми подпрограмма не готова иметь дело. Системные исключительные ситуации, конечно, могут быть перехвачены и преобразованы в языковые исключительные ситуации, но это только одно из применений языковых исключительных ситуаций.