Sunteți pe pagina 1din 12

Curs 1 Windows API (Application Programming Interface) Microsoft Foundation Class (MFC)

Windows API (Win32 API)este un set de funcii oferite de sistemul de operare Windows pentru manipularea resurselor calculatorului.Aceste funcii pot fi utlizate de ctre programatori pentru dezvoltarea aplicaiilor utilizator. Funciile din interfaa Win32 API sunt implementate n urmtoarele trei biblioteci: user32.dll, kernel32.dll i gdi.dll.Ele pot fi folosite n orice program dac fisierul header Windows.h este inclus n program i linkeditarea programului se face cu fiierul de exporturi corespunzator) user32.lib, kernel32.lib sau/i gdi32.lib. Aceste trei biblioteci sunt trecute n mod automat n lista de module a linkeditorului, n orice proiect generat de mediul Visual C++. Funciile din interfaa Win32 API sunt mprite n mai multe categorii. Dintre acestea cele mai importante sunt User Interface Services i Windows Base Services. Tipuri de date noi folosite de funciile Win32 API. Tipul HANDLE tip generic, utilizat pentru manipularea obiectelor folosite n program (fiiere, ferestre, alte resurse). Pentru a manipula un astfel de obiect, este necesar obinerea unui astfel de HANDLE, n urma apelrii unei funcii care returneaz un astfel de obiect. Exemplu: Se creaza un fiier n care se scrie Hello world HANDLE hFile=CreateFile(numeFisier, GENERIC_READ,0, NULL, CREATE_ALWAYS, FILE_ATRIBUTE_NORMAL,NULL); char buf[]=Hello world; DWORD nr_octeti_scrisi; WriteFile(hFile,(LPVOID)buf,9,&nr_octeti_scrisi,NULL); CloseHandle(hFile) Tipul DWORD un cuvnt de lungime 32 bii Tipul LPVOID definit ca: typedef void * LPVOID Tipul LPSTR este definit ca typedef char * LPSTR Tipul HWND este definit ca typedef HANDLE HWND este folosit n manipularea ferestrelor. Tipurile WPARAM i LPARAM cuvinte cu lungimea de 32 de bii. Procese i fire de execuie n sistemul de operare Windows Un proces (task) este imaginea unui program executabil n memoria calculatorului. Sistemul de operare Windows este un sistem de operare multitasking pentru c poate rula mai multe procese simultan. De exemplu, poate rula simultan un mediu de dezvoltare si un editor de texte. Dac n memoria calculatorului exist mai multe procese care provin din acelai fiier executabil, ele sunt numite instane ale acelui program. Windows

permite rularea mai multor instane ale unui program. Toate instanele unui program au aceeai zon de cod dar fiecare instan are propria ei zon de date i stiv. De aceea fiecare instan poate rula independent de celelalte instane aflate n memoria calculatorului. Windows furnizeaz mecanisme pentru comunicaia ntre procese. Acestea sunt descrise n WindowsBase Services->InterprocessComunication. n cazul n care un program trebuie s execute mai multe sarcini simultan se creaz fire de execuie separate care execut fiecare din aceste sarcini (task-uri). Acestea se numesc fire de execuie. De axemplu, un program de calcul tabelar trebuie s gestioneze interfaa grafic i n acelai timp s execute un calcul care dureaz un interval de timp ndelungat. De aceea se creaz cel puin dou fire de execuie (thread) care se execut n paralel. Spre deosebire de procese firele de execuie mpart aceeai zon de memorie i de aceea pot comunica uor (de ex. prin intermediul variabilelor globale). Att firele de execuie ale unui proces ct i procesele din sistem , se pot manipula prin intermediul unui HANDLE. De ex., programul de mai jos creaz o nou instan a sa folosind funcia CreateProcess i o manipuleaz folosind funcia TerminateProcess. Exemplu: #include <Windows.h> #include <conio.h> #include <stdio.h> void main() { STARTUPINFO si; // informatii despre starea initiala a procesului PROCESS_INFORMATION pi; memset(&si,0,sizeof(si)); si.cb=sizeof(STARTUPINFO); if(CreateProcess(C:\\Winnt\\Regedit.exe,NULL,NULL,NULL,FALSE,0L,NULL,NUL L,&si,&pi)) { DWORD err=GetLastError(); } printf(Proces creat.Apasati o tasta pentru oprire!\n); getch(); TerminateProcess(pi.hProcess,0L); Ferestre n sistemul de operare Windows O fereastr este elementul fundamental pe baza cruia se construiete orice interfa utilizator. Interfaa sisteelor de operare Windows este bazat pe ferestre. Majoritatea aplicaiilor Windows posed o fereastr principal, n care ruleaz. O fereastr aloc unei aplicaii un spaiu n form dreptunghiular pe ecran. Elementele principale ale unei ferestre sunt: - bara de titlu afieaz titlul aplicaiei i eventual denumirea documentului deschis pentru prelucrare; este o zon activ care permite mutarea ferestrei pe ecran; - butoanele de minimizare, maximizare i nchidere apar de obicei n bara de titlu; - meniul sistem coninut tot de bara de titlu (n partea stng a acesteia); - marginea ferestrei este o zon activ, care permite redimensionarea ferestrei;

