Document, comentariu, eseu, bacalaureat, liceu si facultate
Top documenteAdmitereTesteUtileContact
      
    


 


Ultimele referate adaugate

Adauga referat - poti sa ne ajuti cu un referat?

Politica de confidentialitate



Ultimele referate descarcare de pe site
  CREDITUL IPOTECAR PENTRU INVESTITII IMOBILIARE (economie)
  Comertul cu amanuntul (economie)
  IDENTIFICAREA CRIMINALISTICA (drept)
  Mecanismul motor, Biela, organe mobile proiect (diverse)
  O scrisoare pierduta (romana)
  O scrisoare pierduta (romana)
  Ion DRUTA (romana)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  Starea civila (geografie)
 

Ultimele referate cautate in site
   domnisoara hus
   legume
    istoria unui galban
   metanol
   recapitulare
   profitul
   caract
   comentariu liric
   radiolocatia
   praslea cel voinic si merele da aur
 
despre:
 
Meniuri
Colt dreapta
Vizite: ? Nota: ? Ce reprezinta? Intrebari si raspunsuri
 

 

Un meniu este o lista de elemente care pentru utilizator constituie comenzi ale aplicatiei. Dar nu numai atit, dupa cum s-a putut constata din exemplul prezentat in soc11.txt, caci elementele din meniu pot fi si optiuni ale aplicatiei intre care putem alege, pot fi generatoare a altor sub-meniuri etc. j2x7xn
Utilizatorul "spune" aplicatiei sa faca ceva prin selectarea unui element de meniu cu ajutorul mouse-ului sau tastaturii. Windows - care se ocupa de zona sistem a ferestrei aplicatiei - trateaza evenimentul prin trimiterea catre procedura ferestrei a unui mesaj WM_COMMAND indicind totodata si care este elementul de meniu (prin ID-ul sau identificatorul sau).
Pasii pentru a atasa un meniu la o aplicatie sint:
1. Definirea meniului cu ajutorul unui editor de resurse sau scrierea lui manuala in fisierul de resurse al aplicatiei.
2. Specificarea meniului pentru fereastra aplicatiei:
- la definirea stucturii clasei de ferestre sau
- la crearea ferestrei prin functia CreateWindow().
3. Initialazarea meniului daca e cazul.

Pe parcursul rularii aplicatiei meniul asigura interactiunea cu utilizatorul generind comenzi specifice catre aplicatie dar la rindul ei in anumite circumstante e posibil ca aplicatia sa schimbe starea unor elemente de meniu, sa adauge sau sa stearga elemente din meniu sau chiar sa schimbe complet meniul aplicatiei.

Definirea unui meniu

Dupa ce stim in mod cert care vor fi optiunile si comenzile pe care aplicatia va trebui sa le puna la dispozitia utilizatorului, putem cu ajutorul unui editor de resurse sau manual sa definim meniul. In exemplul de mai jos am definit o stuctura de meniu folosind toate facilitatile puse la dispozitie de editorul Workshop. Editorul este foarte comod, putind testa tot timpul structura noului meniu.
Editorul de resurse genereaza fisierul .RC in care apare meniul definit in limbajul specific de descriere pentru meniuri. Putem apoi, cu un editor de texte sau din mediu de lucru sa facem mici ajustari acolo unde dorim.




MENU Meniu
BEGIN
POPUP "Grup&1"
BEGIN
MENUITEM "Element 11", IDM_EL 11
MENUITEM "Element 12", IDM_EL 12
MENUITEM SEPARATOR
MENUITEM "Element 13 invalidat",IDM_EL 13,INACTIVE
MENUITEM "Element 14 inactiv",IDM_EL 14,GRAYED
MENUITEM "Element 15 marcat",IDM_EL 15,CHECKED
MENUITEM "Col 11", IDM_EL 16,MENUBARBREAK
MENUITEM "Col 21",IDM_EL 17,MENUBARBREAK
MENUITEM "Col 31",IDM_EL 18,MENUBREAK
MENUITEM SEPARATOR
END

...

Dupa cum se observa meniurile folosesc doar doua instructiuni POPUP (urmata de structura BEGIN-END) pentru a numi elementele barei si MENUITEM pentru elementele unui pop-up. Aceste directive sint urmate de numele elementului, identificatorul atasat si eventuale atribute.
Identificatorii sint definiti intr-un header inclus in fisierul de resurse si in sursa modulului ce ii foloseste. Pentru exemplul dat fisierul header contine :

#define IDM_EL 11 101
#define IDM_EL 12 102
#define IDM_EL 13 103
#define IDM_EL 14 104
#define IDM_EL 15 105
#define IDM_EL 16 106
#define IDM_EL 17 107
#define IDM_EL 18 108
#define IDM_EL 21 201
#define IDM_EL 221 221
#define IDM_EL 222 222

