Administratie | Alimentatie | Arta cultura | Asistenta sociala | Astronomie |
Biologie | Chimie | Comunicare | Constructii | Cosmetica |
Desen | Diverse | Drept | Economie | Engleza |
Filozofie | Fizica | Franceza | Geografie | Germana |
Informatica | Istorie | Latina | Management | Marketing |
Matematica | Mecanica | Medicina | Pedagogie | Psihologie |
Romana | Stiinte politice | Transporturi | Turism |
Elemente de programare Windows
Scopul
lucrarii: Dezvoltarea de aplicatii Windows bazate pe
evenimente
Desfasurarea
lucrarii: Se vor scrie programe folosind functiile
standard din biblioteca API
(Application Program Interface) a mediului Windows.
Programare Windows cu functii API
Caracteristica sistemului de operare Windows este concentrarea pe interfete grafice si evenimente, ceea ce inseamna ca toate interactiunile dintre aplicatie si utilizator sunt manipulate de catre sistemul de operare. Aplicatiile dezvoltate sub mediul Windows trebuie sa comunice cu sistemul de operare prin interfata de programare a aplicatiilor (Application programming interface - API). Aceasta este o componenta fundamentala in fiecare membru al familiei de sisteme de operare Windows si consta dintr-un mare numar de functii care faciliteaza comunicarea aplicatiei cu Windows-ul si cererile pentru serviciile sistemului de operare.
Interfata de programare a aplicatiilor Winndows furnizeaza un sistem de management al memoriei virtuale, ceea ce face ca fiecare aplicatie sa ruleze in propriul spatiu de adrese. Acest lucru creste robustetea sistemului deoarece impiedica interferenta aplicatiilor. O alta trasatura disponibila pentru procesele Windows este securitatea avansata bazata pe obiecte, care protejeaza obiectele partajate de accesare neautorizata prin verificarea drepturilor de acces ale fiecarei aplicatii. Aceste caracterisitici de securitate sunt implementate complet numai pe platforma Windows.
Pentru scrierea de aplicatii Windows cu Visual C++ se pot utiliza functiile standard API (Application Program Interface) sau biblioteca de clase MFC (Microsoft Fundation Class). Un dezavantaj al utilizarii ierarhie de clase MFC est faptul ca aceasta ierarhie ascunde in spatele ei principiile si modul fundamental de programare Windows.
O aplicatie Windows este o aplicatie bazata pe evenimente, prin care calculatorul receptioneaza mesajele generate de diverse elemente externe sau interne unui program (de exemplu: apasarea unei taste, miscarea unei ferestre, apasarea unui buton dintr-o anumita fereastra a programului) si apeleaza functii specifice de tratare a evenimentelor respective. In cadrul acestor aplicatii, modul uzual de comunicare intre utilizator si calculator este o interfata grafica, cu diverse componente.
O interfata utilizator Windows contine un numar de controale standard, precum butoane, meniuri, bare de defilare care pot fi gestionate in cadrul aplicatiei prin intermediul functiilor standard din biblioteca API (Application Program Interface) a mediului Windows. Proiectarea si dezvoltarea unei interfete utilizator presupune doua etape diferite:
Proiectarea grafica a interfetei, in care programatorul pozitioneaza si dimensioneaza diferitele controale in cadrul ferestrei asociate interfetei, conferindu-le functionalitatea dorita pentru introducerea si extragerea datelor inspre/dinspre aplicatie;
Scrierea functiilor care gestioneaza aceste resurse.
Functiile de gestionare a resurselor din cadrul unei interfete utilizator folosesc functiile disponibile din biblioteca API Windows.
Programarea Windows traditionala utilizeaza cateva notiuni foarte importante: notiunea de eveniment, cea de mesaj, precum si cea de fereastra.
In Windows, toate actiunile utilizatorului sunt privite ca evenimente, iar acestea au de obicei ca rezultat un fragment de cod executat intr-o aplicatie. In general, directia de executie a unui program este determinata de o secventa de actiuni ale utilizatorului. Un astfel de program poarta denumirea de program condus de evenimente (event-driven). Acest lucru are drept consecinta faptul ca o proportie semnificativa a codului aplicatiei este dedicata prelucrarii evenimentelor.
O aplicatie isi directioneaza iesirea catre un anumit dispozitiv grafic prin crearea unui context de dispozitiv (device context - DC). DC-ul este o structura de date gestionata de GDI, care contine informatii despre atributele de desenare ale unui dispozitiv. Un DC poate fi creat de catre aplicatie folosind functii GDI. Un context de dispozitiv poate fi folosit pentru a desena pe ecran, la imprimanta sau intr-un metafile (o lista de comenzi care pot fi urmate pentru desenarea unui grafic).
Un rol cheie al Windows API este asigurarea pentru aplicatii a functiilor pentru crearea si gestionarea interfetei grafice utilizator (GUI). user32.dll contine aceste functii de management al ferestrelor. Interfata grafica Windows este realizata de aplicatii care apeleaza functii din user32.dll pentru a crea obiecte Windows standard, cum ar fi:
. ferestre
. casute de dialog
. meniuri
. butoane
. icoane
. cursoare
Arhitectura unui program Winndows
Cand utilizatorii interactioneaza cu obiectele de pe ecran, sistemul de operare captureaza toate evenimentele hardware brute. Informatiile acestea sunt plasate intr-o coada sistem, controlata si mentinuta de Windows, care traduce fiecare element intr-o structura mica de date numita mesaj.
Mesajele Windows contin:
. informatii despre tipul de eveniment care a fost initiat
. momentul de timp la care a avut loc evenimentul
. fereastra careia i-a fost adresat mesajul
. pozitia cursorului cand mesajul a fost postat
. alte informatii specifice evenimentului
Fiecare aplicatie de tip Winndows are propria sa coada privata de mesaje, iar responsabilitatea principala a oricarui program Windows este regasirea propriilor mesaje din coada de mesaje, dupa care programul poate raspunde acestora in mod adecvat.
De asemenea, fiecare aplicatie Windows consta in 2 elemente de programare esentiale:
. functia WinMain, care initializeaza si porneste programul
. functia WndProc, care trateaza mesajele programului
Toate programele Windows isi incep executia prin apelarea WinMain-ului, singurul punct de intrare al oricarei aplicatii Windows create in C sau C++. Functia WinMain este echivalentul Windows al functiei main din aplicatiile consola. Ea initializeaza variabilele necesare si creaza fereastra sau ferestrele care reprezinta interfata primara cu utilizatorul. WinMain contine o portiune mica de cod numita bucla de mesaje (message loop). Scopul sau este regasirea mesajelor introduse in coada de mesaje a aplicatiei. Aceste mesaje sunt recuperate pe rand, dupa modelul FIFO.
Pe masura ce bucla de mesaje prelucreaza mesajele din coada, ea le transmite unei functii asociate din program, numita procedura ferestrei sau WndProc. Daca aplicatia are mai multe ferestre, atunci sunt necesare mai multe proceduri de acest fel, cate una pentru fiecare fereastra. Atat WinMain cat si WndProc comunica cu sistemul de operare prin apeluri de functii Windows API. Desi cele doua functii sunt necesare pentru orice program, ele nu au o legatura directa. Legatura dintre WinMain si WndProc este stabilita prin declararea si inregistrarea unui clase fereastra. Aceasta furnizeaza sistemului de operare adresa functiei WndProc potrivite, care sa prelucreze mesajele aplicatiei.
Bucla de mesaje din WinMain utilizeaza trei functii pentru tratarea mesajelor din coada. WinMain apeleaza functia GetMessage pentru a extrage un mesaj din coada, apoi apeleaza TranslateMessage pentru eventualele conversii necesare asupra mesajului regasit. Functia DispatchMessage determina Windows-ul sa apeleze WndProc pentru prelucrarea mesajului. In toate programele C si C++, trebuie mai intai declarata si inregistrata o clasa fereastra inainte sa cream fereastra propriu-zisa. O clasa fereastra este un set de atribute care descriu in mod unic fereastra programului. Clasa include flag-uri, pentru specificarea alinierii ferestrei, de exemplu, si orice context de dispozitiv sau alte atribute de nivel scazut asociate cu fereastra, precum:
. meniul principal
. cursor si icon
. culoarea de fundal
. numele procedurii ferestrei (WndProc)
In Windows, exista mai multe sute de tipuri de mesaje care pot fi trimise. Unele se petrec foarte frecvent - de mai multe ori pe secunda cand este miscat mouse-ul in fereastra programului, de exemplu. Drept rezultat, functia WndProc este de obicei cel mai vast element din aplicatie. Codul din WndProc depinde foarte mult de program, spre deosebire de WinMain, care are o structura standard, cu exceptia setarilor aspectului general al ferestrei.
Cateva mesaje tipice gestionate de WndProc:
. WM_PAINT - cerere de redesenare a unei portiuni a ferestrei unei aplicatii
. WM_RBUTTONDBLCLK - utilizatorul a facut dublu-click pe butonul din dreapta al mouse-ului
. WM_DESTROY - cerere pentru distrugerea (inchiderea) ferestrei aplicatiei
Mesajele tratate de WndProc pot fi din coada de mesaje (queued) sau nu (non-queued). Mesajele din coada sunt regasite initial de bucla de mesaje din WinMain si sunt in general generate de intrarile utilizator de tip mouse sau tastatura. Mesajele care nu sunt introduse in coada sunt mesaje trimise direct de Windows catre WndProc prin API. Acestea pot fi mesaje generate de programul insusi, de exemplu trimiterea unui WM_CLOSE la apasarea butonului "Iesire". Multe mesaje de acest tip sunt generate ca o consecinta a procesarii in WndProc a mesajelor din coada. Altele sunt implicate in managementul ferestrelor, de exemplu redimensionarea unei ferestre sau gestionarea meniurilor. Mesajele pot fi generate pentru orice fereastra in orice aplicatie folosind doua apeluri Win32 API. Functia SendMessage este un apel API sincron care invoca direct procedura WndProc si revine dupa ce mesajul este tratat. PostMessage este un apel asincron care plaseaza noul mesaj in coada de mesaje si revine inainte sa fie cunoscute rezultatele actiunii. In WndProc, putem trata in mod specific fiecare mesaj, dar in cele mai multe cazuri, aceasta functie este de fapt responsabila pentru analiza a ce este un mesaj. El este ori tratat ori trimis unei proceduri implicite, de aceea nu are rost sa tratam toate mesajele posibile, ci numai pe acelea care ne intereseaza in mod direct. Toate celelalte mesaje pot fi pasate inapoi Windows-ului folosind procedura de fereastra implicita. Aceasta este o functie standard numita DefWindowProc, care implementeaza multe din caracteristicile de comportament ale aplicatiilor Win32, cum ar fi minimizarea, refacerea sau maximizarea unei ferestre, afisarea unui meniu si asa mai departe. Iar daca DefWindowProc nu implementeaza tratarea unui anumit mesaj, pur si simplu il sterge din coada.
Structura functiei WinMain
Mai intai trebuie inregistrata clasa ferestrei. Se foloseste un obiect de tipul:
typedef struct tagWNDCLASSEX WNDCLASSEX, *PWNDCLASSEX;
Semnificatia principalelor campuri este urmatoarea:
style - un numar ce rezulta din combinarea unui numar de stiluri predefinite pentru ferestre;
lpfWndProc - pointer spre functia Wndproc a ferestrei;
hInstance - handler-ul instantei curente a aplicatiei;
hIcon - pictograma asociata ferestrei, cea care va fi desenata cand fereastra este minimizata;
hCursor - cursorul care se afiseaza cand mouse-ul traverseaza zona de ecran asociata ferestrei;
hbrBackground - pensula utilizata pentru desenarea fundalului ferestrei;
lpszMenuName - numele clasei, utilizat atunci cand se creeaza fereastra.
Liniile de program vor avea urmatorul aspect:
// obiectul instantiat din structura
WNDCLASSEX wc;
// dimensiunea structurii
wc.cbSize = sizeof (wc);
// stilul ferestrei
wc.style = NULL;
// functia fereastra care trateaza mesajele acestei ferestre
wc.lpfnWndProc = (WNDPROC) WndProc;
// nu exista date suplimentare pentru clasa
wc.cbClsExtra = 0;
// nu exista date suplimentare pentru fereastra
wc.cbWndExtra = 0;
// instanta aplicatiei
wc.hInstance = hInstance;
// nu avem icoana predefinita
wc.hIcon = NULL;
// se incarca un cursor de tip sageata
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// culoarea fondului - aici alb
wc.hbrBackground = (HBRUSH) CreateSolidBrush(RGB(255,255,255));
// numele resursei meniu
wc.lpszMenuName = LPTSTR (ID_MENU);
// numele clasei de ferestre
wc.lpszClassName = szAppName;
// icoana asociata clasei ferestrei; NULL inseamna ca folosim tot hIcon
wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
// inregistrarea clasei de ferestre
RegisterClassEx(&wc);
// se retine handle-ul instantei ferestrei intr-o variabila globala, care poate fi folosita apoi in program
hInst = hInstance;
In continuare trebuie creata fereastra principala. Functia CreateWindow are urmatorul prototip:
HWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth,
int nHeight, HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID lpParam);
Apelul functiei este de tipul:
hWnd = CreateWindow(
szAppName, // numele clasei inregistrat cu RegisterClass
szTitle, // text pentru bara de titlu a ferestrei
WS_OVERLAPPEDWINDOW, // stilul ferestrei
CW_USEDEFAULT, // pozitia orizontala implicita
CW_USEDEFAULT, // pozitia verticala implicita
CW_USEDEFAULT, // latimea implicita
CW_USEDEFAULT, // inaltimea implicita
NULL, // nu are parinte
NULL, // foloseste meniul clasei de ferestre
hInstance, // proprietara ferestrei
NULL);
Urmeaza afisarea ferestrei si trimiterea mesajului WM_PAINT:
ShowWindow(hWnd,nCmdShow); // afiseaza fereastra
UpdateWindow(hWnd); // trimite mesajul WM_PAINT
In final cream bucla de mesaje:
BOOL GetMessage(LPMSG lpMsg, // adresa structurii cu mesajul
HWND hWnd, // handle-ul ferestrei
UINT wMsgFilterMin, // primul mesaj
UINT wMsgFilterMax // ultimul mesaj);
// preia si distribuie mesaje din coada de mesaje pana se primeste WM_QUIT
while(GetMessage(&msg,NULL,0,0))
// intoarce valoarea de la PostQuitMessage
return(msg.wParam);
Structura functiei WndProc
Notiunile de eveniment si mesaj sunt legate una cealalta: un eveniment reprezinta o actiune care poate fi detectata de catre sistemul de operare, pe cand mesajul reprezinta secventa de informatii care se genereaza in momentul aparitiei evenimentului. Mesajele sunt generate de catre sistemul de operare si nu sunt dependente de un anumit limbaj de programare.
Mesajele sunt directionate. In momentul in care apare un eveniment si se genereaza mesajul aferent lui, in afara de alte elemente de identificare, mesajul va contine si identificarea locului de destinatie, spre care se doreste a fi trimis si unde va avea loc tratarea lui.
Aplicatiile scrise pentru Windows
sunt aplicatii 'message driven'. Ca raspuns la diferite
evenimente cum ar fi click-uri pe mouse, mutari ale ferestrelor, sistemul
de operare Windows gestioneaza mesajele generate directionandu-le
spre fereastra corespunzatoare.
Tratarea
unui mesaj inseamna executia unei functii de tratare a
mesajului, care realizeaza anumite actiuni specifice. Tratarea
mesajelor se poate realiza atat de catre sistemul de operare, cat si
de catre aplicatii. Mesaje de nivel jos, cum sunt cele de
miscare a mouse-ului, indiferent de destinatie, sunt de obicei
trimise spre sistemul de operare, asa incat desenarea mouse-ului este
realizata de sistemul de operare si nu de catre aplicatie.
In mod uzual, destinatia unui mesaj este o fereastra, deoarece fereastra este elementul grafic de baza al unei interfete utilizator, marea majoritate a controalelor unei ferestre, fiind tot ferestre in ultima instanta.
In general, pentru o aplicatie exista doua categorii de mesaje:
mesaje transmise spre sau de la sistemul de operare;
mesaje transmise spre sau de la controalele existente in cadrul interfetei grafice a aplicatiei.
Fiecare mesaj este caracterizat prin:
un identificator de mesaj
parametrii mesajului (desemnati uzual prin wParam si lParam), care contin informatia utila a mesajului.
Identificatorul de mesaj este in mod uzual un numar intreg si unic pentru fiecare mesaj. Pentru simplitate, in cadrul programelor C si C++, se pot utiliza constante simbolice, ale caror definitii se afla in fisiere header. Pentru Visual C++, definitiile identificatorilor de mesaje se afla in fisierul Winuser.h.
Numele simbolic al unui mesaj poate avea un prefix, care indica tipul ferestrei care este sursa sau destinatia mesajului. In tabelul urmator sunt prezentate cateva prefixe uzuale pentru mesaje.
Prefix |
Tip fereastra |
BM, BN |
Buton |
CB, CBN |
Combo box |
CPL |
Aplicatie Control Panel |
DM |
Dialog box |
EM, EN |
Edit box |
LB, LBN |
List box |
LVM, LVN |
List view |
NM |
Fereastra parinte (notification message) |
PBM |
Progress bar |
PBT |
Orice aplicatie (battery power broadcast) |
PSM, PSN |
Foaie de proprietati (property sheet) |
SB |
Status bar |
SBM |
Scrollbar |
STM, STN |
Static control |
TB, TBN |
Toolbar |
TVM, TVN |
Tree view |
WM |
Fereastra generica (window message) |
Se observa faptul ca pentru anumite ferestre exista doua tipuri de prefixe. Cele care se termina cu caracterul 'N' sunt numite mesaje de notificare si reprezinta de fapt feedback-uri ale terminarii actiunilor asociate anumitor mesaje. De exemplu, un mesaj de tip BN trimis de o fereastra la un buton continut in cadrul ei indica actiunea de apasare a butonului de catre utilizator. Din punct de vedere grafic, butonul trebuie sa indice faptul ca a fost apasat si din acest caz functia de tratare a ferestrei butonului trebuie sa redeseneze butonul. Dupa terminarea operatiei de redesenare, butonul va transmite un mesaj de notificare (de tip BN) spre fereastra principala, indicand acest lucru. Mesajele de notificare au identificatorul simbolic WM_NOTIFY.
O alta categorie speciala de mesaje sunt cele de tip comanda, care au identificatorul simbolic WM_COMMAND. O comanda este un mesaj generat de Windows la anumite interactiuni ale utilizatorului cu aplicatia (de exemplu, cand utilizatorul apasa un element de meniu). Atat mesajele de notificare, cat si cele de comanda, au ca parametru wParam identificatorul resursei care a generat mesajul.
Sistemul de operare distribuie mesajele generate spre ferestrele destinatie ale acestora. Astfel, pentru fiecare fereastra exista o coada de mesaje, in care se introduc mesajele pe masura ce sosesc si din care sunt extrase si tratate pe rand. Fiecare fereastra trebuie sa posede o functie specifica de tratare a mesajelor. O asemenea functie va primi ca parametri tipul mesajului, handlerul ferestrei care a emis mesajul, precum si alte informatii aditionale, care depind de tipul fiecarui mesaj.
WndProc consta in principal intr-un switch amplu care trateaza mesajele primite de la fereastra.
LONG WndProc (HWND hWnd, // handler-ul ferestrei
UINT message, // tipul mesajului
UINT wParam, // informatie aditionala
LONG lParam) // informate aditionala
return
Se observa faptul ca o functie WndProc trateaza doar mesajele care prezinta interes pentru fereastra respectiva, celelalte mesaje fiind redistribuite pentru tratare de catre o functie implicita de tratare, numita DefWndowProc. In acest mod, un anumit mesaj poate fi tratat de catre o fereastra superior ierarhica ferestrei destinatie, sau chiar de catre sistemul de operare.
Observatii
1. In programarea Windows se utilizeaza notiunea de handler, iar tipuri de date precum HWND, HICON, HCURSOR, etc., reprezinta multimi de handlere. Handlerele sunt utilizate in general pentru a gestiona resursele unei aplicatii.
2. Programele Windows utilizeaza multe tipuri de date cu nume proprii, pentru a usura scrierea programelor. In general acestea sunt scrise cu litere mari si sunt definite in fisierul Windef.h. De exemplu UINT, BOOL, WORD, HWND, etc.
Probleme:
1. Sa se realizeze o aplicatie Windows folosind functii API care, la apasarea unui buton, sa afiseze mesaj-ul "Hello World".
2. Sa se realizeze o aplicatie Windows folosind functii API care sa permita citirea textului dintr-un editbox si il afisarea acestuia inversat intr-un alt editbox.
3. Sa se realizeze o aplicatie Windows folosind functii API care la fiecare click stanga al mouse-ului sa deseneze un cerc in pozitia curenta.
4. Sa se modifice problema 3 astfel incat sa se poata selecta o valoare pentru raza cercului intre doua limite date, si sa se poata alege si culoarea de desenare.
5. Sa se completeze problema 3 astfel incat la fiecare click dreapta al mouse-ului sa aiba loc desenarea unui dreptunghi in pozitia curenta.
6. Sa se realizeze o aplicatie Windows folosind functii API care sa manifeste un efect de tip Winamp - rotatia unui text in Taskbar. Textul va fi introdus prin intermediul unui editbox.
Acest document nu se poate descarca
E posibil sa te intereseze alte documente despre:
|
Copyright © 2024 - Toate drepturile rezervate QReferat.com | Folositi documentele afisate ca sursa de inspiratie. Va recomandam sa nu copiati textul, ci sa compuneti propriul document pe baza informatiilor de pe site. { Home } { Contact } { Termeni si conditii } |
Documente similare:
|
ComentariiCaracterizari
|
Cauta document |