zona client a ferestrei este zona pus la dispoziie pentru aplicaia respectiv.

Ferestrele au dou dimensiuni: X pe orizontal i Y pe vertical. Mulimea ferestrelor afiate pe ecran la un moment dat trebuie privit ca fiind n spaiu. Toate ferestrele au o a treia dimensiune comun, Z, i sunt caracterizate de o anumit ordine n care sunt afiate pe axa Z. n cazul unui click stnga (cu mouse-ul) n interiorul unei ferestre care nu era activ i era parial ascuns, aceasta este activat (i se deseneaz bara de titlu cu o alt culoare) i seschimb ordinea Z a ferestrelor, de aa manier nct fereastra activat devine ultima fereastr din ordinea Z (fereastra din fa). La un moment dat, o singur fereastr poate fi activ. Aceasta este ultima n ordinea Z i primete input focus-ul, adic poate recepiona evenimentele de la tastatur. Exist dou tipuri de ferestre: top-level i child. Ferestrele top-level sunt ferestrele principale in care ruleaz o aplicaie. Ferestrele child sunt butoanele i alte elemente de control dintr-o caset de dialog. O fereastr este unic identificat n sistem printr-un handle (o variabil de tip HWND) care se obine n urma apelrii funciei API CreateWindow. Fiecare fereastr are asociat o structur de tip coad numit coad de mesaje. n aceast structur sistemul de operare pune mesajele care sunt de interes pentru fereastra respectiv. De aceea, programele Windows se mai numesc i orientate pe mesaje. Pentru prelucrarea mesajelor se creaz o structur de tip bucl de mesaje. Aceasta presupune apelarea continu a funciilor API GetMessage (care extrage un mesaj din coada de mesaje) i DispatchMessage. Funcia API DispatchMessage apeleaz o funcie special numit procedura fereastr, cu urmtoarea semntur: LRESULT CALLBACK Wndproc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) unde: hwnd este handle de fereastr apelant, uMsg este identificator de mesaj, wParam este primul parametru al mesajului i lParam este al doilea parametru al mesajului. Aceast funcie este declarat i definit n cadrul fiecrui program Windows. Mai multe ferestre care au aceleai caracteristici (dimensiune, stare iniial, dac se pot redimensiona sau nu) formeaz o clas de ferestre. Clasa de ferestre se specific la fiecare apel al funciei CreateWindow. Pentru a putea folosi o clas deferestre este necesar nregistrarea ei, cu funcia API RegisterClass. La nregistrarea unei clase de ferestre, se specific, printre alte caracteristici i procedura fereastr care se va folosi de ctre ferestrele din clasa respectiv. Procedura fereastr primete fiecare mesaj extras de ctre funcia GetMessage i transmis cu funcia DispatchMessage i l proceseaz. Pentru mesajele a cror tratare nu necesit aciuni speciale, se apelez funcia API DefWindowProc (cu aceeai semntur ca orice procedur fereastr obinuit). Dup tratarea mesajului se revine n bucla de mesaje. Mesajele sistemului de operare Windows sunt definite ca i constante simbolice de tip WM_*(de ex. WM_CHAR, WM_PAINT, etc.). Ele pot transmite, pe lng tipul mesajului i alte informaii utile, prin cei doi parametri de tip WPARAM, respectiv LPARAM, care se transmit procedurii fereastr. De ex., mesajul WM_LBUTTONDOWN, generat la apsarea butonului stng al mouse-ului transmite

