Modelul de programare Windows

 

In cazul programelor pentru Windows, execuţia instrucţiunilor nu mai urmează ordinea strictă impusă de utilizator ci ordinea dictată de funcţionarea sistemului de operare Windows, care procesează īn permanenţă mesaje. Programul utilizatorului este un răspuns la un anumit mesaj (engl. event-driven programming). Programele pentru Windows īncep cu funcţia WinMain( ), īn cadrul căreia este  creată fereastra şi programul intră īntr-o buclă de aşteptare şi procesare a mesajelor (dispatch message).

Atunci cānd apare un eveniment, Windows trimite un anumit mesaj către funcţia de procesare asociată ferestrei noastre (CALLBACK window procedure). Pe baza mesajelor primite, această funcţie execută majoritatea acţiunilor programului, atāt aspectul ferestrei cāt şi acţiunile programate de utilizator. Bucla se īncheie cu trimiterea mesajului WM_QUIT către fereastră. Aceasta este echivalent cu īnchiderea ferestrei şi sfārşitul aplicaţiei. De obicei, funcţia CALLBACK face apelurile către toate funcţiile necesare, care sunt locale şi API (Application Programming Interface)

Funcţiile locale sunt create de utilizator iar API sunt specifice Windows, fiind localizate īn bibliotecile DLL (Dynamic Link Libraries), mai ales USER32.dll, KERNEL32.dll, GDI.dll şi COMMCTRL32.dll. API dau aspectul grafic specific (look and feel) pentru Windows. Există mii de mesaje specifice, dar un anumit program nu trebuie să le folosească pe toate. In plus, multe funcţii API sunt aparent greoi de folosit din cauza moştenirii lăsate de Windows 3.1 care lucra cu reurse mult mai modeste. Există o funcţie API numită DefWindowProc care poate fi folosită ca un răspuns implicit la procesarea mesajelor.

In cadrul API sunt predefinite mai multe elemente utile pentru programele ce folosesc o interfaţă grafică:

*   Funcţii pentru mouse

*   Icoane şi imagini (de tip bmp)

*   Meniuri, bare de instrumente, bare de stare, casete de dialog

 

Concepte importante

 

Bibliotecile translatabile (header files, include files)

Toate programele care folosesc ferestre trebuie să folosească windows.h, care conţine prototipuri pentru toate funcţiile API.

 

Resurse

 

Resursele sunt un termen folosit pentru a desemna meniurile, icoanele, casetele de dialog, sau alte elemente ale interfeţei grafice care ssunt parte din program dar nu sunt cod executabil (scris de utilizator). Ele sunt mai degrabă obiecte  folosite de program. De aceea majoritatea programelor pentru Windows conţin un fişier de resurse (rsrc.rc) care conţine aspectul interfeţei grafice (meniuri, casete de dialog, butoane). Pentru fişierul de resurse avem un compilator separat care produce un cod obiect care va fi legat de restul programului sursă. Fişierele de tip resursă pot fi evitate prin specificarea elementelor ferestrei īn programul principal.

De aceea, programele sub Windows sunt īntotdeauna proiecte.

Un program care declară standard o fereastră este relativ lung pentru īnceput. Se poate folosi un truc care constă īn declararea unei casete de dialog, care este mult mai simplă.

 

WinMain( )

In locul funcţiei main( )  din programele C, suntem obligaţi să folosim WinMain().

 

int WINAPI WinMain (

     HINSTANCE hThisInst,    // instanţa curentă a programului

     HINSTANCE hPrevInst,    // instanţa anterioară a programului (depăşit)

     LPSTR lpszArgs,         // argumentele liniei de comandă (depăşit)

     int nWinMode            // specifică starea ferestrei

                   )

 

Această funcţie trebuie să īndeplinească următoarele funcţii:

*   1. Definirea unei clase pentru fereastră.

*   2. Inregistrarea acestei ferestre le sistemul de operare Windows.

*   3. Crearea feretrei specificate de acea clasă.

*   4. Afişarea ferestrei.

*   5. Incepe derularea buclei de mesaje.

 

Funcţia CALLBACK

 

Cānd mesajele sunt primite, funcţia CALLBACK asociată ferestrei iniţiază acţiuni asupra altor funcţii, mai ales API.

Mesajele

Fiecare mesaj īncepe cu secvenţa WM_ , de exemplu WM_QUIT sau WM_PAINT, īn funcţie de eveniment. Mesajele sunt trimise ca o tructură care conţine toate informaţiile despre eveniment şi are patru parametri:

*   fereastra īn discuţie (handle)

*   Identificatorul mesajului, care constă din doi īntregi pe 32 biţi, cunoscuţi ca lParam şi wParam. Pe baza lor avem: identificatorul de control: LOWORD(wParam); mesajul de control,  HIWORD(wParam); controlul ferestrei, (HWND)lParam

*   Un cāmp legat de timp

*   O structură care conţine o coordonată

 

typedef struct tagMSG

{

        HWND hwnd; /* window that message is for */

        UINT message; /* message */

        WPARAM wParam; /* message-dependent information */

        LPARAM lParam; /* more message-dependent information */

        DWORD time; /* time message posted */

        POINT pt; /* X,Y location of mouse */

} MSG;

 

Atāt wParam cāt şi lParam constau din segmente de 16 biţi, adresate cu funcţiile LOWORD şi HIWORD folosite după cum urmează:

x = LOWORD(lParam);

z = HIWORD(wParam);

De exemplu, la apăsarea unei taste este emis mesajul WM_CHAR. wParam conţine codul ASCII al tastei apăsate, LOWORD(lParam)  conţine numărul de apăsări ale tastei iar HIWORD(lParam) detalii suplimentare

Mnemonica:

CTLID LOWORD(wParam) = Identificatorul elementului de control pentru WM_COMMAND

CTLMSG HIWORD(wParam) = Mesajul transmis de elementul de control, pentru

                                                     WM_COMMAND

HCTL   (HWND)lParam = Identificatorul fereastra al elementului de control

 

Clasa asociată ferestrei

Trebuie să definim şi să īnregistrăm fereastra la sistemul de operare (Windows), după care să rulăm bucla de mesaje.

 

Bucla de mesaje

Programul crează o buclă īn interiorul funcţiei WinMain() şi citeşte mesajele din lista de aşteptare a ferestrei, după care execută acţiunea asociată.

 

Contextul de dispozitiv

Contextul de dispozitiv este o imagine (bitmap, structură de date) asociată cu un dispozitiv de afişare (ecran sau imprimantă). Un program care urmează să afişeze pe ecran trebuie să obţină un context de dispozitiv, hdc=GetDC(hwnd). Acestea trebuie dezactivate cānd nu mai sunt folosite, ReleaseDC(hwnd,hdc). Aplicaţiile grafice sunt permise numai īn cadrul unui context de dispozitiv.