Limbajul C++ si oop abc-doar


Aplicatie1() : TApplication() { }



Yüklə 1,36 Mb.
səhifə10/18
tarix12.09.2018
ölçüsü1,36 Mb.
#81721
1   ...   6   7   8   9   10   11   12   13   ...   18

Aplicatie1() : TApplication() { };

void InitMainWindow(); };

void Aplicatie1::InitMainWindow()

{

MainWindow = new TFrameWindow(0,"Test",new Fer1);

};

int

OwlMain(int,char* [])

{

return Aplicatie1().Run();

}

Compilati,construiti,link-ati si apoi executati aplicatia.In fereastra

Test executati alternativ click-uri de mouse cu butonul drept sau stang.

Nu este necesar sa rescrieti toata fila.Puteti copia fila precedenta si

apoi adaugati doar metodele nou introduse pentru clasa Fer1.In general,

programele si aplicatiile se pot dezvolta prin modificarea,actualizarea

sau transformarea unor aplicatii precedente.


-61-

Observati elementele noi din program: fila header "owl/dc.h",cele

doua functii destinate pentru controlul butoanelor mouse si tabela de

control a evenimentelor Windows denumita RESPONSE_TABLE.

Fila header asigura tot ce este necesar pentru a putea

executa functii si operatii de tip grafic.Deschideti fila si observati

clasele definite in aceasta fila.Cea mai importanta este clasa TDC in

care sunt incluse atat contextul de dispozitiv grafic cat si principalele

functii grafice.Celelalate clase (TWindowDC,TDesktopDC,TClientDc,TPaintDC,

TMetaFileDc,TCreatedDC,TIC,TMemoryDC,TDibDC,TPrintDC) contin seturi de

metode specializate pentru diverse situatii speciale.Trebuie remarcat

faptul ca pentru fiecare clasa,contextul de dispozitiv este detectat auto-

mat de catre constructorul clasei.Dupa derivarea unui obiect nu mai este

necesar sa tineti evidenta acestui factor.Toate functiile membru se pot

apela direct.In exemplul de mai sus,au fost utilizate doar functiile

Rectangle() si TextOut().

Urmatorul element de noutate il reprezinta modul de interpretare si

control al evenimentelor de tip Windows.Toate programele care realizeaza

o interfata grafica de tip Windows exploateaza mesajele sistemului de

operare Windows.Pentru fiecare operatie executata in sistem,Windows emite

un mesaj specializat.Mesajele Windows sunt denumite dupa operatia care a

determinat emiterea mesajului la care se adauga prefixul WM_.Principalele

mesaje Windows sunt: WM_ACTIVATE,WM_CANCELMODE,WM_CHAR,WM_CHILDACTIVATE,

WM_CLEAR,WM_CLOSE,WM_COMMAND,WM_COPY,WM_CREATE,WM_DELETEITEM,WM_ENABLE,

WM_GETTEXT,WM_INITMENU,WM_KEYDOWN,WM_KEYUP,WM_LBUTTONDOWN,WM_LBUTTONUP,

WM_MENUSELECT,WM_MOUSEMOVE,WM_MOVE,WM_PAINT,WM_PASTE,WM_POWER,WM_QUIT,

WM_RBUTTONDOWN,WM_RBUTTONUP,WM_SIZE,WM_TIMER,WM_UNDO,WM_USER,WM_VSCROLL.

Lista completa este mult mai lunga.Manualul Help din C++ nu contine lista

acestor evenimente,dar puteti utiliza manualul Help din Borland Pascal,sau

orice alta sursa de documentare.Modul de interceptare si interpretare al

acestor mesaje este diferit de la un program la altul.In Pascal trebuie

sa scrieti o bucla continua in care sa fie preluate toate mesajele si sa

adaugati o conditie oarecare de selectie.In Delphi,eveniemetele sunt

rezolvate integral cu ajutorul utilitarului Object Inspector,iar in Visual

C++ evenimentele sunt ordonate sub forma unei grile denumita "message map".

In OWL,evenimentele sunt ordonate sub forma de tabel de corespondenta,

denumit RESPONSE_TABLE,in care la fiecare eveniment de tip Windows consi-

derat a fi semnificativ se asociaza o anumita functie de raspuns prin care