coordonatele (n pixeli, relativ colul stnga sus al zonei client) punctului n care s-a apsat butonul stng al mouse-ului. Aa cum un program C/C++ necesit declararea unei funcii main, programele Windows necesit declararea unei funcii WinMain cu urmtoarea semntur: int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) unde hInstance este handle de instan curent a programului, lpCmdLine este un pointer la linia de comand, nCmdShow arat cum s fie prezentat iniial fereastra principal a aplicaiei. Exemplu de nregistrare a unei clase de ferestre i de utilizare a ei pentru crearea unei ferestre simple. #include <Windows.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CLOSE: MessageBox(hwnd, Aplicatie terminata !,Mesaj, MB_OK | MB_ICONEXCLAMATION); PostMessage(hwnd, WM_Quit, 0L, 0L); return DefWindowProc(hwnd,uMsg,wParam,lParam); default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hwndMain; MSG msg; WNDCLASS wndCls; UNREFERENCED_PARAMETER(lpCmdLine); wndCls.style=0; wndCls.lpfnWndProc=(WNDPROC) WndProc; wndCls.cbClsExtra=0; wndCls.cbWndExtra=0; wndCls.hInstance=hInstance; wndCls.hIcon=LoadIcon((HINSTANCE) NULL, IDI_APPLICATION); wndCls.hCursor=LoadCursor((HINSTANCE) NULL,IDC_ARROW); wndCls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndCls.lpszMenuName=NULL; wndCls.lpszClassName=MainWndClass);

if(!RegisterClass(&wndCls)) return FALSE; hwndMain=CreateWindow(MainWndClass,Exemplu,WS_OVERLAPPEDWINDO W, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL, hInstance,(LPVOID) NULL); if (!hwndMain) return FALSE; ShowWindow(hwndMain,nCmdShow); UpdateWindow(hwndMain); while (GetMessage(&msg,(HWND) NULL,0,0)) { TranslateMessage(&msg); DispatchMesasge(&msg); } return msg.wParam; } Dac dorim s tratm un alt eveniment funcia Wndproc trebuie modificat astfel nct mesajul asociat s fie interceptat. De ex., pentru a genera mesajul Ai apsat o tast la fiecare apsare a unei taste trebuie tratat mesajul WM_KEYDOWN, astfel: LRESULT CALLBACK WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CLOSE: MessageBox(hwnd,Aplicatie terminata, Mesaj terminare, MB_OK | MB_ICONEXCLAMATION); PostMessage(hwnd,WM_QUIT,0L,0L); return DefWindowProc(hwnd,uMsg,wParam,lParam); case WM_KEYDOWN: MessageBox (hwnd, Ati apasat o tasta, Mesaj tasta, MB_OK | MB_ICONSTOP); return DefWindowProc(hwnd,uMsg,wParam,lParam); default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } Pentru implementarea programului anterior s-a deschis un proiect de tip Win32 Application. Microsoft Foundation Class (MFC) Microsoft Foundation Class este o bibliotec de clase, dezvoltat de firma Microsoft pentru a simplifica programarea aplicaiilor Windows API.