Atributele pe care le poate avea un element de meniu sint:

CHECKED elementul are un marcaj
GRAYED elementul este initial inactiv si va apare intr-o nuanta deschisa
HELP elementul va fi aliniat la dreapta
INACTIVE element afisat dar care nu are o actiune
MENUBARBREAK elementul va fi pe o noua coloana separat de o bara
MENUBREAK pentru bare de meniu elementul va fi pe o linie noua, iar pentru element de pop-up va fi pe o noua coloana dar fara separare cu bara

De precizat ca atributele INACTIVE si GRAYED sint exclusive.

Includerea meniurilor in aplicatie

Dupa cum s-a prezentat mai devreme avem doua pasibilitati. Una este sa specificam numele meniului din structura clasei ferestrelor aplicatiei. De exemplu daca acesta se numeste "MENU":
wndClass.lpszMenuName = "MENU"
Din momentul inregistrarii clasei, ferestrele ce se creaza pe baza ei vor avea meniul identic cu cel definit in resurse prin directiva
MENU Meniu
Daca dorim ca abia in momentul creerii ferestrei sa atasam acesteia un meniu vom proceda in felul urmator:

HANDLE hWnd,hMenu;

... hMenu=LoadMenu(hInst,"Meniu"); hWnd=CreateWindow(.......,hMenu,hInst,NULL);

Deci functia LoadMenu() incarca din instanta aplicatiei resursa meniu cu numele "Meniu" obtinind un handle la acesta, care apoi va fi comunicat ca parametru functiei de creare a ferestrei.

Procesarea intrarilor din meniu

Daca reluam exemplul din soc11.txt vom vedea ca stuctura de program pentru tratarea meniului este :

... switch(message)
A
... case WM_COMMAND: switch(wParam)A case IDM_EL11:
//codul comenzii "Element 11"; break; case IDM_EL12;
//codul comenzii"Element 12"; break;
...
S break;

deci mesajul WM_COMMAND este tratat functie de valoarea parametrului wParam care contine ID-ul elementului de meniu ce a fost actionat.

Lucrul cu meniurile intr-o aplicatie

Dupa cum s-a putut constata pina acum se pare ca e chiar banal sa echipezi interfata unei aplicatii cu meniu. Lucrurile nu se opresc insa doar aici.
Interfata API Windows mai are multe facilitati legate de meniuri. Majoritatea acestora stau la dispozitie prin citeva functii specifice. In continuare vom vedea ce se poate face cu ele:

Activarea, inactivarea elementelor de meniu

Un element de meniu are o stare initiala fixata de atributul atasat lui in procesul definirii. Pentru a-l putea modifica trbuie intii sa obtinem handle-ul meniului ferestrei - hMenu. Dupa aceasta, cu functia
EnableMenuItem(hMenu, IDM_elem, MF_flag ) se poate atasa elementulului
IDM_elem starea data de flagul:

MF_DISABLED inactiv
MF_ENABLED activ
MF_GRAYED dezactivat

Marcajul unui element din meniu

Exista posibilitatea ca aplicatia sa semnalizeze utilizatorului ca un element de meniu a fost selectat(comutat). Aceasta facilitate se utilizeaza cu precadere acolo unde se realizeaza meniuri cu optiuni. Marcajul poate fi stabilit inca din faza definirii resursei folosind atributul CHECKED. Modificarea in timpul rularii se poate face cu functia CheckMenuItem(hMenu,IDM_elem,MF_flag) unde ultimul parametru poate fi:

MF_CHECKED -marcare element
MF_UNCHECKED -demarcare element

Adaugarea, inserarea unor elemente

Iata o posibilitate comoda de a modifica continutul unui meniu. Pentru aceasta avem functiile AppendMenu(hMenu,MF_flag,IDM_elem,"NumeElement") care adauga la sfirsitul listei un element cu starea MF_flag,ID_ul IDM_elem si numele "NumeElement". Daca MF_flag este

MF_POPUP-se adauga un nou pop-up.

Ca si functia de adaugare, functia de inserare permite introducerea in meniu a unui element nou precizat prin ID si nume doar ca in acest caz se precizeaza si elementul inaintea caruia se fece inserarea. Functia este
InsertMenu(hMenu,IDM_elempoz,MF_flagpoz|MF_flagstare,IDM_elem,"NumeElement" ).
Flagul MF_flagpoz poate fi:

MF_BYCOMMAND-par. IDM_elempoz este ID-ul elementului fata de care se face pozitionarea
MF_BYPOSITION-par. IDM_elempoz este pozitia elementului (primul e 0) in meniu.

Modificarea, stergerea unor elemente