se declanseaza o anumita serie de operatii specifice.In acest fel,dintre

toate evenimentele Windows,se vor selecta doar cele care au semnificatie

pentru aplicatia respectiva.De exemplu,daca in exercitiul de mai sus exe-

cutati diverse deplasari ale indicatorului mouse,se vor declansa o serie

intreaga de mesaje de tip WM_MOUSEMOVE.Aceste mesaje vor fi ignorate de

catre aplicatie.Singurele mesaje cu semnificatie sunt WM_LBUTTONDOWN si

respectiv WM_RBUTTONDOWN,adica cele care au fost incluse in RESPONSE_TABLE

Pentru fiecare astfel de evenimet,trebuie sa fie definita o functie

de raspuns la eveniment si un macro de identificare a evenimentului.Prin

conventie,functia de raspuns la evenimet are acelasi nume ca si mesajul

Windows corespunzator,la care se adauga si prefixul "Ev".Exemplu: functia

care raspunde la mesajul WM_PAINT va fi denumita EvPaint().Dupa prefix,

prima litera din numele mesajului va fi scrisa cu majuscula,iar restul

vor fi scrise cu litere mici.


-62-

Pentru identificarea fiecarui mesaj,se va defini un macro specializat.

Numele acestui macro va fi format din numele mesajului,la care se va

adauga si prefixul "EV_".In acest caz toate literele vor fi scrise cu

majuscule.Exemplu: pentru mesajul WM_PAINT macroul de identificare va fi

EV_WM_PAINT.

Asadar,pentru fiecare mesaj Windows se poate scrie un macro care il

identifica si o functie care executa o serie de comenzi in momentul in

care mesajul a fost receptionat.

Editarea tabelei de raspuns la evenimentele Windows se face in patru

etape succesive:

1.Se declara tabela cu: DECLARE_RESPONSE_TABLE(numele clasei)

2.Definitia incepe cu: DEFINE_RESPONSE_TABLEx(clasa,clase receptive)

3.Se introduc macrourile de identificare a mesajelor (gen EV_WM_PAINT)

4.Se termina definitia tebelei cu: END_RESPONSE_TABLE

In etapa a doua,x reprezinta numarul de parametri,adica numarul de clase

care vor receptiona mesajul respectiv.Primul paramatru este clasa in care

este definit tabelul de raspunsuri,iar cel de al doilea parametru este

clasa care va receptiona mesajul.In exemplu,tabelul este definit in Fer1,

iar mesajul va fi receptionat de catre TWindow.In acest caz,exista o

singura clasa receptiva,adica un singur parametru,astfel incat definitia

va fi: DEFINE_RESPONSE_TABLE1(Fer1,TWindow).In cazul in care ar fi

existat si o alta clasa,in care exista o tabela de raspuns si in care se

vor receptiona mesajele,de exemplu o fereastra denumita TWindow2,definitia

ar fi fost de genul: DEFINE_RESPONSE_TABLE2(Fer1,TWindow,Twindow2).

Asadar,pentru fiecare mesaj exista o functie de raspuns si un macro de

identificare.In exemplu,daca se apasa butonul mouse stang,sistemul de

operare Windows va emite un mesaj de tip WM_LBUTTONDOWN.Acest mesaj va fi

interceptat si identificat de catre macroul EV_WM_LBUTTONDOWN,care va

declansa automat functia de raspuns EvLButtonDown().

Practic tabela de raspunsuri tine locul unei proceduri in care toate

mesajele emise de sistemul Windows sunt receptionate si filtrate prin

macrourile definite.Daca un mesaj corespunde cu macro-ul,se va declansa

automat functia corespunzatoare.

Prin acest mecanism,puteti programa orice fel de suita de algoritmi de

raspuns autoamt la un eveniment oarecare.Observati faptul ca un singur

mesaj Windows poate declansa simultan mai multe functii de raspuns,in

cazul in care exista mai multe clase(obiecte) care asteapta evenimentul

respectiv.De exemplu,o simpla apasare de buton poate declansa o serie

intreaga de functii de raspuns.Reciproc,este posibil ca raspunsul unei

anumite functii sa nu poata fi declansat decat in urma unei combinatii de

mesaje Windows(fiecare mesaj activeaza o functie care concura cu alte

functii pentru a forma raspunsul final).