Multe dintre clasele MFC ncapsuleaz funciile Windows API. Astfel, programatorul are posibilitatea de a se concentra numai asupra aspectelor particulare ale aplicaiei, lsnd aspectele standard (clase de ferestre, proceduri fereastr) n seama claselor MFC. Clasele coninute de biblioteca MFC se clasific astfel: clase de uz general clase pentru manipularea fiierelor (CFile) i irurilor de caractere (CString), clase excepii (CException), clase pentru reprezentarea unor zone de pe ecran (CRect, CPoint); clase de obiecte vizuale aceste clase manevreaz aproape tot ce este vizibil ntr-un program Windows. n aceast categorie intr clasele de ferestre (CWnd i clasele derivate din ea), meniuri (CMenu), controale (CButton, CEdit, CListBox, etc. derivate din clasa CWnd) i obiecte de desenare, cum ar fi creioanele (CPen) i pensulele (CBrush); clase de aplicaie clasele care gestioneaz obiectele fir de execuie (CWinThread), aplicaie (CWinApp derivat din CWinThread), precum i clasele care implementeaz arhitectura Document-View (CDocument, CView i clasele derivate din acestea ) clase de tip colecie aceste clase se folosesc la stocarea altor obiecte de tip structuri de date de tip tablou (CArray), list (CList), sau hart (CMap). clase suport OLE2 pentru scrierea aplicaiilor care necesit faciliti OLE2; clase pentru baze de date pentru manipularea bazelor de date (Cdatabase, CRecordset, CdaoDatabase, CdaoRecordset); clase pentru dezvoltarea aplicaiilor distribuite (n reea) CSocket (pentru deschiderea unui canal de comunicaie ntre dou calculatoare) CFTPConnection i CHTTPConnection (pentru deschiderea unei sesiuni de lucru FTP, respectiv HTTP). n cadrul bibliotecii MFC se folosete motenirea multipl. Majoritatea claselor MFC sunt derivate din clasa CObject. Toate clasele care reprezint ferestre sau controale sunt derivate din clasa CWnd. Clasele CObject i CWnd utilizeaz funciile virtuale. Aceasta permite obiectelor din program s acceseze funcii de uz general, prin intermediul unui pointer de baz. Un program care utilizeaz MFC se scrie mai uor dect dac se folosesc funciile Windows API i presupune urmtoarele etape: - se creaz un proiect Win32 Application - din meniul Project->Settings se selecteaz Settings for: all configurations, iar de la tab-ul General se selecteaz Using MFC in a shared library. - se introduce codul programului, se compileaz i se linkediteaz. Exemplu: #include <afxwin.h> class CFirstApp: public CWinApp { public: BOOL InitInstance(); }; class CFirstWnd: public CFrameWnd {