Este posibila si modificarea numelui sau/si cea a ID-ului precum si a starii folosind functia ModifyMenu(hMenu,IDM_vechi,MF_flagpoz|MF_staremod,
IDM_nouvechi,"Numenou");
Parametrii corespund specificatiilor anterioare.
Pentru stergerea unui element din meniu avem la dispozitie functia DeleteMenu
(hMenu,IDM_elempoz,MF_flagpoz)

Utilizarea unui desen ca element de meniu

O surprinzatoare si foarte atragatoare facilitate este aceea de a putea relativ simplu sa realizam un meniu ddin imagini si nu cuvinte. Procedeul consta din utilizarea functiei ModifyMenu() impreuna cu citeva flaguri MF_staremod speciale. Acestea sunt :

MF_BITMAP -insemnind ca ultimul parametru va fi un handle de desen
MF_OWNERDRAW -insemnind ca la orice redesenare a elementului de meniu, procedura ferestrei aplicatiei (proprietatea meniului -OWNER)va fi instiintata prin mesaje specifice ca trebuie sa-si deseneze (DRAW) elementul.

Iata un mic exemplu preluat dintr-o functie WinMain() a unei aplicatii care incarca din rsurse (hInst, dar ar putea la fel de bine sa incarce dintr-o biblioteca dinamica .DLL sau din modulele Windows) un desen care aici se cheama "Ajutor" si care va apare ca element de meniu:
Deci inainte de afisarea ferestrei este obtinut handle_ul hBitmap de la functia ce incarca din resurse desenul "Ajutor", apoi handle_ul meniului ferestrei aplicatiei hMenu, dupa care se modifica elementul de meniu IDM_AJUTOR.
Se observa ca handle_ul desenului este extins de la WORD la LONG cu ajutorul macro_ului MAKELONG() dupa care este adus de la tipul pointer long la sir de caractere (LPSTR). Acest lucru este obligatoriu deoarece in mod implicit functia ModifyMenu lucreaza cu flagul MF_STRING ce presupune ca ultim parametru un sir de caractere.

... hBitmap=LoadBitmap(hInst,"Ajutor"); hMenu=GetMenu(hWnd);
ModifyMenu(hMenu,IDM_AJUTOR,MF_BYCOMMAND|MF_BITMAP,IDM_AJUTOR,

(LPSTR)MAKELONG(hBitmap,0));

ShowWindow(hWnd,SW_NORMAL);

Inlocuirea unui meniu

Meniul unei ferestre poate fi inlocuit cu un altul folosind functia
SetMenu(hWnd,hMenunou). Pentru aceasta trebuie ca in resurse sa fie definite ambele meniuri (sau mai multe). Secventa de program ce urmeaza exemplifica o modalitate:

...
HMENU hOldMenu,hNewMenu;
... hOldMenu=GetMenu(hWnd); hNewMenu=LoadMenu(hInstance,"Meniu2");
SetMenu(hWnd,hNewMenu);
...

Crearea unui meniu in timpul rularii

Chiar daca pare surprinzatoare aceasta posibilitate totusi exista si poate fi utila celor care nu doresc sa editeze resurse. Exista deci o functie,
CreateMeniu care creaza un meniu gol ce poate fi apoi completat cu ajutorul functiilor Append,Insert,ModifyMenu().
In final este dat un astfel de exemplu, generat de faptul ca acel meniu este doar temporar creat.

Initializari

Cu toate ca starea initiala a elementelor unui meniu poate fi stabilita inca din definirea resursei, prin atributele atasate fiecarui element, Windows
API pune la dispozitia aplicatiei si un mesaj special WM_INITMENU care este receptionat de procedura ferestrei aplicatie chiar inainte de a fi afisat meniul.
Este momentul in care aplicatia poate modifica starea de validare/invalidare/dezactivare sau marcajul unor elemente din meniu.
In privinta meniurilor exista citeva extra-facilitati.

* Suport pentru tastatura

Am facut deja cunostiinta in laboratoarele anterioare cu Tabela Acceleratorilor.
Aceasta resursa a fost special gindita pentru imbunatatirea accesului la comenzile implementate in meniuri. Vom insista doar asupra modului de a-i insera in in textul meniului. Regula este ca acestia sa apara la dreapta elementului din meniu. Pentru aceasta au fost introduse secventele "\t","\a" pentru aliniere la Tab. si pentru aliniere la dreapta a caracterelor ce le succed. Mai trebuie precizata importanta majora a caracterului "&" care precede litera care devine Hot-Key (tasta de acces rapid) pentru elementele meniului. Ca exemplu iata o comanda din meniul sistem.

MENUITEM"&Close\aAlt+F4"

* Utilizarea unor meniuri cascade

