|
void Fer1::Paint(TDC& dc,bool,TRect&)
|
səhifə | 16/18 | tarix | 12.09.2018 | ölçüsü | 1,36 Mb. | | #81721 |
| void Fer1::Paint(TDC& dc,bool,TRect&)
{ dc.TextOut(50,100,"Primul rand de text....",25);
dc.TextOut(50,150,"Al doilea rand de text...",25);
dc.Ellipse(50,250,100,300);dc.Ellipse(250,250,300,300); };
class Aplicatie1 : public TApplication {
public: Aplicatie1() : TApplication() {};
void InitMainWindow(); };
void Aplicatie::InitMainWindow()
{ MainWindow = new TFrameWindow(0,"Test",new Fer1()); };
int OwlMain(int,char* []) { return Aplicatie1().Run(); }
-104-
Proiectul nu poate fi compilat ca atare,deoarece C++ nu are legaturi
directe cu porturile de iesire si nu poate apela direct imprimanta.Pentru
a putea realiza legatura fizica cu dispozitivele de iesire,trebuie editata
o procedura in assembler,sau trebuiesc apelate resursele sistemului de
operare Windows.
O parte din resursele utilizate pentru obiectele TPrintout si TPrinter
sunt incluse in fila owl/printer.rc.Pentru a include si aceste resurse
editati fila de resurse (fila owl38.rc) astfel:
#ifndef WORKSHOP_INVOKED
#include
#endif
#include
#include
#include
#include
Optional,puteti adauga un meniu,icon etc...
Fila owl38.def nu este necesara.Puteti elimina aceasta fila din proiect,
sau puteti utiliza fila default,din directorul LIB(redenumita owl38.def).
In plus fata de celelalte proiecte,pentru a putea avea acces la calea
fizica(porturile de imprimanta),este necesar ca procesul de compilare si
constructie sa fie dirijat de o fila de tip "makefile".Utilizati orice
editor de text,pentru a scrie urmatoarea fila:
MODELS = ldft
EXERES = prntprev
!include $(BCEXAMPLEDIR)\owlmake.gen
Copiati fila in directorul owl38 cu numele de makefile.Puteti utiliza fila
din exemplu,sau puteti edita o fila noua.
In mod normal,procesul de compilare a proiectului utilizeaza o rutina
automata pentru generarea filei de tip MAKE (puteti verifica cu optiunea
Generate makefile din meniul Project).Pentru a utiliza o fila makefile
editata de d-voastra,trebuie inactivata aceasta rutina automata.Pentru
acest scop,executati un click de mouse cu butonul drept pe fila owl38.exe
din proiect si alegeti optiunea "View options hierarchy".In fereastra
Options Hierarchy alegeti nodul owl38.exe si apoi apasati butonul Edit.
In fereastra Project Options,din Topics alegeti Make si apoi dintre
optiunile casetei Autodependencies (butoane radio) selectati optiunea
"None".Confirmati cu OK,si apoi iesiti din setari cu butonul Close.
In acest moment,directorul proiectului trebuie sa contina filele:
owl38.cpp,owl38.rc si fila makefile.Compilati,construiti si apoi utilizati
optiunea Make node,pentru a finaliza proiectul.Apoi executati aplicatia.
In momentul in care imprimanta este pregatita pentru scriere,inchideti
fereastra si imprimarea va incepe imediat.
Din economie de spatiu,am introdus comanda de imprimare in destructorul
ferestrei,astfel incat imprimarea sa inceapa doar dupa inchiderea feres-
trei.O solutie mult mai eleganta este sa utilizati un meniu,sau un buton
pentru declanasarea functiei Scrie().Pentru a utiliza ferestrele de
dialog,se poate utiliza metoda TPrinter.Setup(this),respectiv metoda
TPrinter.Print() cu optiunea TRUE.Atentie: TPrinter.Print() apeleaza auto-
mat metoda Print.Daca se include aceasta metoda in Print() se va obtine o
-105-
bucla infinita in care Paint() apeleaza Print() iar Print() apeleaza
Paint().
Nu toate tipurile de imprimanta accepta setarile pentru Banding.Daca
utilizati o imprimata mai rudimentara,renuntati la aceasta setare.
Exemplul prezentat este rudimentar.Pentru a specifica parametrii de
imprimare,puteti utiliza toate metodele celor doua obiecte.
Metoda PrintPage() a fost definita pentru modul MM_ISOTROPIC,adica va
imprima datele asa cum sunt.Pentru a modifica aspecul se pot utiliza
toate metodele contextului de dispozitiv definite in fila dc.h.
Pentru a personaliza si mai mult proiectul,puteti utiliza si alte
optiuni din Project Options.Pentru a vedea toate optiunile posibile,
utilizati "View options hierarchy",apasati butonul Edit si apoi,pentru
fiecare optiune din Topics executati un click de mouse pe semnul plus (+).
Selectati fiecare optiune si observati se variante sunt.
Nu va jucati cu setarile.Daca efectuati modificari,notati fiecare mo-
dificare efectuata,astfel incat sa puteti reveni la setarile initiale.In
caz contrar,riscati sa dereglati ireversibil procesul de compilare.
EXEMPLU:
Daca efectuati un click pe Compiler se vor afisa urmatoarele optiuni:
Defines,Code generation,Floating Point,Compiler output,Source,Debugging
si Precompiled Headers.Alegeti Floating Point si selectati "Correct
Pentium FDIV flaw",sau respectiv "No floating point" (daca doriti sa
blocati utilizarea numerelor in virgula mobila).Optiunea implicita este
"Fast floating point".
Pentru a limita spatiul ocupat de proiectul d-voastra,puteti selecta
optiunea "Precompiled Headers" si puteti alege "Do not generate or use".
In acest caz,compilatorul nu va mai genera fila de tip .csm (destul de
voluminoasa) pe care o utilizeaza in situatiile de depanare automata.
Ca rezultat,proiectul va fi mult mai mic (portabil pe diskete).
Nu faceti nici o modificare,daca nu intelegeti exact care va fi rezul-
tatul obtinut.In orice caz,este bine sa aveti o schema cu setarile origi-
nale,pentru a putea reveni la valorile implicite.
In mod similar,puteti alege optiunea Messages,pentru a specifica ce
situatii doriti sa va fie semnalate de catre compilator.
EXEMPLU: Alegeti "Potential Errors" si bifati caseta "Ambiguous operators
need parantheses".In acest caz,in situatiile in care utilizati expresii
complexe,cu mai multi operatori,la care ordinea de precedenta este incerta
compilatorul va utiliza si acest mesaj de avertizare.
Pentru o orientare sumara,cititi si textul afisat imediat sub caseta
"Topics",pentru o explicatie sumara a variantelor respective.
Exista un numar destul de mare de variante posibile,astfel incat
pornind de la aceeasi fila sursa de tip .cpp se pot obtine o varietate de
file executabile,cu proprietati diferite.Asa se explica de ce doua pro-
iecte dezvoltate din aceeasi sursa,ruleaza sau executa programul final in
mod diferit (Exemplu: utilizeaza sau nu utilizeaza numerele cu virgula
mobila).Din acest motiv,atunci cand distribuiti programele realizate de
d-voastra,este bine sa includeti si fila de tip .ide in care sunt deja
setate toate optiunile necesare pentru executia optima.
Setarile astfel specificate,nu vor fi valabile decat pentru proiectul
respectiv.Pentru orice proiect nou,se vor utiliza setarile implicite.
-106-
Dupa specificarea setarilor,proiectul trebuie reconstruit cu Make all,
sau cu Make node.Pentru orice eventualitate,este bine sa detineti si o
copie de siguranta a filelor sursa,astfel incat proiectul sa poata fi
reconstruit de la zero.
Daca rezultatul obtinut nu este cel scontat,reconstruiti proiectul cu
aceleasi file sursa si utilizati setarile implicite,sau reluati procesul
de setare.
Pentru setarea optiunilor,se poate utiliza si meniul Options,respectiv
optiunea Project (vezi mai sus) sau optiunea Enviroment.
Pentru setarea optiunilor referitoare la mediul de operare,alegeti din
meniul Options,optiunea Enviroment.Se va afisa fereastra denumita :
"Enviroment Options" in care puteti modifica mediul de operare:
EXEMPLU: Alegeti SpeedBar (cu un click de mouse) si optiunea Customize:
In caseta Available Buttons alegeti butonul Browse Print si apoi apasati
butonul cu sageata orientata spre caseta Active Buttons.Butonul va trece
in caseta Active Buttons.Confirmati cu OK.Observati ca in meniul princi-
pal,in bara de obiecte SpeedBar a aparut un buton nou (inactivat).
Pentru a sterge butonul,se procedeaza invers.Alegeti butonul Browse Print
din caseta Active Buttons si utilizati butonul cu sageata orientata spre
caseta Available Buttons,apoi confirmati cu OK.
Pentru a alege fonturile si culoarea preferata,utilizati optiunea Fonts.
Pentru a modifica aspectul arborelui de directoare din fereastra Project,
alegeti Project View.De exemplu,daca selectati si casetele "Show run-times
node" si "Show project node",se vor afisa permanent si subdirectoarele
din proiect.
Pentru a modifica aspectul filei script (cea in care introduceti codu-
rile) alegeti Syntax Highlighting si optiunea Customize.Apoi alegeti
culoarea preferata pentru fiecare tip de element:
Exemplu: albastru pentru comentarii,rosu pentru cuvintele rezervate,
negru bold pentru identificator,albastru pentru siruri,verde pentru
preprocesor etc. Daca doriti,puteti utiliza si culori speciale pentru
background,dar,daca fila este prea incarcata de culori va fi mai greu de
citit.In fereastra Sample se va afisa un text cu culorile specificate de
d-voastra.Cand va declarati satisfacuti,confirmati cu OK.
In functie de nivelul de pregatire si de necesitatile de moment,puteti
modifica si celelalte optiuni ale mediului de operare.Nici o modificare
nu este ireversibila,sau daunatoare pentru calculatorul d-voastra.Este
bine sa va notati setarile preferate,astfel incat sa puteti sa reveniti
la ele cat mai usor.Nu apelati la cunoscuti,sau la necunoscuti pentru
"ajutor de specialitate".Nu lasati pe nimeni sa modifice neautorizat
optiunile din programul d-voastra.In situatii disperate,dezinstalati si
apoi reinstalati programul.
In mod normal,este bine sa pastrati o fila de siguranta pentru fiecare
fila generata.In momentul in care efectuati modificari,compilatorul sal-
veaza fila anterioara cu extensia .bak.La nevoie fila poate fi utilizata
pentru refacerea proiectului anterior (se redenumeste cu extensia .cpp).
In cazurile in care generati un numar foarte mare de file .cpp si un
numar mare de actualizari,la care nu doriti sa pastrati cate o copie de
tip .bak,pentru a face economie de memorie,puteti alege din Editor optiu-
nea File si apoi deselectati caseta "Create Backup".Este bine sa va ale-
geti un set de preferite,pe care sa le utilizati pentru toate proiectele.
-107-
PRELUCRAREA MESAJELOR WINDOWS - FUNCTIILE DISPECER (dispatch)
Aplicatiile de program realizate pentru sistemul de operare Windows,
difera radical de cele realizate sub sistemul de operare DOS.In Windows,
aplicatiile realizate nu sunt o insiruire de apeluri catre o anumita
functie sau procedura ci sunt controlate de catre sistemul de operare,
ca rezultat al evenimentelor din aplicatie.Orice aplicatie de tip Windows
este structurata modular.Cel mai simplu modul este fereastra Windows.O
aplicatie Windows lucreaza cu una sau mai multe ferestre.Ferestrele de
tip Windows nu apeleaza direct anumite functii,pentru a obtine un anumit
rezultat,ci asteapta sa fie apelate de catre sistemul de operare.Pentru
fiecare fereastra din aplicatie,sistemul distribuie periodic ( la cateva
nanosecunde-in functie de viteza procesorului) toate mesajele destinate
ferestrei respective.Pentru comunicarea cu sistemul de operare,fiecare
fereastra are o functie specializata,denumita procedura ferestrei(window
procedure),care va receptiona toate datele de intrare si respectiv va
returna catre sistem toate datele de iesire.
Sistemul Windows trimite datele de intrare pentru ferestre sub forma
de mesaje Windows.Mesajele pot fi generate atat de catre sistem,cat si de
catre aplicatia aflata in executie.Sistemul genereaza mesaje pentru fie-
care eveniment din program (Exemple: -deplasarea mouse,click de mouse,
apasarea unei taste...etc.),sau ca raspuns la orice modificare a datelor
din aplicatie (Exemple: -se schimba fonturile,se redimensioneaza fereastra
sau se deplaseaza fereastra...etc.).Aplicatia genereaza mesaje prin care
poate comunica cu alte ferestre,sau cu alte module din program (Exemple:
-se apasa un buton grafic din aplicatie ).
Fiecare mesaj Windows este format din patru elemente: un cod de manipu-
lare interna (window handle),un identificator (message identifier) si doi
parametri care preiau datele (LPARAM si WPARAM).
Codul handle identifica fereastra de destinatie a fiecarui mesaj.Iden-
tificatorul este o constanta prin care se specifica scopul mesajului emis.
(Exemplu: WM_PAINT inseamna ca fereastra va fi redesenata).Cei doi para-
metri (valori pe 32 de biti),contin datele transmise sau adresa de memorie
la care sunt localizate datele ce urmeaza sa fie utilizate pentru prelu-
crarea mesajului.Sensul si valoarea pentru fiecare parametru,difera de
la un mesaj la altul.Astfel,un paramteru poate contine un integer,o va-
loare binara,un pointer spre o adresa de memorie,sau orice alt tip de data
ce poate fi preluat de o valoare pe 32 de biti.Daca mesajul nu contine
nici o data,cei doi parametrii vor fi setati NULL.
Pentru a determina modul in care va fi interpretat fiecare mesaj,pro-
cedura de fereastra trebuie sa utilizeze identificatorul mesajului si o
functie de distributie (dispatch) care sa separe datele si pointerii din
fiecare parametru si sa le trimita catre functiile,procedurile sau meto-
dele interne ale ferestrei respective.
Daca exista un numar mic de mesaje,iar procesorul este liber,mesajele
vor fi transmise la ferestre instantaneu.Daca exista un numar mare de
mesaje emise simultan,mesajele vor fi arhivate temporar intr-o stiva,unde
asteapta sa le vina randul sa fie prelucrate si distribuite.Pentru ampla-
sarea mesajelor in stiva,sistemul utilizeaza o structira de tip MSG,iar
pentru a transmite si receptiona mesajele utilizeaza functii specializate
cum sunt:PostMessage,PeekMessage,GetMessage,WaitMessage etc.
-108-
In aplicatiile de tip API Windows,programul trebuie sa contina o
procedura specializata pentru prelucrarea mesajelor.Aceasta procedura
contine o bucla de repetitie (message loop) care utilizeaza ceasul intern
al procesorului pentru a receptiona si distribui periodic toate mesajele
din aplicatie.O astfel de bucla trebui sa contina urmatoarele functii:
1.GetMessage -copiaza din stiva mesajele arhivate si le preia tot intr-o
structura de tip MSG,de unde urmeaza sa fie prelucrate.Facultativ
se poat asocia si functii de eliberare a stivei,dupa prelucrare.
2.TranslateMessage - se utilizeaza atunci cand mesajele virtuale trebuie
sa fie transformate in mesaje reale.De exemplu,atunci cand obiectul
asteapta date introduse de la tastatura,sistemul genereaza mesaje
de tasta virtuala de tip WM_KEYDOWN (asteapta o tasta).De fiecare
data cand se apasa o tasta,functia TranslateMessage transforma
mesajul virtual intr-un mesaj real care contine caracterul introdus,
intr-un mesaj de tip WM_CHAR si amplaseaza mesajul in stiva.
3.DispatchMessage este functia care selecteaza fereastra de destinatie a
fiecarui mesaj (in functie de codul handle).
O singura bucla poate sa deserveasca toate ferestrele din aplicatie.
In aplicatiile de tip OWL,bucla de mesaje este inlocuita de tabela de
raspuns la evenimente.Pentru a simplifica munca procesorului,aplicatia
nu va mai prelucra toate mesajele si toate evenimentele,ci doar acelea
care sunt incluse in tabela de raspuns la evenimente.Ca rezultat,executia
programului este mult mai rapida si mai simpla.Nu se mai formeaza "cozi
de asteptare" in stiva de mesaje si se exclude riscul de a interpreta
mesaje nesemnificative.Pentru a realiza distributia datelor din parametri
catre metodele si procedurile proprii se utilizeaza o serie de functii
dispecer incluse in fila "dispatch.h".Aceste functii separa datele din
fiecare mesaj,in functie de tipul lor si transfera controlul catre membrii
obiectului respectiv cu ajutorul unor pointeri (pmf).Aceste functii nu
pot fi apelate direct,nici nu pot fi modificate.La nevoie,puteti crea si
adauga in fila de resurse functii noi,care sa satisfaca necesitatile de
moment.Este important sa studiati aceste functii,deoarece nu se pot uti-
liza ca raspuns la evenimentele Windows decat functii,care contin daor
parametrii pentru care exista o functie de distributie gata definita.
EXEMPLU: daca Windows trimite un mesaj de tip WM_CTRLCOLOR catre o
aplicatie,parametrul WParam este de fapt o data de tip HDC iar parametrul
LParam include o data de tip HWND si una de tip UINT (cele doua date ocupa
segmentul si respectiv off-setul adresei).Dupa interventia functiei de
dispatch,datele vor fi preluate din parametri si distribuite functiei
locale de tip OWL astfel : HBrushEvCtrlColor(HDC,HWND,UINT).
Toate functiile de tip dispatch au urmatorii patru parametrii:
1. GENERIC & -este un pointer spre obiect
2. GENERIC::*pmf -este un pointer spre functia membru
3. WPARAM -este unul dintre parametrii mesajului
4. LPARAM -este celalalt parametru al mesajului
In definitiile din fila sursa se utilizeaza urmatoarele abrevieri:
v = void return ; i = int ; U = uint ; H = handle ; I32 = int32 ;
POINT = TPoint& (pointeaza obiectul construit) ; POINTER = void*
Pentru a vedea daca metoda definita de d-voastra poate fi inclusa in
tabela de raspuns la evenimete,studiati continutul filei "dispatch.h"
si analizati daca exista o functie dispecer corespunzatoare.
-109-
Pentru fiecare definitie,primul grup de date indica tipul de data care
va fi returnat,iar cel de al doilea grup de date indica paramatrii accept-
ati.
EXEMPLU: prima functie definita in fila "dispatch.h" este:
int 32 _OWLFUNC i_LPARAM_Dispatch ( GENERIC& generic,
int (GENERIC::*pmf)(int32),
uint wParam,
int32 lParam);
Aceasta functia analizeaza parametrul LParam si returneaza o valoare de
tip int32.Se poate aplica pentru orice mesaj care contine in parametrul
WParam o valoare de tip uint si in parametrul LParam o valoare de tip
int32,atunci cand functia membru pentru care se apeleaza asteapta sa
primeasca un peremetru de tip int32 (valoarea returnata ).
Urmatoarea functie este identica,dar analizeaza parametrul WParam.
Fiecare functie este insotita si de o explicatie sumara:
EXEMPLU:
// parses wParam as bool and lParam as uint and always returns 0
int32 _OWLFUNC v_B_U Dispatch ( GENERIC& generic,
void (GENERIC::*pmf) (bool,uint),
uint wParam,
int32 lParam);
aceasta functie analizeaza parametrul wParam ca pe o valoare booleana
(zero sau unu),parametrul lParam ca pe o valaore de tip integer si retur-
neaza zero (functia este de tip void)
Analizati toate aceste definitii si alegeti cea care va putea prelucra
mesajele Windows astfel incat sa furnizeze valori pentru functia de ras-
puns la evenimentul ales.Este usor de observat ca functia de raspuns poate
avea maximum patru parametrii distincti(cate doi pentru fiecare paramteru
din mesajul Windows).Daca de exemplu LParam contine doua valori de tip
int,acestea vor fi denumite ca lParam.lo si lParam.hi,in functie pozitia
byte-ului in care sunt stocate (byte-ul HI sau byte-ul LO din word).
Daca wParam contine o singura valoare,iar lParam contine doua valori,
functia de raspuns la eveniment rezultata dupa dispatch va putea contine
Dostları ilə paylaş: |
|
|