|
cu DeleteObject in momentul in care nu mai sunt necesare.Numarul mare
|
səhifə | 11/24 | tarix | 03.11.2017 | ölçüsü | 2,15 Mb. | | #28851 |
| cu DeleteObject in momentul in care nu mai sunt necesare.Numarul mare
de parametri permite modelarea fonturilor dupa bunul plac,sau dupa nece-
sitatile de spatiu din aplicatia in care vor fi utilizate.
Pentru a adauga si putina culoare,se pot utiliza functiile SetBkColor si
respectiv SetTextColor,iar pentru a distanta caracterele se poate apela
functia SetTextCharacterExtra.
EXEMPLU: program fonturi2
usesWinCRT,WinProcs;
var P:PChar;
y,z,f1:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
f1:=CreateFont(60,20,150,160,700,1,1,0,255,1,1,1,0,P);
SelectObject(z,f1);
SetBkColor(z,RGB(50,250,50));
SetTextColor(z,RGB(250,10,10));
SetTextCharacterExtra(z,5);
TextOut(z,10,200,'Fonturi Personalizate',21);
DeleteObject(f1);
end.
Observati ca textul poate fi si inclinat cu un unghi oarecare,prin modi-
ficarea celui de al treilea parametru din CreateFont(150).Incercati sa
schimbati succesiv valorile parametrilor pana cand obtineti efectul dorit.
Se pot utiliza mai multe randuri de fonturi,la fel ca si pensulele sau
penitele grafice,dar nu uitati sa eliberati obiectele,in momentul in care
nu mai sunt necesare.Eventual utilizati functii constructor pentru crearea
obiectelor grafice si apoi functii destructor pentru eliberarea lor(doar
atunci cand utilizati repetat un numar mai mare de obiecte grafice).
Eventual constructorul si destructorul pot forma un modul independent.
-80-
Pentru a programa interfata grafica,sau pentru diverse aplicatii,se pot
utiliza si functii mult mai discriminative,cum sunt GetPixel si SetPixel,
care permit selectarea nuantei de culoare pentru fiecare pixel de pe
suprafata grafica.
EXEMPLU: program pixeli2;
uses WinCRT,WinProcs;
var y,z,nr1,nr2:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
Randomize;
for nr1:=1 to 20 do
begin
for nr2:=1 to 20 do
begin
SetPixel(z,nr1*nr1,nr2*nr2,RGB(250,10,10));
SetPixel(z,nr1+5*nr2,nr1+nr2,RGB(10,10,250));
end;
end;
end.
Exemplul de mai sus prezinta dispersia valorilor pentru o functie simpla
fata de o grila de coordonate liniare,Se poate observa fiecare valoare
reprezentata printr-un pixel (albastru).
Functia se poate insa utiliza si pentru a grupa un numar mai mare de
pixeli cu scopul de a forma un anumit efect grafic,sau pentru a forma
un anumit model de culoare marmorata sau patata,etc...
EXEMPLU: program pixeli1;
uses WinCRT,WinProcs;
var y,z,nr1,nr2:Integer;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
Randomize;
for nr1:=1 to 200 do
begin
for nr2:=1 to 200 do
begin
SetPixel(z,nr1,nr2,RGB(250,Random(250),10));
SetPixel(z,nr1,nr2,RGB(10,Random(250),250));
end;
end;
end.
Pentru efecte complexe de animatie,desenele realizate pixel cu pixel sunt
preluate sub forma de bitmap si apoi sunt prelucrate cu alte functii,
pentru a obtine diferite efecte speciale.Functiile la nivel de bit sunt
insa extrem de utile pentru reprezentarea grafica a functiilor matematice,
pentru prezentarea modului de dispersie la un grup de valori aleatorii,
pentru reprezentarea datelor statistice sub forma de multimi de de valori,
sau pentru realizarea unor obiecte grafice personalizate etc.
-81-
Obiectele grafice create pentru un anumit dispozitiv grafic pot fi salvate
intr-o metafila cu ajutorul functiei CreateMetafile.Ulterior dupa inchi-
derea filei astfel create cu CloseMetaFile,fila de obiecte poate fi reape-
lata cu ajutorul functiei PlayMetaFile,astfel incat obiectele grafice sa
poata fi utilizate in alt context de dispozitiv (alta fereastra,imprimanta
etc.).Dupa epuizarea operatiilor grafice,fila se elibereaza cu functia
DeleteMetaFile,pentru a elibera memoria.
EXEMPLU: program metafila1;
uses WinCRT,WinProcs;
var y,z,h,p,f,f1,w,c:integer;
v:boolean;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
RoundRect(z,100,100,300,300,100,300);
h:=CreatePen(1,3,RGB(200,10,20));
p:=CreateSolidBrush(RGB(100,200,10));
SelectObject(z,p);
Floodfill(z,200,200,0);
SelectObject(z,h);
Rectangle(z,200,100,206,70);
f:=CreateMetaFile(NIL);
f1:=CloseMetaFile(f);
writeln('Apasati orice tasta:');
readln;
w:=Create Window('Edit','M1',5,10,10,400,300,0,0,hInstance,Nil);
ShowWindow(w,4);
UpdateWindow(w);
c:=GetDC(w);
rectangle(c,100,100,200,200);
v:=PlayMetaFile(c,f1);
SelectObject(c,h);
SelectObject(c,p);
Ellipse(c,20,20,100,100);
DeleteObject(p);
DeleteObject(h);
DeleteObject(f);
DeleteObject(f1);
DeleteMetafile(f1);
end.
Observati ca am transferat cu ajutorul metafilei create,obiectele grafice
din fereastra initila in fereastra M1 nou creata.Daca metafila este creata
cu parametrul Nil (ca in exemplu),atunci ea va fi salvata doar in memoria
de operare si poate fi apelata doar in cursul executiei.Daca se utilizeaza
un pointer de tip PChar,metafila poate fi salvata pe disc,iar obiectele
grafice vor putea fi utilizate in orice alt program,prin apelarea filei
cu PlayMetaFile(numele filei).Acest procedeu este mai simplu si mai econo-
micos decat operatiile cu arii bitmap.Exista si alte functii care opereaza
cu metafile(GetMetaFile,EnumMetafile,etc.).Nu uitati sa eliberati din me-
morie metafilele care nu vor mai fi utile in program !.
-82-
Pentru realizarea unor efecte grafice speciale,se pot utiliza functii care
realizeaza un anumit aspect grafic pentru o anumita zona de ecran.Astfel
functia FrameRgn deseneaza in culoarea pensulei specificate un chenar de
grosimea dorita.
EXEMPLU: program frame1;
uses WinCRT;WinProcs;
var y,z,R1,R2,B1,B2:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
R1:=CreateRectRgn(50,50,150,150);
R2:=CreateRectRgn(250,50,350,150);
B1:=CreateSolidBrush(RGB(250,10,10));
B2:=CreateSolidBrush(RGB(10,10,250));
FrameRgn(z,R1,B1,20,20);
Frame(z,R2,B2,30,30);
end.
Observati ca functia traseaza chenarul spre interiorul regiunii definite,
astfel incat,daca inaltimea si grosimea chenarului sunt destul de mari,
intreaga regiune va fi colorata in culoarea pensulei.
O functie asemanatoare este ExtTextOut,care scrie un sir de caractere
in interiorul unei suprafete rectangulare pe care o coloreaza in culoarea
de fond setata prin SetBkColor.
EXEMPLU: program exttext1;
uses WinCRT,WinProcs,WinTypes;
var S:string;
R:TRect;
P:PChar;
y,z:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
S:=' Text scris in chenar ';
P:=$S;
R.left:=20
R.top:=100;
R.right:=250;
R.bottom:=200;
SetBkColor(z,RGB(90,220,90));
SetTextColor(z,RGB(10,10,250));
ExtTextOut(z,70,150,2,Ptr(Seg(R),Ofs(R)),P,22,Nil);
end.
Observati ca pentru descrierea chenarului am utilizat o structura de tip
TRect spre care am orientat un pointer cu ajtorul functiei Ptr.In chenarul
astfel realizat se pot introduce siruri succesive,la fel ca intr-un obiect
grafic.Functia are si optiunea prin care sirurile pot fi trunchiate auto-
mat la lungimea suprafetei active(in parametrul 4, optiunea=1).In chenar
se pot introduce si fonturi personalizate,sau la distente specificate prin
o arie de puncte de coordonate incluse in ultimul parametru al functiei.
-83-
Unitatea WinProcs contine si alte functii GDI,destinate pentru a realiza
o interfata grafica cu utilizatorul.Descifrarea si aplicarea acestora va
fi un exercitiu extrem de util pentru cititori.Unele dintre functii,au un
numar destul de mare de parametrii,dar cu putina rabdare se poate descifra
semnificatia si rostul fiecaruia dintre ei.Este extrem de important ca
fiecare viitor programator sa poata lucra singur,cu manualul Help.Nu va
rezumati sa copiati exemplele prezentate.Dezvoltati cat mai multe exemple
sau aplicatii asemenatoare.Pastrati toate programele si exercitiile fun-
ctionale,nu se stie cand va vor fi de folos.Daca sunteti mai avansati in
programare,dezvoltati functii,proceduri,algoritmi sau chiar unitati pe
care sa le puteti apoi include in programele viitoare.
MENIURI SI POPUPURI
Un prim pas pentru trecerea de la programarea liniara,la cea structura-
ta il reprezinta formarea si utilizarea barelor de meniuri si a meniurilor
popup,care permit prin simpla selectare cu mouse-ului a unei pictograme
grafice,punerea in executie a unui algoritm sau chiar a unui program.
Se pot utiliza obiecte gata definite (meniuri standardizate),sau se
pot construi meniuri personalizate,adaptate dorintelor si necesitatilor de
moment ale programatorului.Chiar daca dispuneti de o colectie impresio-
nanta de obiecte gata definite,este bina sa stiti sa programati un meniu,
sau un meniu popup,cu care sa puteti executa unul sau mai multe programe.
Meniurile se includ intr-o anumita fereastra,care poate fi creata de
catre programator,sau poate fi o fereastra standard,predefinita,preluata
din unitatea de resurse OWindows.Fereastra care va contine meniul,nu numai
ca poate fi creata,dar poate fi si deplasata sau redimensionata,cu aju-
torul functiei MoveWindow.
EXEMPLU: program window1;
uses WinCRT,WinProcs;
var y,z,n:integer;
begin
InitWinCRT;
y:=CreateWindow('LISTBOX','Text',5,10,10,200,200,hInstance,Nil);
z:=GetDC(y);
ShowWindow(y,4);
UpdateWindow(y);
for n:=1 to 8 do
begin
MoveWindow(y,n*30,n*30,200-10*n,200-10*n,FALSE);
TextOut(z,10,30,'Text scris in fereastra !',25);
TextOut(z,10,80,'Tastati ENTER !',15);
readln;
end;
DestroyWindow(y);
end.
Fereastra creata este afisata cu ShowWindow,actualizata cu UpdateWindow
si la final este eliberata din memorie (distrusa) cu DestroyWindow.
Fereastra care va fi aleasa ca gazda pentru meniul creat trebuie sa fie
dimensionata si amplasata astfel incat accesul la meniu sa fie cat mai
simplu si cat mai facil (toate optiunile sa fie vizibile).
-84-
Pentru a inchide o fereastra,se poate utiliza fie patratelul din coltul
stanga sus al ferestrei,fie functia CloseWindow.Fereastra va fi minimi-
zata si pastrata pe bara de jos a ecranului,de unde poate fi reafisata
cu functia ShowWindow.Se utilizeaza pentru a elibera ecranul.
EXEMPLU: window2;
uses WinCRT,WinProcs;
var y,n:integer;
t1,t2:longint;
begin
InitWinCRT;
y:=GetActiveWindow;
for n:= 1 to 3 do
begin
writeln('Tastati ENTER !');
ShowWindow(y,4);
readln;
CloseWindow(y);
t1:=GetCurrentTime;
repeat
t2:=GetCurrentTime;
until t2>(t1+2000);
end;
ShowWindow(y,4);
writeln('Inchideti fereastra);
end.
Bucla repeat...until creaza o intarziere de 2 secunde (2000 de miimi),
astfel incat operatia de minimizare sa fie usor de evidentiat.
Pentru crearea unui meniu sunt necesare functiile CreateMenu,AppendMenu
si SetMenu,la care se adauga optional HiliteMenuItem.
Exemplu: program meniu1;
uses WinCRT,WinProcs,WinTypes;
var y,m:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
ShowWindow(y,4);
UpdateWindow(y);
m:=CreateMenu;
AppendMenu(m,MF_STRING,1,'Optiunea 1');
AppendMenu(m,MF_STRING,2,'Optiunea 2');
SetMenu(y,m);
HiliteMenuItem(y,m,1,MF_HILITE);
DestroyMenu(m);
end.
Observati ca meniul ramane afisat si dupa eliberarea din memorie,dar nu
mai poate fi activat.Prima optiune este afisata ca si cand ar fi fost
selectata,deoarece am apelat functia HiliteMenuItem.
Asadar,crearea unui meniu este extrem de simpla.Aplicarea si utilizarea
meniului este insa putin mai comlexa si face apel la sistemul de mesaje
automate prin care sistemul Windows contabilizeaza fiecare actiune sau
comanda,fiecare tasta sau deplasare ori activare a mouse-ului etc.
-85-
Sistemul de operare Windows,este un sistem complex,care tine evidenta
permanenta a unui numar foarte mare de parametri interni,dar si al tutu-
ror operatiilor executate de utilizator.Pentru fiecare operatie,sistemul
elibereaza un mesaj,care se va aduna sub forma de stiva,intr-un tampon
de memorie special creat,care se asociaza cu fiecare fereastra activa.
Astfel,se poate reconstitui cronologic fiecare actiune,se poate stabili
ordinea operatiilor care au avut loc succesiv dar in ferstre diferite,
sau se poate realiza comunicarea dintre doua sau mai multe programe care
se deruleaza in paralel dar in ferestre diferite.Acest sistem de mesaje,
ofera sistemului Windows o superioritate neta fata de alte sisteme,
deoarece permite supravegherea proceselor si cooperarea dintre programe.
Mesajele Windows referitoare la operatiile dintr-o fereastra sunt de fapt
niste constante,al caror nume incepe cu WM_xxx(EXEMPLE: WM_ACTIVATE,
WM_CHAR,WM_CLEAR,WM_CLOSE,WM_COMMAND,WM_COPY,WM_CREATE,WM_DESTROY,
WM_ENABLE,WM_INITMENU,WM_KEYDOWN,WM_MOVE,WM_PAINT,WM_QUIT,WM_SIZE,WM_TIMER
etc. ).
Pentru fiecare operatie din fereastra,sistemul elibereaza un astfel de
mesaj,care sa va adauga in stiva de memorie sub forma de lant de operatii.
Cu ajutorul acestor mesaje,sistemul stie daca o fereatra a fost creata,
afisata,deplasata,inchisa sau actualizata si in ce moment exact anume.
Pentru a identifica cel mai recent mesaj eliberat de sistem de poate
utiliza functia GetMesage.
EXEMPLU: program window3;
uses WinCRT,WinProcs,WinTypes;
var y,z,m:integer;
MS:TMSG;
begin
InitWinCRT;
GetMesaage(MS,0,0,30000);
writeln('Codul ferestrei este:',MS.hwnd);
writeln('Parametrul wParam este:',MS.wParam);
writeln('Byte-ul inferior lParam=',LOWORD(MS.lParam));
writeln('Byte-ul superior lParam=',HIWORD(MS.lParam));
writeln('timpul sistemului este:',MS.time);
writeln('Pozitia x pt. mouse este:',MS.pt.x);
writeln('Pozitia y pt. mouse este:',MS.pt.y);
end.
Functia utilizeaza o structura de tip TMSG (definita in WinTypes) in care
arhiveaza parametrii de mai sus.La apelarea functiei,se vor citi din
stiva ultimi parametri arhivati la tipul respectiv.Pentru parametrii de
tip word se pot utiliza functiile LOWORD si HIWORD pentru a separa cele
doua valori aferente byte-ului inferior si respectiv superior din word.
Dupa cum se observa in paramterul time,timpul este determinat in miimi
de secunda (vezi GetCurrentTime),astfel incat gradul de discriminare
dintre doua operatii succesive este de ordinul unei miimi de secunde in
ceea ce priveste momentul executiei unei anumite operatii.Fiecare operatie
va determina eliberarea unui anumit mesaj,care va modifica valoarea unuia
dintre acesti parametri.In cazul concret al meniurilor,prin selectarea
unuia dintre meniuri se elibereaza mesajele: WM_COMMAND,WM_INITMENU si
WM_MENUSELECT care vor modifica parametrul wParam,astfel incat sa se poata
identifica meniul care a fost selectat cu ajutorul mouse-ului.
-86-
Un exercitiu extrem de intuitiv este urmatorul:
EXEMPLU: program window5;
uses WinCRT,WinProcs,WinTypes;
var y,z,m:integer;
MS:TMSG;
begin
InitWinCRT;
y:=GetActiveWindow;
for m:=1 to 10 do
begin
clrscr;
writeln('Deplasati mouse-ul(fara click) si tastati ENTER !');
GetMessage(MS,0,0,30000);
writeln('Pozitia mouse-ului este:');
writeln('x=',MS.pt.x);
writeln('y=',MS.pt.y);
readln;
end;
end.
Utilizand sistemul de mesaje,optiunile meniului pot fi selectate si acti-
vate succesiv,utilizand o bucla de repetitie pentru citirea mesajelor.
EXEMPLU: program window4;
uses WinCRT,WinProcs,WinTypes;
var y,z,m:integer;
MS:TMSG;
t1,t2:longint;
begin
InitWinCRT;
y:=GetActiveWindow;
z:=GetDC(y);
ShowWindow(y,4);
UpdateWindow(y);
m:=Createmenu;
AppendMenu(m,MF_STRING,1,'Optiunea 1');
AppendMenu(m,MF_STRING,2,'Optiunea 2');
SetMenu(y,m);
t1:=GetCurrentTime;
repeat
GetMessage(MS,0,0,30000);
TranslateMessage(MS);
DispatchMessage(MS);
if MS.wParam=1 then
writeln('Meniul 1 a fost activat !');
if MS.wParam=2 then
writeln('Meniul 2 a fost activat !');
until t2>(t1+5000);
writeln('Inchideti fereastra !');
DestroyMenu(m);
end.
In intervalul de 5 secunde al buclei de repetitie,selectati cu mouse-ul
cele doua optiuni,pentru a sesiza modul de activare.
-87-
Meniurile popup pot fi create cu CreatePopup si pot fi izolate sau pot fi
atasate unei bare de meniuri.Se afiseaza cu SetMenu sau TrackPoupupMenu.
EXEMPLU: program meniu2;
uses WinCRT,WinProcs,WinTypes;
var y,m,p1,p2:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
ShowWindow(y,4);
UpdateWindow(y);
p1:=CreatePopupMenu;
p2:=CreatePopupMenu;
AppendMenu(p1,MF_STRING,7,'Popup 1');
AppendMenu(p2,MF_STRING,8,'Popup 1');
SetMenu(y,p1);
TrackPopupMenu(p2,1,200,200,0,y,Nil);
DestroyMenu(p1);
DestroyMenu(p2);
end.
Pentru a atasa un meniu popup la o bara de meniuri,AppendMenu va utiliza
flag-ul MF_POPUP pentru meniul la care se va atasa meniul popup.
EXEMPLU: program meniu3;
uses WinCRT,WinProcs,WinTypes;
var y,m,p:integer;
begin
InitWinCRT;
y:=GetActiveWindow;
ShowWindow(y,4);
UpdateWindow(y);
m:=Createmenu;
p:=CreatePopupMenu;
Dostları ilə paylaş: |
|
|