VC ++ poate fi utilizat pentru a dezvolta programe pentru trei platforme Win32: Windows NT (pe procesoare multiple), Windows 95/98 si Win32s.
Windows NT este un SO multifir (multithreaded ) pe 32 biti cu mediu grafic integrat si posibilitati de server avansate. A fost dezvoltat pentru a maximiza portabilitatea, stabilitatea si securitatea.
Subsistemul Win32s este un alt nivel pentru Windows 3.1; acesta implementeaza un subset al sistemului Win32 care permite executia aplicatiilor pe 32 biti.
Windows 95 mosteneste o parte semnificativa de cod de la Windows 3.1. Asigura o compatibilitate pentru aplicatiile scrise pentru Windows 3.1.
Windows si Mesajele
Windows este referit adesea ca un sistem de operare bazat pe mesaje. Fiecare eveniment (apasarea unei taste, clic de mouse, etc.) este transformat într-un mesaj. In mod obisnuit aplicatiile sunt construite în jurul unei bucle de mesaje care regases 727f54h te aceste mesaje si apeleaza functia potrivita pentru a trata mesajul.
Mesajele, desi sunt trimise aplicatiilor, nu se adreseaza acestora, ci unei alte componente fundamentale a SO, fereastra (windows). O fereastra este mai mult decât o zona dreptunghiulara afisata pe ecran; aceasta reprezinta o entitate abstracta cu ajutorul careia utilizatorul si aplicatia interactioneaza reciproc.
Aplicatii, Fire si Ferestre
O aplicatie Win32 consta din unul sau mai multe fire (threads), care sunt cai paralele de executie. Gândim firele ca fiind multatsking-ul din cadrul unei aplicatii.
Observatie: Sub Win32s, poate rula o aplicatie cu un singur fir de executie.
O fereastra este totdeauna "gestionata de" un fir; un fir poate fi proprietarul uneia sau mai multor ferestre sau pentru nici una. In final, ferestrele sunt într-o relatie ierarhica; unele sunt la nivelul cel mai de sus, altele sunt subordonate parintilor lor, sunt ferestre descendente.
Procese,
fire si ferestre
Exista mai multe tipuri de ferestre in Windows; cele mai obisnuite sunt asociate cu o aplicatie. Boxele de dialog din cadrul unei ferestre sunt de asemenea ferestre. Acelasi lucru pentru butoane, controale de editatre, listbox-uri, icoane, etc.
Clase Window
Comportarea unei ferestre este definita de clasa fereastra (window class). Clasa fereastra mentine informatii despre modul de afisare initial, icoana implicita, cursor, resursele meniu si cel mai important lucru adresa functiei atasata ferestrei - procedura fereastra - window procedure. Când o aplicatie proceseaza mesaje, aceasta se face în mod obisnuit prin apelul functiei Windows DispatchMessage pentru fiecare mesaj primit; DispatchMessage la rândul ei apeleaza procedura fereastra corespunzatoare, identificând initial carei ferestre îi este trimis mesajul. În continuare procedura fereastra va trata mesajul.
Exista mai multe clase fereastra standard furnizate de Windows. Aceste clase sistem globale implementeaza în general functionalitatea controalelor comune. Orice aplicatie poate folosi aceste controale, de exemplu orice aplicatie poate implementa controale de editare, utilizând clasa fereastra Edit.
Aplicatiile pot de asemeni sa-si defineasca propriile clase fereastra cu ajutorul functiei RegisterClass. Acest lucru se întâmpla în mod obisnuit pentru fereastra principala a aplicatiei (icoana, resurse, etc.).
Windows permite de asemeni subclasarea sau superclasarea unei ferestre existente.
Subclasarea substituie procedura fereastra pentru o clasa ferestra cu o alta procedura. Subclasarea se realizeaza prin schimbarea adresei procedurii fereastra cu ajutorul functiei SetWindowLong (instance subclassing) sau SetClassLong (subclasare globala).
Instance subclassing - înseamna ca se schimba numai comportarea ferestrei specificate.
Global subclassing - înseamna ca se schimba comportarea tuturor ferestrelor de tipul specificat.
Observatie: Global subclassing se comporat diferit in Win32 si în Windows pe 16 biti (Win32s). In cazul Win32, aceasta afecteaza numai fereastra care este sub controlul aplicatiei ce face subclasarea; în windows pe 16 biti, efectul este global, se afecteaza ferestrele fiecarei aplicatii.
Superclasarea creaza o noua clasa bazata pe o clasa existenta, retinând numai procedura fereastra. Pentru a superclasa o clasa fereastra, o aplicatie regaseste informatiile despre clasa fereastra utilizând functia GetClassInfo, modifica structura WNDCLASS astfel receptionata si foloseste structura modificata într-un apel al functiei RegisterClass. GetClassInfo întoarce de asemenea si adresa procedurii fereastra. Mesajele pe care noua fereastra nu le trateaza trebuie trecute acestei proceduri.
Tipuri de mesaje
Mesajele reprezinta în fapt evenimente la diferite nivele ale aplicatiei. Exista o clasificare a acestor mesaje (din pacate nu prea exacta): mesaje fereastra, mesaje de notificare si mesaje de comanda, dar deocamdata nu ne intereseaza acest lucru.
Mesajele windows constau din mai multe parti, descrise de structura MSG.
typedef struct tagMSG MSG;
Descriere:
hwnd identifica în mod unic fereastra la care a fost transmis acest mesaj. Fiecare fereastra în Windows are un asemenea identificator.
message reprezinta identificatorul mesajului. Identificatorii mesajului sunt referiti în mod obisnuit cu ajutorul constantelor simbolice decât prin valoarea lor numerica care o au în sistem. Aceasta descriere se gaseste în windows.h.
Urmatoarele elemente pot fi privite ca parametrii ai mesajului, care au valori specifice functie de fiecare mesaj în parte.
Marea majoritate a mesajelor încep cu WM_. De exemplu WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP, etc.
Aplicatiile pot sa-si defineasca propriile mesaje. Cerinta majora este ca identificatorul mesajului sa fie unic. Pentru a defini un mesaj în sistem folosim functia RegisterWindowMessage.
Mesaje si multitasking
In Windows 3.1, bucla de mesaje are rol important în interactiunea dintre aplicatii si SO. Functionarea corecta a unui SO Windows 3.1 depinde de cooperarea dintre aplicatii. Aplicatiile sunt cele care permit SO sa preia controlul. Acest neajuns este înlaturat în Windows 95/98, NT, 2000. SO este cel care realizeaza programarea aplicatiilor pentru cuantele de timp necesare pe procesor. Desi aceasta planificare a executiei este diferita pe Windows 95/98 fata de NT, rolul primordial revine SO.
Cozi de mesaje
În Windows pe 16 biti, SO mentine o singura coada de mesaje. Când o aplicatie încearca sa gaseasca urmatorul mesaj din coada de mesaje prin functiile GetMessage sau PeekMessage, SO poate efectua un context switch si poate activa o alta aplicatie pentru care mesajele asteapta în coada. Mesajul din vârful cozii este extras si returnat aplicatiei via structura MSG. Daca aplicatia esueaza în apelul lui GetMessage PeekMessage sau Yield, aceasta blocheaza sistemul. Coada de mesaje poate deveni plina...
În Win32 (95/98, NT, 2000) mecanismul cozii de mesaje este mult mai complicat. O singura coada de mesaje nu mai rezolva problema. Aici sistemul de operare da controlul unei aplicatii si tot SO permite multitasking-ul. Doua sau mai multe fire pot accesa coada de mesaje în acelasi timp si nu exista nici o garantie ca mesajele extrase sunt ale lor.
Acesta este unul motivele pentru care coada de mesaje a fost separata în cozi de mesaje individuale pentru fiecare fir din sistem.
Procese si Fire
Într-un SO non-multifir, de exemplu UNIX, unitatea cea mai mica de executie este task-ul sau procesul. Mecanismul de planificare (apartine SO) al task-urilor va comuta între acestea; multitasking-ul se realizeaza între doua sau mai multe procese (task-uri). Daca o aplicatie are nevoie sa execute mai multe functii simultan, atunci aceasta se va divide în mai multe task-uri. Din aceasta tehnica decurg anumite neajunsuri, consum de resurse, timp de lansare a unui nou task, spatii de adrese diferite, probleme de sincronizare, etc.
În contrast, într-un sistem multifir (multifilar, multithreaded) unitatea cea mai mica de executie este firul, nu procesul. Un proces sau task poate contine mai multe fire, dintre care unul singur este firul principal, firul primar. Lansarea în executie a unui nou fir cere mai putine resurse din partea SO, firul ruleaza în cadrul aceluiasi proces, problemele de sincronizare sunt si nu sunt complicate. Oricum apar doua sincronizari: sincronizare între procese si sincronizare între fire.
Fire si Mesaje
Dupa cum am mai spus proprietarul ferestrei este firul de executie. Fiecare fir are coada proprie, privata, de mesaje în care SO depoziteaza mesajele adresate ferestrei. Aceasta nu înseamna ca un fir trebuie neaparat sa aiba o fereastra proprie si o coada proprie de mesaje. Pot exista fire si fara fereastra si fara bucla de mesaje.
În MFC, aceste fire se numesc worker threads (nu au atasata o fereastra, nu prezinta interfata catre utilizator), iar celelalte se numesc user-interface threads.
Apeluri de functii Windows
Windows ofera un mare numar de functii pentru a executa o mare varietate de task-uri, controlul proceselor, gestionarea ferestrelor, fisierelor, memoriei, servicii grafice, comunicatii, etc.
Apelurile sistem pot fi organizate în trei categorii:
servicii nucleu (apeluri sistem pentru controlul proceselor, firelor, gestiunea memoriei, etc.);
servicii utilizator (gestiunea elementelor de interfata ale utilizatorului cum ar fi ferestre, controale, dialoguri, etc.);
servicii GDI (Graphics Device Interface) (iesirea grafica independenta de dispozitiv).
Sistemul Windows include de asemenea functii API pentru alte functionalitati - MAPI (Messaging API), TAPI (Telephony API) sau ODBC (Open Database Connectivity).
Servicii Nucleu
Serviciile nucleu cuprind de obicei: getionarea fisierelor, memoriei, proceselor, firelor, resurselor.
Gestionarea fisierelor nu ar trebui sa se mai faca cu functii din bibliotecile C sau prin iostream-urile din C++. Aplicatiile ar trebui sa utilizeze conceptul Win32 de obiect fisier - file object - si functiile asociate cu acesta. De exemplu exista fisiere mapate în memorie care asigura comunicarea între task-uri.
Referitor la gestionarea memoriei pe lânga functiile cunoscute, SO Windows ofera functii care pot manipula spatii de adrese de sute de MB alocându-le dar nefacând commiting.
Cea mai importanta fateta a proceselor si firelor este gestiunea sincronizarii. Problema este complet noua si nu a fost întâlnita în Windows 3.1. În Win32, sincronizarea se face cu ajutorul unor obiecte de sincronizare, pe care firele le pot utiliza pentru a informa alte fire despre starea lor, de a proteja zone senzitive de cod sau de a obtine informatii despre alte fire sau starea altor obiecte.
In Win32 multe resurse nucleu sunt reprezentate ca obiecte - obiecte nucleu: fisiere, fire, procese, obiecte de sincronizare, etc. Obiectele sunt referite prin manipulatori, identificatori (handlers); exista functii pentru manipularea generica a obiectelor, pentru manipularea obiectelor de un anumit tip. Sub NT, obiectele au atasate proprietati de securitate. De exemplu, un fir nu poate accesa un obiect fisier daca nu are drepturile necesare care sa coincida cu proprietatile de securitate.
Modulul nucleu furnizezza de asemeni functii pentru gestionarea resurselor interfata-utilizator. Aceste resurse includ icoane, cursoare, sabloane de dialog, resurse string, tabele de acceleratori, bitmap-uri, etc.
Nucleul NT furnizeaza printre altele: atribute de securitate pentru obiectele nucleu, backup, functionalitatea aplicatiilor de tip consola care pot utiliza functii pentru memoria virtuala sau pot utiliza mai multe fire de executie.
Servicii utilizator
Modulul utilizator furnizeaza apeluri sistem care gestioneaza aspecte si elemente ale interfetei utilizatorului; sunt incluse functii care manipuleaza ferestre, dialoguri, meniuri, controale, clipboard, etc. Se exemplifica tipurile de operatii pentru fiecare resursa în parte (în general creare, modificare, stergere, mutare, redimensionare, etc.).
Modulul utilizator furnizeaza functii pentru managementul mesajelor si cozilor de mesaje. Aplicatiile pot utiliza aceste apeluri pentru a controla continutul cozii de mesaje proprii, a regasi si a procesa mesajele, a crea noi mesaje. Noile mesaje pot fi trimise (sent) sau plasate (posted) la orice fereastra. Un mesaj plasat pentru o fereastra - functia PostMessage - înseamna pur si simplu intrarea acestuia în coada de mesaje nu si procesarea imediata a acestuia. Trimiterea unui mesaj (sent) implica tratarea lui imediata sau mai corect spus functia SendMessage nu-si termina executia pîna când mesajul nu a fost tratat.
Servicii GDI
Functiile din GDI sunt utilizate în mod obisnuit pentru a executa operatii grafice primitive independente de dispozitiv pe contexte de dispozitiv. Un context de dispozitiv este o interfata la un periferic grafic specific (în fapt este o structura de date pastrata în memorie). Contextul de dispozitiv poate fi utilizat pentru a obtine informatii despre periferic si pentru a executa iesirile grafice pe acest periferic. Informatiile care pot fi obtinute printr-un context de dispozitiv, descriu în detaliu acest periferic.
Iesirea grafica este executata printr-un context de dispozitiv prin pasarea (trecerea) unui manipulator (identificator) al contextului de dispozitiv functiilor grafice din GDI
Contextele de dispozitiv pot descrie o varietate mare de periferice. Contextele de dispozitiv obisnuite includ: contexte de dispozitiv display, contexte de dispozitiv memorie (pentru iesirea unui bitmap memorat în memorie) sau contexte de dispozitiv printer.
Un context de dispozitiv foarte special este contextul de dispozitiv metafile care permite aplicatiilor de a înregistra permanent apelurile din GDI (fisierul pastreaza o serie de primitive grafice) care sunt independente de dispozitiv.
Metafisierele joaca un rol crucial în reperzentarea independenta de dispozitiv a obiectelor OLE înglobate.
Desenarea într-un context de dispozitiv se face cu ajutorul coordonatelor logice Coordonatele logice descriu obiectele utilizând masuratori reale independente de dispozitiv, de exemplu, un dreptunghi poate fi descris ca fiind lat de 2 inch si înalt de 1 inch. GDI furnizeaza functionalitatea necesara pentru maparea coordonatelor logice în coordonate fizice.
Diferente semnificative exista în modul cum aceasta mapare are loc în Win32s, Windows 95 si Windows NT.
Win32s si Windows 95 folosesc reprezentarea coordonatelor pe 16 biti.
Windows NT poate manipula coordonate pe 32 biti.
Toatre cele trei sisteme suporta mapari (transformari) din coordonate logice în coordonate fizice. Aceste transformari sunt determinate (influentate) de valorile ce specifica originea coordonatelor si (signed extent) extensia cu semn a spatiului logic si al celui fizic.
Originea coordonatelor specifica deplasarea pe orizontala si verticala, iar extensia (extent) determina orientarea si scara obiectelor dupa mapare (transformare).
În plus, Windows NT ofera ceea ce se numeste world transformation functions. Prin aceste functii, orice transformare liniara poate fi folosita pentru transformarea spatiului de coordonate logice în spatiul de coordonate fizice; în plus pentru translatii si scalare iesirile pot fi rotite sau sheared.
Exemple de functii grafice: Rectangle, Ellipse, Polygon, TextOut, etc.
Alte functii de interes deosebit (bit blit functions: PatBlt, BitBlt, StechBlt) sunt cele legate de desenarea si copierea bitmap-urilor.
Contextele de dispozitiv pot fi create si distruse, starea lor poate fi salvata si reîncarcata.
Un alt grup de functii gestioneaza transformarile de coordonate. Functii comune tuturor platformelor pot fi utilizate pentru a seta sau regasi originea si extent-ul unei ferestre (spatiul de coordonate logic) si viewport-ului (spatiul de coordonate al perifericului destinatie).
NT poseda functii specifice pentru transformari matriceale.
Functiile GDI pot fi folosite de asemenea pentru gestionarea paletelor, aceasta înseamna ca prin gestionarea paletei de culori, aplicatiile pot selecta o multime de culori care se potrivesc cel mai bine cu culorile din imaginea (gif, pcx.) care trebuie afisata. Gestionarea paletei poate fi utilizata si în tehnici de animatie.
O alta trasatura a GDI-ului este crearea si gestionarea obiectelor GDI (pensoane, penite, fonturi, bitmap-uri, palete) precum si a regiunilor si a clipping-ului.
Alte API-uri
Functii pentru controale comune;
Functii pentru dialoguri comune;
MAPI (Messaging Applications Programming Interface);
MCI (Multimedia Control Interface);
OLE API
TAPI (Telephony API).
Raportarea erorilor
Majoritatea functiilor Windows folosesc un mecanism pentru evidentierea erorilor. Când apare o eroare, aceste functii seteaza o valoare a erorii pentru firul respectiv, valoare care poate fi regasita cu functia GetLastError
Valoarile pe 32 biti, returnate de aceasta functie sunt definite in winerror.h sau în fisierul header al bibliotecii specifice.
Valoarea erorii poate fi setata si din cadrul aplicatiei cu ajutorul functiei SetLastError. Codurile de eroare trebuie sa aiba setat bitul 29.
Folosirea functiilor din biblioteca
C/C++
Aplicatiile Win32 pot folosi setul standard al functiilor din biblioteca C/C++ cu anumite restrictii. Aplicatiile Windows nu au acces în mod normal la stream-urile stdin, stdout, stderr sau obiectele iostream din C++. Numai aplicatiile consola pot utiliza aceste stream-uri.
Functiile relative la fisiere pot fi folosite, dar acestea nu suporta toate facilitatile oferite de SO Windows - securitate, drepturi de acces.
În locul functiilor din familia exec se va folosi CreateProcess.
În ceeea ce priveste gestionarea memoriei se folosesc cu succes functiile din C sau C++. Functiile din biblioteca matematica, pentru gestionarea stringurilor, a bufferelor, a caracterelor, a conversiilor de date pot fi de asemenea folosite.
Aplicatiile Win32 nu trebuie sa foloseasca întreruperea 21 sau functii IBM PC BIOS.
|