Acesta facilitate apare datorita posibilitatii de a incapsula in locul unui element de meniu un element de pop-up. Se poate construi astfel un exemplu de cascade. Codul generat de compilatorul de resurse, sau pe care ar trebui sa-l scriem este:

...
POPUP "Grup&2"
BEGIN
MENUITEM "Element21",IDM_EL"
POPUP "Subgrup22"
BEGIN
MENUITEM "Element 221",IDM_EL221
MENUITEM "Element 222",IDM_EL222
END
END
...

Un meniu pop-up cascadat cum este in exemplu prezentat "Subgrup22" are propriul sau handle. Pentru a putea lucra asupra elementelor lui de meniu este deci necesara obtinerea acestui handle cu functia GetSubMenu(hMenu,npoz) unde npoz este un intreg desemnind pozitia (de la zero) a meniului pop-up in meniul parinte.

Utilizarea unor meniuri pop-up flotante

In mod normal meniurile pop-up sint legate de bara de meniu. Iata insa ca Windows da posibilitatea ca folosind doua functii sa cream si apoi sa pozitionam unde dorim un meniu pop-up. Aceste functii sint CreatePopupMenu() si TrackPopupMenu(hFlotMenu,TPM_flags,x,y,hWnd,lprect) dintre parametrii caruia trebuie precizat ca al doilea reprezinta un flag sau o reuniune de flag-uri (proprietati) ale meniului pop-up dupa cum urmeaza:

TPM_LEFTALIGN -alinierea meniului la coordonata x stinga
TPM_CETRALIGN --//- central
TPM_RIGHTALIGN --//- drepta
TPM_LEFTBUTTON -meniu sensibil la butonul stinga
TPM_RIGHTBUTTON -meniu sensibil la butonul dreapta al mouse-lui

Iata fragmentul de cod corespunzator ce apare la apasarea butonului din dreapta a mouse-ului :