Ca rezultat,fata de alte programe,OWL permite o interpretare extrem

de discriminativa a mesajelor Windows,fara riscul de a se declansa si

"raspunsuri accidentale".

Alegeti cu atentie mesajul Windows utilizat pentru declansarea unei

anumite functii.Exista si mesaje nediscriminative,care pot fi eliberate

de catre mai multe evenimente disticte.Daca RESPONSE_TABLE este mai ampla,

este bine sa faceti si o mica schema cu fiecare functie de raspuns si cu

fiecare macro care identifica mesajul,astfel incat sa nu existe mesaje

incrucisate sau macro-uri fara functie de raspuns.


-63-

Tot o tabela de comenzi se utilizeaza si pentru a monitoriza optiunile

unui meniu:

EXEMPLU: (vezi si OWL_ABC \ owl4 )

Deschideti un proiect nou,iar in fila .cpp introduceti un text de genul:

#include

#include

#include

#include

#include

#include

class Fer1 : public TApplication {

public:

Fer1() : TApplication("Editor:"){};

protected:

void InitMainWindow();

void CmFileNew();

void CmFileopen();

DECLARE_RESPONSE_TABLE(Fer1); };

DEFINE_RESPONSE_TABLE1(Fer1,TApplication)

EV_COMMAND(CM_FILENEW,CmFileNew),

EV_COMMAND(CM_FILEOPEN,CmFileOpen);

END_RESPONSE_TABLE;

void

Fer1::InitMainWindow()

{

MainWindow = new TFrameWindow(0,Name,new TEditFile);

MainWindow -> AssignMenu(IDM_EDITFILE);

MainWindow ->Attr.AccelTable = IDA_EDITFILE;

MainWindow ->SetIcon(this,201);

};

void Fer1::CmFileNew()

{

TEditFile* fila=TYPESAFE_DOWNCAST(MainWindow->GetClientWindow(),TEditFile);

CHECK(fila);

fila->NewFile();

};

void Fer1::CmFileOpen()

{

TEditFile* fila=TYPESAFE_DOWNCAST(MainWindow->GetClientWindow(),TEditFile);

CHECK(fila);

fila->Open();

};

int

OwlMain(int,char* [])

{

return Fer1().Run();

}

Pentru definitia meniului propriu zis,este necesara o fila de resurse

de tip .rc.Executati un click de mouse drept si stergeti din proiect fila

.def si fila .rc cu optiunea DeleteNode.Deschideti o fila noua(din File,cu

New si TextEdit) si introduceti urmatorul text:


-64-

#ifndef WORCKSHOP_INVOKED

#include

#endif

#include

#include

#include

Salvati fila cu numele de owl4.rc,apoi includeti fila in proiect cu

Add Node.Compilati,construiti si link-ati proiectul,apoi executati apli-

catia.Programul de mai sus,deschide un editor de text.Puteti deschide sau

edita orice fila de tip ASCI.

Pentru exemplul de mai sus,am ales un meniu gata definit in filele

editfile.rc si editfile.rh.In directorul INCLUDE\OWL exista mai multe

astfel de file cu extensia .rc si .rh.Puteti utiliza aceste file pentru

a utiliza meniurile predefinite.In program,meniul se incarca cu comanda

AssignMenu().

Pentru a atribui cate o functie la fiecare optiune din meniu,se va

declara si defini o tabela de raspunsuri.Toate optiunile exploateaza

mesajul Windows WM_COMMAND,la care se adauga cate o comanda specifica

pentru fiecare optiune.Numele comenzii se scrie cu majuscule si se adauga

prefixul "CM_".De exemplu,pentru FileOpen comanda va fi: CM_FILEOPEN.

Pentru fiecare comanda se va asocia si o functie de raspuns care va

executa o serie de operatii,in momentul in care se receptioneaza mesajul

WM_COMMAND + comanda specifica (Exemplu: WM_COMMAND + CM_FILEOPEN).Functia

va avea acelasi nume cu comanda optiunii + prefixul "Cm".Prima litera din

mumele functiei se va scrie cu litera mare (majuscula) iar restul litere-

lor se vor scrie cu litere mici.Exemplu: pentru comanda CM_FILEOPEN se