public: CFirstWnd(); }; BOOL CFirstApp::InitInstance() { m_pMainWnd=new CFirstWnd; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CFirstWnd::CFirstWnd() { Create(NULL,First MFC Application); } CFirstApp theApp; Este necesar includerea n fiierul surs a fiierului header afxwin.h care conine declaraiile claselor MFC. Orice program MFC are o clas derivat public din clasa CWinApp. De obicei, aceast clas redefinete metoda InitInstance a clasei CWinApp. Metoda InitInstance, dup cum sugereaz i numele su, este apelat automat de cadrul aplicaie la pornirea unei instane a aplicaiei. Ea este declarat virtual n cadrul clasei CWinApp, aa nct se va apela varianta corect (cea redefinit n noua clasa aplicaie). Este neaprat necesar redefinirea funciei InitInstance cu semnatura: BOOL InitInstance() pentru a nu se pierde caracterul de funcie virtual. De obicei, funcia InitInstance are rolul de a crea fereastra principal a aplicaiei i de o a afia pe ecran. Pentru aceasta, n funcia InitInstance se folosete variabila m_pMainWnd, membr a clasei CWinApp i motenit de clasa aplicaie (CFirstApp n cazul de mai sus). Aceast variabil este de tip CWnd*. Ea este iniializat folosind o linie de program de forma: m_pMainWnd = new CFirstWnd; unde n operatorul new se apeleaz constructorul unei clase derivat, direct sau indirect, n mod public din clasa CWnd. Aceasta permite conversia explicit de la un obiect de tip CFirstWnd* (returnat de operatorul new, n exemplu) la un obiect de tip CWnd* (m_pMainWnd). Dup crearea obiectului de tip fereastr, acesta este afiat pe ecran folosind funciile ShowWindow i UpdateWindow, membre ale clasei CWnd. Funcia ShowWindow primete ca parametru un ntreg care specific modul de afiare iniial a ferestrei aplicaiei (normal, minimizat, maximizat). Dup succesiunea normal a operaiilor sus-menionate, funcia InitInstance returneaz TRUE, semnaliznd faptul c aplicaia poate continua normal. Folosirea unei clase derivate (direct sau indirect) din clasa CWnd nu este obligatorie. Se pot folosi una dintre clasele fereastr furnizate de MFC: CWnd, CFrameWnd, sau alt clas fereastr. Totui, exemplul de mai sus definete o nou clas fereastr, bazat pe clasa CFrameWnd. Motivul este prezentat n paragraful urmtor. Clasa CFrameWnd este

derivat direct din clasa CWnd, i reprezint o fereastr cadru a unei aplicaii. Constructorul clasei CFirstWnd apeleaza funcia Create (membr a clasei CFrameWnd). Primul parametru se refer la clasa de ferestre pe care dorim s o folosim pentru fereastra cadru a aplicaiei. El este NULL, i se va folosi o clas de ferestre nregistrat de MFC. Cel de-al doilea parametru este titlul ferestrei principale a aplicaiei. Ceilali parametri ai funciei CFrameWnd::Create iau valori implicite. Orice program MFC posed un obiect (i numai unul) derivat din clasa aplicaie (CfirstApp::theApp, n cazul exemplului de mai sus). Declararea unui asemenea obiect (sub forma unei variabile globale) duce la declanarea mecanismului MFC de desfurare a unei aplicaii (apelul funciei InitInstance, urmat de alte apeluri de metode, ascunse programatorului). Putem considera acest obiect aplicaie ca fiind echivalent funciei main dintr-un program consol, sau funciei WinMain dintr-un program Windows scris folosind Windows API. Manipularea mesajelor in MFC Se poate observa c aceast aplicaie nu trateaz nici un mesaj adresat ei, i las tratarea mesajelor n seama procedurilor implicite. Mesajele Windows pot fi tratate dup cum ilustreaz programul de mai jos: #include <afxwin.h> class CFirstApp: public CWinApp { public: BOOL InitInstance(); }; class CFirstWnd: public CFrameWnd { public: CFirstWnd(); protected: afx_msg void OnClose(); DECLARE_MESSAGE_MAP() }; BOOL CFirstApp::InitInstance() { m_pMainWnd = new CFirstWnd; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } BEGIN_MESSAGE_MAP(CFirstWnd, CFrameWnd)

ON_WM_CLOSE() END_MESSAGE_MAP() CFirstWnd::CFirstWnd() { Create(NULL, "First MFC Application"); } void CFirstWnd::OnClose() { MessageBox("Message text: application over!", "Message title", MB_OK|MB_ICONEXCLAMATION); CFrameWnd::OnClose(); } CFirstApp theApp; Pentru a putea trata mesajele adresate unei ferestre, este necesar definirea unei hri de mesaje. O hart de mesaje este utilizat pentru a stabili legturi ntre mesajele transmise unei ferestre i funciile destinate procesrii acestor mesaje. Declararea unei hri de mesaje se face n interiorul unei clase derivate din clasa CWnd, folosind macroul DECLARE_MESSAGE_MAP, astfel: DECLARE_MESSAGE_MAP(). Clasa fereastr, derivat din clasa CWnd va trata mesajele Windows ntr-un mod specific aplicaiei. Declararea hrii de mesaje i a funciilor de tratare a mesajelor se face n cadrul unei seciuni protejate a clasei fereastr. Funciile de tratare a mesajelor au semnturi predefinite. Declararea lor ncepe cu cuvntul afx_msg, care semnalizeaz compilatorului faptul c este vorba despre o funcie de tratare a mesajelor. Ce urmeaz dup acest cuvnt cheie este specific fiecrui mesaj tratat. Funcia de tratare a mesajului WM_CLOSE are semnatura afx_msg void OnClose() i este de fapt o funcie membr a clasei CWnd. Aceast funcie este redefinit de clasa CFirstWnd. Funcia OnClose redefinit apeleaz versiunea sa de baz (prin intruciunea CFrameWnd::OnClose), dar nainte de aceasta, apeleaz funcia MessageBox. Funcia MessageBox apelat nu este funcia MessageBox din Windows API. Este vorba despre funcia CWnd::MessageBox. Se observ c cele dou funcii au semnturi diferite: int MessageBox(HWND, LPCSTR, LPCSTR, UINT); //Win API int MessageBox(LPCSTR, LPCSTR, UINT); //membru CWnd Funcia Windows API MessageBox, poate fi apelat n programul de mai sus sub forma: ::MessageBox(this->m_hWnd, ..., ..., MB_OK); Funcia API MessageBox solicit ca prim parametru o variabila de tip HWND. Forma this->m_hWnd se refer la un membru de tip HWND, numit m_hWnd, motenit de clasa CFirstWnd din clasa CWnd.

De reinut faptul c orice funcie Windows API care este redefinit ntr-o clas MFC se poate apela (n interiorul acelei clase, sau al unei clase derivate din ea) folosind construcia ::Nume_Functie_API(lista_parametri_actuali); Definirea hrii de mesaje se face n exteriorul clasei. Se folosesc macrourile BEGIN_MESSAGE_MAP i END_MESSAGE_MAP, care marcheaz nceputul, respectiv sfritul hrii de mesaje. Macroul BEGIN_MESSAGE_MAP primete doi parametri: numele clasei derivate i numele clasei de baz. Macroul END_MESSAGE_MAP nu primete nici un parametru. Aceste dou macrouri apar la nceputul, respectiv sfritul oricrei hri de mesaje. La recepionarea unui mesaj, se ncearc tratarea lui printr-o funcie definit n clasa derivat. Dac clasa derivat nu furnizeaz o funcie de tratare a mesajului, tratarea mesajului este lsat n seama clasei de baz. Acest mecanism se repet n cazul clasei de baz (dac aceasta este la rndul ei derivat dintr-o alt clas). Harta de mesaje conine, ntre macrourile de nceput i sfrit, intrri care specific ce mesaje sunt tratate de clasa respectiv. Intrrile n harta de mesaje sunt de fapt macrouri. Fiecare mesaj general Windows are asociat n MFC un astfel de macrou. Regula de numire a macroului asociat este urmtoarea: se adaug la numele mesajului (scris cu litere mari) prefixul ON_. Rezult astfel macrouri de forma: ON_WM_CLOSE() ON_WM_PAINT() ON_WM_LBUTTONDOWN() Pentru fiecare dintre aceste macrouri (folosite n harta de mesaje), clasa fereastr trebuie s declare i s defineasc o funcie de tratare a mesajului respectiv (cu o semntur predefinit). Pentru mesajele WM_CLOSE, WM_PAINT i WM_LBUTONDOWN, aceste funcii au semnaturile: afx_msg void OnClose(); afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); Toate aceste funcii sunt funcii membre ale clasei CWnd. Datorit faptului c ele sunt redefinite i incluse n harta de mesaje a clasei CFirstWnd, se apeleaz versiunea corect a lor (fr a fi nevoie de declararea lor ca funcii virtuale). n cele ce urmeaz, vom extinde programul prezentat anterior, astfel nct s trateze mesajul WM_PAINT. Mesajul WM_PAINT este transmis unei ferestre ori de cte ori este necesar redesenarea sa (de exemplu, cnd este afiata pentru prima dat fereastra, sau cnd este mutat sau redimensionat). Iat cum se trateaz acest mesaj folosind MFC: #include <afxwin.h>

