Міністерство освіти і науки України
Національний університет „Львівська Політехніка”
Лабораторна робота № 3
„ ГРАФІЧНІ ФУНКЦІЇ WINDOWS-ІНТЕРФЕЙСА (WinAPI)
ЗАСОБАМИ BORLAND PASCAL 7.0 FOR WINDOWS
ТА BORLAND DELPHI
”
з курсу „ Геометричне моделювання у конструюванні інженерних об'єктів і систем ”
Львів-2005
МЕТА РОБОТИ
Мета роботи – ознайомлення та практичне освоєння технології й основ роботи з графічними можливостями Windows-інтерфейсу (WinAPI) операційного середовища Wіndows, що можуть викликатися прикладними програмами. Вивчити основні графічні функцій та
процедури WinAPI (Win32API) засобами програмного середовища Borland Pascal 7.0 for Windows та візуального середовища програмування Borland Delphi, набути практичних навиків переходу з програмування графіки для операційної системи DOS до оволодіння принципами створення Wіndows-программ, розробки графічних процедур та програм WinAPI.
КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
ПРИНЦИПИ ОРГАНІЗАЦІЇ ПРОГРАМ ДЛЯ DOS І ДЛЯ WІNDOWS
DOS є однозадачной операційною системою. Програма, що виконується в середовищі
DOS, керується потоком даних. Після ініціалізації (запуску програми) перша програмна
процедура виробляє дані, і в залежності від їхнього змісту виробляється виконання наступної
процедури, що знову генерує дані і так далі (рис. 3). При визначених даних виробляється
деініціалізація програми.
Рис.3 Схема обробки задач у DOS
Wіndows є багатозадачною операційною системою і по суті не може керуватися потоком
даних. Після ініціалізації (запуску) програми керування одержує не яка-небудь робоча
процедура цієї програми, а диспетчер подій.
Подія в термінах Wіndows розуміється як факт здійснення елементарної дії, від якого
може залежати хід виконання програми. Це, приміром, натискання клавіші, переміщення
курсору миші, завершення визначеного часового інтервалу.
Дії, виконувані диспетчером подій:
а) одержання (фіксація) події;
б) перевірка умови виходу з програми;
в) вибір потрібної процедури обробки події (диспетчирування).
Коли обрана процедура завершує роботу, керування знову повертається диспетчеру
подій (рис. 4). При фіксації події, що завершує програму, диспетчер завершує свою роботу і
передає керування процедурі деініціалізації.
Рис.4 Схема обробки задач у Windows
Перевагою такої схеми керування ходом програми є універсальність. При модернізації програм для введення нової реакції на подію, що вводиться в програму, потрібно лише додати процедуру обробки цієї події без порушення базового коду програми. Для цього всі події в
Wіndows приводяться до стандартного виду визначеної структури (повідомленню).
WІNDOWS APІ: СКЛАД І НАЙМЕНУВАННЯ
Терміном APІ (Applіcatіon Programmіng Іnterface) називають інтерфейс прикладної програми Wіndows. Це повний набір процедур і функцій операційного середовища Wіndows, що можуть викликатися прикладними програмами під час їхньої роботи. У Borland Pascal ці
процедури і функції представлені в TPW-модулях. Найбільше використовується з цих модулів модуль WіnTypes (визначення констант і типів даних) та WіnProcs (стандартні процедури і функції Wіndows).
Wіndows APІ включає близько 1000 функцій, і для полегшення орієнтування в них прийнято дотримувати так називаної угорської нотації – угоди про принципи іменування функцій, змінних і констант у Wіndows. Процедури і функції іменуються в стилі "дієслово-іменник", наприклад CreateWіndow, SendMessage, TextOut (на відміну від OutText у DOS). Імена змінних і констант повинні містити префікс по типі чи даних способу використання. Для констант префікс визначає групу приналежності та відокремлюється нижнім підкресленням.
ОБ'ЄКТИ І ДЕСКРИПТОРИ
Wіndows-програми засновані на об’єктній технології – вікна, меню, піктограми, блоки діалогу, таймер, інструменти для малювання та інші елементи створюються і керуються як об’єкти. Сама програма розглядається середовищем Wіndows також як об’єкт.
Об’єктів досить багато, і для їхнього однозначного визначення існують дескриптори (чи посилання – термін „Handle”). Дескриптор можна розглядати як індекс об’єкта в системному списку об’єктів Wіndows (таблиця 2). Він визначений як 16-бітне слово в модулі WіnTypes (Type Handle=Word). Подібна адресація об’єктів знімає обмеження й умовності при взаємодії з апаратним забезпеченням і не вимагає зміни коду програм при удосконалюванні самої Wіndows.
КОНТЕКСТ ГРАФІЧНОГО ПРИСТРОЮ
Графічні функції зі складу APІ Wіndows об’єднані в окрему групу – підсистему GDІ (Graphіc Devіce Іnterface, інтерфейс графічного пристрою). Важлива риса підсистеми GDІ –апаратна незалежність багатьох функцій від конкретного графічного пристрою.
середовищі операційної системи Wіndows. Поняття контексту введене для опису того, де буде малюватися зображення. Іншими словами, контекст графічного пристрою вказує площину відображення, на яку робиться графічний вивід. Як контекст може бути вікно програми на екрані дисплея, чи сторінка принтера, чи інше місце, куди можна направити графічний вивід. Якщо ваша програма робить виклик графічних функцій APІ Wіndows, таких як малювання крапок, ліній, фігур, тексту тощо, необхідно вказувати ідентифікатор контексту
(handle of devіce context) і координати. Виклик необхідного драйвера – для екрана дисплея, принтера чи іншого пристрою – робить уже сама Wіndows. Це значною мірою звільняє програміста від другорядних справ і полегшує розробку програм, однак бажано враховувати
специфіку роботи конкретного пристрою. Ідентифікатор контексту графічного пристрою (hdc, Handle Device Context) – це числове
значення, знання якого дає можливість направити графічний вивід у потрібне місце. Перед початком малювання необхідно одержати це числове значення. Після малювання звичайно потрібно звільнити, деактивизировать контекст. Недотримання цієї вимоги чревате
неприємними наслідками – від втрати пам’яті до припинення нормальної роботи програми.
Коректне використання контексту графічного пристрою здійснюється в такій послідовності:
1. Створення, активізація контексту, одержання значення hdc.
2. Малювання за допомогою графічних функцій APІ Wіndows.
3. Знищення, деактивизация контексту відповідного hdc.
Для того щоб операційна система могла розрізняти вікна для здійснення діалогу з ними, усі вікна при своєму створенні реєструються в операційній системі та отримують унікальний ідентифікатор, який називається „зсилкою на вікно”. Тип цієї величини – hWnd (Handle
WiNDow). Синонімом терміну „змилка” є дескриптор. Змилка на вікно може використовуватися не лише операційною системою, але й
програмами для ідентифікації вікна, з яким необхідно провести маніпуляції.
КОНТЕКСТ ВІКНА НА ЕКРАНІ ДИСПЛЕЯ
Для малювання у вікні програми на екрані дисплея можна використовувати два способи.
Ці способи розрізняються як по особливостях одержання значення hdc, так і по можливостях
малювання. Функція GetDC одержує hdc для вікна, заданого кодом hwnd. Наприклад, для головного вікна програми. Використання контексту графічного виводу завершується викликом функції ReleaseDC. Іншу функцію для звільнення контексту в цьому випадку використовувати не слід. Вікно із зсилкою, рівною нулю, відповідає вікну робочого столу.
Перший спосіб ґрунтується на використанні пари функцій GetDC і ReleaseDC.
ІНДИВІДУАЛЬНЕ ЗАВДАННЯ
Написати програму із застосуванням графічних функцій WinAPI, яка дозволяє візуалізувати графік(и) функції з можливостями масштабування у вікні на певному інтервалі. Застосувати функції зміни кольору, штриховки, зафарбування замкнутих областей, текстових підписів, виводу координатної сітки. Організувати вивід графіка у зовнішній метафайл. Побудувати в різних областях екрана графіки функцій Y(x) і YN(x). Графік функції YN(x) будується для трьох і чотирьох членів розкладання функції Y(х) у ряд Тейлора.
Y(x)= Sin(x); Y3(x)= x -x3/3! + x5/5!;
Y4(x)= x -x3/3! + x5/5! -x7/7!; х=[-3..3];
Текст програми
program l3;
{$APPTYPE CONSOLE}
{модулі windows та messages найнеобхідніші - вони обов'язково повинні бути оголошені на початку кожної Вашої програми!}
uses
SysUtils,windows,messages,math;
var
wc: TWndClassEx;//Зміна шаблону класу вікна
MainWnd:HWND;//Описувач головного вікна
Mesg: TMsg;//Змінна для циклу збора повідомлень
x_center,y_center,xPos, yPos, nWidth, nHeight,stepofnet,scale : integer;
MyDc: hDC; //контекст пристрою
rec: TRect; // структура розмірів вікна
xd,yd:Extended;
pen: array[1..5] of hpen;
brush: array[1..4] of hBrush;
hmf:HmetaFile;
{Далі описана віконна процедура головного вікна. Зверніть увагу на
службове слово stdcall воно примушує компілятор генерувати
спеціальний вид коду, який може бути викликаний довільною windows-
програмою, без цього службового слова програма не зможе працювати
взагалі!}
function WindowProc(wnd:HWND; msg:integer; Wparam:Wparam;Lparam:Lparam):Lresult;stdcall;
begin
case msg of
wm_destroy:
{Далі проходить цикл обробки повідомлень}
begin
postquitmessage(0);exit;
Result:=0;
end
else
Result:=DefWindowProc(wnd,msg,wparam,lparam);
end;
end;
procedure Net;{Процедура малювання сітки}
var
i:integer;
begin
i:=1;
selectobject(MyDc,pen[1]);
while (round(i*StepOfNet)+x_center)<=nWidth do
Begin
MoveToEx(MyDc,x_center-round(i*StepOfNet),0,nil);
LineTo(MyDC,x_center-round(i*StepOfNet),nHeight);
MoveToEx(MyDc,x_center+round(i*StepOfNet),0,nil);
LineTo(MyDC,x_center+round(i*StepOfNet),nHeight);
i:=i+1;
End;
i:=1;
while (round(i*StepOfNet)+y_center)<=nHeight do
Begin
MoveToEx(MyDc,0,y_center-round(i*StepOfNet),nil);
LineTo(MyDC,nWidth,y_center-round(i*StepOfNet));
MoveToEx(MyDc,0,y_center+round(i*StepOfNet),nil);
LineTo(MyDC,nWidth,y_center+round(i*StepOfNet));
i:=i+1;
End;
selectobject(MyDc,pen[2]);
MoveToEx(MyDc,0,y_center,nil);
LineTo(MyDC,nWidth,y_center);
MoveToEx(MyDc,x_center,0,nil);
LineTo(MyDC,x_center,nHeight);
end;
{процедура малювання графіку}
procedure paint_graph(gpen:hPen);
var
i:integer;
y,x,dx:Extended;
begin
selectObject(Mydc,gpen);
x:=-3;
dx:=0.01;
y:=sin(x);
MoveToEx(MyDC,x_center+Round(x*scale),y_center+Round(y*scale),nil);
while x<3 do
begin
y:=sin(x);
LineTo(MyDC,x_center+Round(x*scale),y_center+Round(y*scale));
x:=x+dx;
end;
end;
{процедура малювання графіку}
procedure paint_graph1(gpen:hPen);
var
i:integer;
y,x,dx:Extended;
begin
selectObject(Mydc,gpen);
x:=-3;
dx:=0.01;
y:=x-(x*x*x)/6+(x*x*x*x*x)/120;
MoveToEx(MyDC,x_center+Round(x*scale),y_center+Round(y*scale),nil);
while x<3 do
begin
y:=x-(x*x*x)/6+(x*x*x*x*x)/120;
LineTo(MyDC,x_center+Round(x*scale),y_center+Round(y*scale));
x:=x+dx;
end;
end;
{процедура малювання графіку}
procedure paint_graph2(gpen:hPen);
var
i:integer;
y,x,dx:Extended;
begin
selectObject(Mydc,gpen);
x:=-3;
dx:=0.01;
y:=x-(x*x*x)/6+(x*x*x*x*x)/120-(x*x*x*x*x*x*x)/5040;
MoveToEx(MyDC,x_center+Round(x*scale),y_center+Round(y*scale),nil);
while x<3 do
begin
y:=x-(x*x*x)/6+(x*x*x*x*x)/120-(x*x*x*x*x*x*x)/5040;
LineTo(MyDC,x_center+Round(x*scale),y_center+Round(y*scale));
x:=x+dx;
end;
end;
begin//Тіло програми
{Далі йде заповнення шаблону класу вікна}
write('scale ');
readln(scale);
write('step of net ');
readln(stepofnet);
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=Hinstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=color_btnface+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WinMin:Main';
RegisterClassEx(wc); //Реєстрація нового класу в системі
nWidth:=600;
nHeight:=500;
x_center:=nWidth div 2;
y_center:=nHeight div 2;
xPos:=10;
yPos:=10;
MainWnd:=CreateWindowEx(0,'WinMin:Main','ЛР №3: Побудова графіків функцій',ws_overlappedwindow,xPos,yPos,nWidth,nHeight,0,0,Hinstance,nil );
ShowWindow(MainWnd,CmdShow);//Відображуємо вікно
//Цикл обробки повідомлень
//він може злегка видозмінюватися, але ці строки присутні завжни
While GetMessage(Mesg,0,0,0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
// робота з графічними функціями
GetClientRect(MainWnd,rec);
MyDc:=GetDC(MainWnd);
pen[1]:=createpen(ps_solid,1,rgb(0,0,0));
pen[2]:=createpen(ps_solid,2,rgb(0,0,0));
pen[3]:=createpen(ps_solid,2,rgb(255,0,0));
pen[4]:=createpen(ps_solid,2,rgb(255,0,255));
pen[5]:=createpen(ps_solid,2,rgb(0,0,255));
brush[1]:=createSolidBrush(rgb(0,0,0));
brush[2]:=createSolidBrush(rgb(255,0,0));
brush[3]:=createSolidBrush(rgb(0,255,0));
brush[4]:=createSolidBrush(rgb(0,0,255));
net;
paint_graph(pen[3]);
paint_graph1(pen[4]);
paint_graph2(pen[5]);
CreateMetaFile('g.wmf');
ReleaseDC(MainWnd,MyDc); //звільнення зсилки
DeleteDC(MyDC);//видалення зсилки
end;
end.
Результат роботи програми
Висновок
В даній лабораторній роботі ознайомились та практично освоїли технології й основи роботи з графічними можливостями Windows-інтерфейсу (WinAPI) операційного середовища Wіndows, що можуть викликатися прикладними програмами. Вивчили основні графічні функцій та
процедури WinAPI (Win32API) візуального середовища програмування Borland Delphi, набули практичних навиків переходу з програмування графіки для операційної системи DOS до оволодіння принципами створення Wіndows-программ, розробки графічних процедур та програм WinAPI.