va utiliza functia de raspuns CmFileopen().In definitia tabelei de raspuns

fiecare astfel de pereche comanda/functie de raspuns va fi introdusa cu

o formula formata din prefixul EV_COMMAND + (comanda,functia).De exemplu,

pentru comanda CM_FILEOPEN si functia CmFileOpen() se va utiliza formula:

EV_COMMAND(CM_FILEOPEN,CmFileOpen)

Functia de raspuns trebuie sa fie de tip void (fara parametri).Nu este

absolut necesar,dar se prefera ca functiile de raspuns sa fie declarate

cu specificatorul "protected:",pentru a nu avea vizibilitate si in afara

clasei in care au fost declarate (se evita coruperea datelor).

Pentru a stabili un punct de intrare prioritar in tabela de raspunsuri

la mesaje,se poate utiliza o formula de genul: EV_COMMAND_ENABLE().In

acest caz,punctul de intrare respectiv va avea prioritate fata de cele-

lalte si va fi selectat implict la initializarea obiectului.De exemplu,

daca o bara de meniu contine mai multe optiuni,se poate utiliza aceasta

formula pentru ca una dintre optiuni sa fie selectata automat in momentul

constructiei obiectului respectiv.

Puteti utiliza exemplul owl4 pentru a deschide orice fila de tip text.

Alegeti optiunea File/Open iar pentru Files of type selectati "All Files"

si apoi deschideti orice fila de pe disc (preferabil cu extensia .txt).

Pentru a utiliza un meniu personalizat,se procedeaza in mod similar,dar

in fila de resurse va trebui sa definiti toate comenzile si sa introduceti

definitia meniului.Puteti utiliza si meniuri care au fost editate sub

forma de file de resurse,dar in alte programe sau limbaje de programare{

De exemplu : resurse Visual C++,resurse Pascal,resurse Delphi etc.).

Pentru a realiza un meniu grafic,puteti utiliza un program de genul:


-65-

EXEMPLU: (vezi si OWL_ABC \ owl5 )

Fila .cpp:

#include

#include

#include

#include

#define CM_PATRAT 201

#define CM_CERC 202

class Fer1 : public TWindow {

public:

Fer1();

protected:

void CmPatrat();

void CmCerc();

DECLARE_RESPONSE_TABLE(Fer1); };

DEFINE_RESPONSE_TABLE1(Fer1,TWindow)

EV_COMMAND(CM_PATRAT,CmPatrat),

EV_COMMAND(CM_CERC,CmCerc),

END_RESPONSE_TABLE;
Fer1::Fer1():TWindow(0,0,0){};

void Fer1::CmPatrat()

{

TClientDC dc1(*this);

TPen pen1(RGB(250,0,0),10);

dc1.SelectObject(pen1);

dc1.Rectangle(50,50,200,200);

MessageBox("Patrat","text:",MB_OK);

}

void Fer1::CmCerc()

{

TClientDC dc2(*this);

TPen pen2(RGB(0,0,250),10);

dc2.SelectObject(pen2);

dc2.Ellipse(70,70,180,180);

MessageBox("Cerc","text:",MB_OK);

};

class Aplicatie1 : public TApplication {

public:

Aplicatie1() : TApplication(){};

void InitMainWindow();

};

void Aplicatie1::InitMainWindow()

{

MainWindow = new TFrameWindow(0,"Meniu 2",new Fer1);

GetMainWindow() -> AssignMenu("GRAFIC");

};

int OwlMain(int,chat* [])

{

return Aplicatie1().Run();

};


-66-

Eliminati fila .def cu DeleteNode.

Inlocuiti fila .rc cu urmatoarea fila:

#define CM_PATRAT 201

#define CM_CERC 202
#ifdef RC_INVOKED
GRAFIC MENU

{

POPUP "&DESEN"

{

MENUITEM "&Patrat", CM_PATRAT

MENUITEM "&Cerc", CM_CERC

};

};

#endif

Compilati,construiti proiectul,verificati legaturile cu Link,apoi execu-

tati aplicatia.Puteti utiliza cele doua optiuni ale meniului,pentru a

desena fie un patrat,fie un dreptunghi.Observati ca fata de exemplul owl3

am introdus si cate un obiect de tip TPen,pentru a putea modifica culoarea