class CFirstApp: public CWinApp { public: BOOL InitInstance(); }; class CFirstWnd: public CFrameWnd { public: CFirstWnd(); protected: afx_msg void OnClose(); afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() }; BOOL CFirstApp::InitInstance() { m_pMainWnd = new CFirstWnd; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } BEGIN_MESSAGE_MAP(CFirstWnd, CFrameWnd) ON_WM_CLOSE() ON_WM_PAINT() END_MESSAGE_MAP() CFirstWnd::CFirstWnd() { Create(NULL, "First MFC Application"); } void CFirstWnd::OnClose() { MessageBox("Message text: application over!", "Message title", MB_OK|MB_ICONEXCLAMATION); CFrameWnd::OnClose(); } void CFirstWnd::OnPaint() { CPaintDC dc(this); CRect rcClient;

GetClientRect(rcClient); dc.TextOut(rcClient.Width()/2, rcClient.Height()/2, "Hello!", 6); } CFirstApp theApp; Funcia CFirstWnd::OnPaint() obine un context de dispozitiv (device context) folosit pentru desenare. n acest scop, se creeaz un obiect de tip CPaintDC (CPaintDC dc(this)). Clasa CPaintDC este derivat din clasa CDC, care conine majoritatea funciilor folosite pentru desenarea ntr-un context dispozitiv (afiare de texte, trasare de linii, figuri geometrice, etc). De asemenea, aceast funcie obine dimensiunile curente ale ferestrei, folosind un obiect de tip CRect, i funciile CRect::Width(), CRect::Height(), CWnd::GetClientRect(CRect&); n final, funcia afieaz textul Hello! centrat n fereastra aplicaiei, folosind funcia CDC::TextOut(int x, int y, LPCSTR txt, int count). Pentru a desena ntreaga zon client cu culoarea alb, se utilizeaz: dc.FillSolidRect(rcClient, RGB(255, 255, 255)); prin care se apeleaz funcia CDC::FillSolidRect(CRect, COLORREF). Cel de-al doilea parametru este o variabil de tip COLORREF (un cuvnt de 32 de bii, care specific coninutul de rou, verde i albastru). Pentru obinerea sa, se folosete macroul RGB(unsigned char red, unsigned char green, unsigned char blue).