POINT ptCurrent;
HMENU hFlotMenu; switch(message)A case WM_RBUTTONDOWN; ptCurrent = MAKEPOINT(lParam); hFlotMenu = CreatePopupMenu();
AppendMenu(hFlotMenu,MF_ENABLED,IDM_EL11,&Elipsa\tF1");
AppendMenu(hFlotMenu,MF_ENABLED,IDM_EL12,"&Patrat\tF2");
AppendMenu(hflotMenu,MF_ENABLED,IDM_EL13,"&Triunghi\tF3");
AppendMenu(hFlotMenu,MF_SEPARATOR,-1,"");
AppendMenu(hFlotMenu,MF_ENABLED,IDCANCEL,"E&xit\tAlt+F4);
ClientToScreen(hWnd,&ptCurrent);
TrackPopupMenu(hFlotMenu,TPM_LEFTALIGN,ptCurrent.x, ptCurrent.y,0,hWnd,NULL);
DestroyMenu(hFlotMenu); break;

Utilizarea unor marcaje desenate de proiectant

Datorita faptului ca fiecare element de meniu este de fapt o structura careia ii sint atasate cele doua mici desenase cu simbolul de marcaj respectiv demarcaj, in Windows API exista dpua functii cu care putem realiza marcaje originale. Acestea sint GetMenuCheckMarkDimension() cu care se gaseste dimensiunea la care trebuie scalat desenul si SetMenuItemBitmaps(hMenu,poz,
MF_BYPOSITION,hbmpMarc,hbmpDemarc), unde in ultimii doi parametri se specifica handle-urile celor doua desene cu care se va face marcajul la elementul specificat.
Meniurile din Windows reprezinta oarecum un domeniu ajuns la excelenta.
Implementarea, modificarea, adaptarea lor la natura sau faza unei aplicatii este deosebit de facila datorita intregului mecanism de serviciu automat din nucleu.

Ferestrele "copil"

In aproape orice aplicatie Windows sintem pusi la un moment dat sa "apasam" un buton, sa facem o selectie dintr-o lista sau se introducem un sir de caractere.
Toate acestea se fac in zone speciale ale spatiului client al ferestrei aplicatiei sau intr-o fereastra de dialog. Aceste zone sint de fapt la rindul lor ferestre care apartin ferestrei ce le contine, relatia dintre ele fiind de la "copil"la "parinte".
Fereastra copil poate afla cine este parintele sau prin functia GetParent(). In exemplul urmator o fereastra copil, cu handle-ul hWnd, isi informeaza parintele printr-un mesaj: SendMessage(GetParent(hWnd),mesaj,wParam,lParam)
Aceasta este filozofia de lucru a tuturor controalelor. Am intilnit-o pina acum la elementele de meniu care comunicau procedurii ferestrei selectia lor prin mesajul WM_COMMAND. Exact in acest mod lucreaza oricare control. Procedura lui de fereastra proceseaza intrarile de la tastatura sau mouse, isi schimba daca e cazul aspectul (se redeseneaza) si informeaza apoi parintele despre schimbarea starii lui.
Aceasta informare se face, in majoritatea cazurilor, prin mesajul WM_COMMAND, in care parametrul wParam poarta identificatorul controlului-ID-ul sau idItem, iar parametrul lParam contine handle-ul ferestrei copil pe cuvintul superior-hwndCtl si mesajul de notificare (informare) pe cuvintul inferior-wNotifyCode. Iata definitia acestui mesaj:

WM COMAND idItem=wParam; hwndCtl=(HWND)LOWORD(lParam);
wNotifyCode=HIWORD(lParam);

In acest fel diferitele controale ale unei ferestre de aplicatie sau de dialog devin dispozitive de intrare a informatiei pentru aplicatie. In acelasi timp unele dintre controale pot afisa o anume informatie devenind dispozitive de iesire.
Controale predefinite

Interfata API Windows cuprinde un set de controale predefinite sub forma unor butoane de apasare-PUSHBUTTON, butoane de optiune-RADIOBUTTON singure sau grupate-GROUPBOX, casute de marcaj-CHECKBOX, liste simple-LISTBOX sau combinate cu cimpuri de editare-EDIT, precum si controale statice-STATIC care nu reactioneaza la mouse sau tastatura. Toate aceste controale sint prezente prin definirea claselor lor in lansarea Windows-ului, mai precis la lansarea modului USER.EXE care cuprinde si procedurile specifice fiecarui control.

Astfel si aplicatia noastra foloseste codul din nucleu la care au acces prin declaratiile din fisierul header windows.h. Clasele de ferestre corespunzatoare acestor controale sint "static","button","scrollbar","edit","listbox" si
"combobox". Deoarece controalele se folosesc cu precadere in ferestrele de dialog, orice editor de resurse cu care se editeaza macheta dialogului pune la dispozitia programatorului aceste controale predefinite care pot fi pozitionate, scalate, inscriptionate dupa nevoie. Este posibila insa si crearea lor dinamica, deci in momentul rularii aplicatiei, folosind functia CreateWindow() care va primi ca parametri clasa (predefinita), stilul controlului, pozitia, etc..
Totusi folosirea controalelor direct in fereastra aplicatiei, spre deosebire de folosirea lor in ferestre de dialog este mai greoaie deoarece implica implementarea unor mecanisme de baleiaj a controalelor (cu tastele TAB si/sau sageti) sau cedarea focus-ului (proprietatea ferestrei ce presupune ca la un moment dat intrarile de mouse sau tastatura sint directionate spre fereastra respectiva), mecanisme care exista implementate in functia Default de gestiune a ferestrelor de dialog.

Culorile controalelor

In orice moment al rularii unei aplicatii sub Windows exista posibilitatea de a folosi culorile pe care nucleul le foloseste cind deseaneaza elementele unei ferestre (sint 19 culori referentiabile in driverul de ecran cu care functioneaza Windows-ul). Aceste culori formeaza o schema de culori-color scheme ce poate fi modificata-vezi utilitarul Control Panel din Program
Manager, grupul Main, la functia Colors). In continuare vom prezenta citiva dintre identificatorii folositi in windows.h pentru referinta la diverse culori:

COLOR_BACKGROUND-fondul desktop
COLOR_WINDOW-fondul unei ferestre
COLOR_WINDOWTEXT-textul unei ferestre
COLOR_WINDOWRAME-linia de contur a unei ferestre
COLOR_ACTIVECAPTION-fondul titlului unei ferestre active
COLOR_INACTIVECAPTION-fondul titlului unei ferestre inactive
COLOR_MENU-fondul meniului
COLOR_MENUTEXT-textul meniului etc...

Toate aceste culori pot fi aflate prin functia GetSysColor() si modificate cu SetSystemColor(). A doua functie trebuie utilizata cu grija pentru ca efectul ei este global pentru toata suprafata grafica.
De exemplu daca dorim sa scriem un text in fereastra aplicatiei folosind functia TextOut(), aceasta va folosi pentru culoarea de fond respectiv culoarea textului valorile implicite ale contextului hdc deci alb si negru. Pentru a fi consistenti cu culorile sistem putem sa scriem:

SetBkColor(hdc,
GetSysColor(COLOR_WINDOW);
SetTextColor(hdc,
GetSysColor(COLOR_WINDOWTEXT);
TextOut(...)

In cazul unui control predefinit, la fiecare operatie de (re)desenare parintele este instiintat de catre acesta prin mesajul WM_CTCOLOR, acesta putind astfel modifica culorile in care va apare controlul. Parametrii mesajului semnifica: wParam-contextul dispozitivului de afisare pentru fereastra copil hdc

LOWORD(lParam)-handle-ul ferestrei copil
HIWORD(lParam)-tipul ferestrei copil
CTLCOLOR_MSGBOX-ferestra de mesaj
CTLCOLOR_EDIT-control de editare
CTLCOLOR_LISTBOX-lista
CTLCOLOR_BTN-buton(cu exceptia celor de apasare)
CTLCOLOR_DLG-fereastra de dialog
CTLCOLOR_SCROLLBAR-bara de defilare
CTLCOLOR_STATIC-control static.

Tratarea acestui mesaj presupune o secventa ca in exemplul urmator:

...pe parcursul initializarii aplicatiei... hBrush=CreateSolidBrush(GetSysColor(COLOR_WINDOW));
...in procedura ferestrei aplicatiei... case WM_CTLCOLOR: if(HIWORD(lParam)=CTLCOLOR_BTN)A
SetBkColor(wParam,GetSysColor(COLOR_WINDOW));
SetTextColor(wParam,GetSysColor(COLOR_WINDOWTEXT)); point.x=point.y=0;
ClientToScreen(hwnd,&point);
SetBrushOrg(wParam,point.x,point.y);
UnrealizeObject(hBrush); return((DWORD)hBrush); break;
...in final nu uitati... case WM_DESTROY:
DeleteObject(hBrush);
..........

Citeva observatii :

-in primul rind nu trebuie uita ca "obiectele" de care se foloseste un anumit context grafic sint de fapt fragmente de memorie alocate din heap-ul global care dupa utilizare trebuie eliberate (de ex hBrush);
-trebuie observat ca pe baza tipului de control se poate face un filtru asa incit vor fi tratate doar butoanele (cu exceptia celor de apasare). Acestora li se modifica contextul de afisare prin setarea unei alte culori pentru fondul si culoarea textului.
-tratarea mesajului presupune returnarea unui handle la brush-ul care va fi folosit de control. Avem o situatie ceva mai complicata si mai subtila. Acest brush este la modul general un patern (deci o structura matriciala de pixeli) care va fi folosit in contextul de afisare al ferestrei copil pentru a umple suprafata ferestrei. Umplerea(fill) este un proces in care conteaza pozitia relativa a originii paternului fata de zona ce se va umple. Pentru ca sa nu apara nepotriviri intre felul in care este umpluta fereastra parinte si felul in care este umpluta fereastra controlului s-au obtinut coordonatele absolute
(de ecran) ale originii zonei client a parintelui (hwnd) prin functia
ClientToScreen() aceste coordonate devenind apoi originea brush-ului nou
SetOrgBrush(). Pentru ca schimbarea originii brush-ului sa fie operationala trebuie folosita functia UnrealizeObject() care va seta un flag al structurii brush marcind la prima utilizare (adica imediat dupa return) ca originea sa este schimbata. Alte doua mici observatii legate de hBrush :variabila trebuie sa fie statica (sau globala) iar procedura de fereastra trebuie sa poata returna handle-ul. Acest ultim lucru se refera doar la procedurile ferestrelor de dialog care asa cum am mai vazut in exemplele anterioare se declara cu BOOL FAR PASCAL in loc de LONG FAR PASCAL castul traditional al procedurilor de fereastra. Vezi exemplul prezentat.

Elemente statice - Clasa STATIC

Putem crea controale statice folosind cuvintul "static" la definirea clasei de care apartine fereastra nou creata. Aceste ferestre sint absolut benigne deoarece ele nu accepta intrari de mouse sau tastatura si nu trimit
WM_COMMAND spre fereastra parinte. De fapt ele "prind" miscarea mouse-ului deasupra lor sau apasarea unui buton prin mesajul WM_NCHITTEST returnind insa valoarea HITTRANSPARENT catre nucleu. Acest retur va provoca producerea aceluiasi mesaj WM_NCHITTEST catre fereastra de sub controlul static-uzual fereastra parinte.
Primele sase controale statice sint individualizate prin stiluri diferite
(parametrul style al ferestrei respective), putind fi dreptunghiuri pline:
SS_BLACKRECT, SS_GRAYRECT, SS_WHITERECT, sau chenare rectangulare:
SS_BLACKFRAME, SS_GRAYFRAME, SS_WHITEFRAME, unde culorile mentionate nu inseamna neaparat exact culorile BLACK-negru, WHITE-alb sau GRAY-gri, ci corespund culorilor sistem (system colors) utilizate la un moment dat si care corespund culorilor mentionate mai sus doar daca schema de culori cu care se lucreaza este Windows Default. In mod conventional deci s-a definit urmatoarea asociere:

BLACK-COLOR_WINDOWFRAME
GRAY-COLOR_BACKGROUND
WHITE-COLOR_WINDOW.

Clasa "static" mai include si alte stiluri acestea fiind: SS_LEFT,

SS_CENTER si SS_RIGHT care definesc o fereastra ce contine text aliniat stinga, central respectiv dreapta. Textul este cel specificat de parametrul window text al functiei CreateWindow. Acest stil este deosebit de util atunci cind, de exemplu, dorim sa fie afisat un anume text in fereastra aplicatiei.Textul unui control static poate fi modificat la orice moment prin apelul functiei SetWindowText.
In fine din aceeasi clasa fac parte si controalele statice definite cu stilul SS_ICON si SS_USERITEM cu ajutorul carora putem afisa desene definite in resursele aplicatiei sau sa le construim imaginea in momentul cind nucleul considera ca acel control trebuie (re)desenat pe ecran.

Barele de defilare - Clasa SCROLLBAR

Spre deosebire de toate celelalte controale predefinite copiii din aceasta clasa nu dialogheaza cu parintii prin WM_COMMAND. Exista in schimb doua mesaje unul generat de barele de defilare orizontale WM_HSCROOL. Aceasta deoarece acest control poate sa fie atasat direct unei ferestre de aplicatie prin precizarea unui stil de fereastra cu atribute WM_VSCROLL si/sau WS_HSCROOL. Mai mult, alte controale predefinite pot sa contina bare de defilare, de exemplu cimpurile de editare, listele, controale combinate. In cazul crearii unor ferestre copil ce dorim sa fie bare de defilare va trebui pe linga precizarea clasei "scrollbar" sa precizam stilul SBS_HORZ-orizontala sau SBS_VERT-verticala.
Cind se proceseaza mesajele de la barele de defilare se pot deosebi cele ale ferestrei de cele ale controalelor propriu-zise de defilare prin parametrul
HIWORD(lParam) care este nul in primul caz si contine handle-ul controlului in cel de-al doilea caz.
Domeniul de baleiaj pentru o bara de defilare se stabileste prin functia
SetScrollRange iar pozitia curenta in domeniu se fixeaza cu SetScrollPoss .
Mesajul WM_VSCROLL sau fratele sau WM_HSCROLL explica prin parametrii sai tot ce s-a intimplat asupra controlului. Parametrul wParam poate lua valorile:

-SB_PAGEDOWN si SB_PAGEUP pot apare la actionarea pe suprafata goala a barei cu mouse-ul sau apasarea tastelor PageDown si PageUp.
-SB_END si SB_TOP apar la actionarea tastelor Home si End.
-SB_LINEDOWN si SB_LINEUP apar la apasarea pe butoanele din capete ale barei sau apasarea sagetilor de la tastatura.

In afara de acestea cu mouse-ul se mai pot obtine doua actiuni distincte prin "tragere" de butonul pozitional al barei de defilare-SB_THUMBPOSITION si
SB_THUMBTRACK.
In afara de ultimile doua stari comunicate, pentru toate celelalte in parametrul lParam sosesc informatiile de identificare a controlului. HIWORD(lParam) este handle-ul ferestrei controlului iar LOWORD(lParam) semnifica pentru ultimile doua pozitia.

Exemplul

In exemplul de mai jos se prezinta un program care exemplifica mesajele
WM-CTLCOLOR si WM_VSCROLL. Se foloseste si un sablon pentru o fereastra de dialog pentru realizarea ferestrei aplicatiei. Studiati cu atentie declararea clasei pentru dialog, apoi precizarea unor octeti suplimentari pentru ferestrele care apartin clasei DLGWINDOWEXTRA. In final fereastra se creaza cu CreateDialog in loc de CreateWindow.

---------------------------------------------------------- #include <windows.h>
#include "w4.h"
HANDLE hInst; char szAppNameai="Culori"; long FAR PASCAL WndProcCulori(HWND,WORD,WORD,LONG);
#pragma argsused int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpsCmdLine, int cmdShow)A
HWND hWnd;
MSG msg;
WNDCLASS wndClass; hInst=hInstance; if(!hPrevInstance) A
wndClass.style =CS_HREDRAW | CS_VREDRAW;
wndClass.lpszClassName =szAppName;
wndClass.lpfnWndProc =(WNDPROC)WndProcCulori;
wndClass.cbClsExtra =0;
wndClass.cbWndExtra =DLGWINDOWEXTRA;
wndClass.hInstance =hInst;
wndClass.hIcon =NULL;
wndClass.hCursor =LoadCursor(NULL,IDC_ARROW);
wndClass.lpszMenuName =NULL;
wndClass.hbrBackground =(HBRUSH)CreateSolidBrush(RGB(0,0,0));
RegisterClass(&wndClass);
S hWnd=CreateDialog(hInst,szAppName,0,NULL);
ShowWindow(hWnd,cmdShow);

while(GetMessage( &msg,NULL,0,0))
A
TranslateMessage(&msg);
DispatchMessage(&msg);
S return msg.wParam;
S long FAR PASCAL WndProcCulori(HWND hWnd, WORD message,WORD wParam,LONG lParam)A static HBRUSH hBrusha3i; static BYTE color a3i;
POINT p; short n; static BOOL first=TRUE; switch (message) A case WM_CREATE: hBrusha0i=CreateSolidBrush(RGB(255, 0, 0) ); hBrusha1i=CreateSolidBrush(RGB(0, 255, 0) ); hBrusha2i=CreateSolidBrush(RGB(0, 0, 255) ); return 0; case WM_PAINT: if(first ) A first=FALSE; for(n=0;n<3;n++) A
SetScrollRange(GetDlgItem(hWnd,ID_SBR+n),SB_CTL,0,255,FALSE);
SetScrollPos(GetDlgItem(hWnd, ID_SBR+n),SB_CTL,0,FALSE);
S
S break; case WM_CTLCOLOR: if(HIWORD(lParam) == CTLCOLOR_SCROLLBAR)A n=GetWindowWord(LOWORD(lParam),GWW_ID)-ID_SBR; p.x=p.y=0;
UnrealizeObject(hBrushani);
SetBrushOrg(wParam,p.x,p.y); return(DWORD)hBrushani;
S break; case WM_VSCROLL: n=GetWindowWord(HIWORD(lParam),GWW_ID)-ID_SBR; switch(wParam)A case SB_PAGEDOWN: colorani += 15; case SB_LINEDOWN: colorani = min(255,colorani+1); break; case SB_PAGEUP: colorani -= 15; case SB_LINEUP: colorani = max(0,colorani-1); break; case SB_TOP: colorani = 0; break; case SB_BOTTOM: colorani = 255; break; case SB_THUMBPOSITION: case SB_THUMBTRACK: colorani = LOWORD(lParam); break; default: break;
S
SetScrollPos(HIWORD(lParam), SB_CTL,colorani,TRUE);
SetDlgItemInt(hWnd,ID_RVAL+n,colorani, FALSE);
DeleteObject(GetClassWord(hWnd,GCW_HBRBACKGROUND));
SetClassWord(hWnd,GCW_HBRBACKGROUND,CreateSolidBrush(RGB(colora0i, colora1i, colora2i)));
InvalidateRect(hWnd,NULL,TRUE); return 0; case WM_DESTROY:
DeleteObject(GetClassWord(hWnd,GCW_HBRBACKGROUND)); for(n=0;n < 3;DeleteObject(hBrushan++i));
PostQuitMessage(0); return 0;
S return DefWindowProc(hWnd,message,wParam,lParam);
S
---------------------------------------------------------- #include "w4.h"
Culori DIALOG 35, 24, 73, 99
STYLE WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN |
WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX |
WS_MAXIMIZEBOX
CLASS "Culori"
CAPTION "Culori"
FONT 8, "Times New Roman"
BEGIN
SCROLLBAR ID_SBR, 10, 6, 11, 78, SBS_VERT | WS_CHILD | WS_VISIBLE
SCROLLBAR ID_SBG, 31, 6, 11, 78, SBS_VERT | WS_CHILD | WS_VISIBLE
SCROLLBAR ID_SBB, 52, 6, 11, 78, SBS_VERT | WS_CHILD | WS_VISIBLE
CTEXT "0", ID_RVAL, 8, 86, 16, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
CTEXT "0", 202, 29, 86, 16, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
CTEXT "0", 203, 50, 86, 16, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
END

-----------------------------------------------------------

#define ID_RVAL 201
#define ID_SBR 101
#define ID_SBG 102
#define ID_SBB 103

---------------------------------------------------------- NAME Culori
DESCRIPTION "Exemplu SCROLLBAR"
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA SINGLE MOVEABLE
HEAPSIZE 5000
STACKSIZE 10000

EXPORTS WndProcCulori
----------------------------------------------------------


Colt dreapta
Creeaza cont
Comentarii:

Nu ai gasit ce cautai? Crezi ca ceva ne lipseste? Lasa-ti comentariul si incercam sa te ajutam.
Esti satisfacut de calitarea acestui document, eseu, cometariu? Apreciem aprecierile voastre.

Nume (obligatoriu):

Email (obligatoriu, nu va fi publicat):

Site URL (optional):


Comentariile tale: (NO HTML)


Noteaza documentul:
In prezent fisierul este notat cu: ? (media unui numar de ? de note primite).

2345678910

 
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite
Colt dreapta