si grosimea penitei de desenare.

In mod similar,puteti edita orice meniu.Puteti utiliza exemplul de

mai sus,sau orice alt exemplu functional,pentru a edita aplicatii moi.Nu

strica sa fiti putin "escroci" si sa efectuati doar operatiile necesare

pentru a transforma un exemplu anterior,dar numai dupa ce a-ti inteles

perfect modul de constructie pentru fiecare aplicatie.

In situatiile in care programul este editat "perfect" si totusi nu

functioneaza,trebuie reeditata fila .ide(fila proiect).Pentru acest scop,

deschideti un nou proiect,alegeti acceasi cale de acces si acelasi nume

pentru proiect,apoi suprascrieti proiectul.Proiectul nou deschis va

contine aceleasi file ca si proiectul anterior,dar va avea o fila .ide

noua.Compilati si construiti din nou,asigurati legaturile cu "Link" si

apoi executati aplicatia.

Pentru functiile grafice,regulile sunt aceleasi ca pentru API Windows,

dar sunt grupate intr-un singur obiect grafic,astfel incat sa fie cat mai

usor de apelat.Deschideti fila header si observati cu atentie

metodele obiectului TDC.Penita grafica este controlata de obiecte deri-

vate din clasa TPen,iar pensula(utilizata pentru a umple suprafetele)

este controlata de obiecte derivate din TBrush.Alte obiecte utile sunt

cele derivate din clasele TFont,TBitmap,TPallete,TIcon,TCursor,TRegion,

TDib,TMetaFilePict si TEnhMetaFilePict.

Pentru a putea utiliza un obiect de tip TPen,TBrush sau TFont se va

utiliza metoda SelectObject() iar pentru a reveni la valorile implicite

se pot utiliza functiile: RestorePen(),RestoreBrush(),RestoreFont()etc.

Pentru culoarea de fond se pot utiliza functiile: GetBkColor() si SetBk-

Color() iar pentru text GetTextColor() si SetTextColor(),etc.

Exista si o serie de functii care permit salvarea imaginilor grafice in

memoria clipboard si apoi utilizarea lor la nevoie,sau permit operatii

complexe cu metafile in care sunt arhivate datele necesare.Prin combinarea

acestor functii,se obtin efecte de animatie.Alte functii opereaza cu

resurse de tip Icon,Cursor,BitMap etc.


-67-

Unul dintre cele mai utilizate elemente ale unei interfete grafice este

butonul simplu.Obiectul de tip buton este definit in fila

si poate fi apelat ca un obiect oarecare.Pentru a crea oricare dintre

elementele interfetei trebuie apelat constructorul obiectului.Constructo-

rul poate fi apelat direct,sau cu ajutorul operatorului "new".

EXEMPLU: (vezi si OWL_ABC / owl6)

Deschideti un prooiect nou si introduceti in fila .cpp:

#include

#include

#include

#include

const uint16 ID_BUTTON = 101;

class Fer1 : public TWindow {

public:

Fer1();

protected:

void HandleButtonMsg();

DECLARE_RESPONSE_TABLE(Fer1);

};

DEFINE_RESPONSE_TABLE1(Fer1,TWindow)

EV_COMMAND(ID_BUTTON,HandleButtonMsg),

END_RESPONSE_TABLE;
Fer1::Fer1(): TWindow(0,0,0) {

new TButton(this,ID_BUTTON,"Buton 1",50,50,150,30,false);

};

void fer1::HandleButtonMsg()

{

TClientDC dc1(*this);

TBrush br1(RGB(0,250,0));

dc1.SelectObject(br1);

dc1.FillRect(100,100,200,200,br1);

MessageBox("Button1","text:",MB_OK);

};

class Aplicatie1 : public TApplication {

public:

Aplicatie1() : TApplication() {};

void InitMainWindow();

};

void Aplicatie1::InitMainWindow()

{

MainWindow = new TFrameWindow(0,"Test",new Fer1);

};

int OwlMain(int,char* [])

{

return Aplicatie1().Run();

};

Pentru controlul operatiilor declansate de apasarea butonului se declara

Yüklə 1,36 Mb.

Dostları ilə paylaş:
1   ...   6   7   8   9   10   11   12   13   ...   18




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin