Documente Academic
Documente Profesional
Documente Cultură
55
H. Vlean, 2004
56
LRESULT
57
butoanele de
minimazare,
maximizare,
nchidere
fereastra cadru
bara meniu
bara de titlu
zona client
bara de defilare
bara de stare
H. Vlean, 2004
58
order) a ferestrelor, de aa manier nct fereastra activat devine ultima fereastr din
ordinea Z (fereastra din fa).
F1
click stnga
F2
F1
F3
F2
F3
Windows transform
aciunea n mesaj
Fereastra
programului
primete
mesajul
Programul execut
o bucl care preia
i distribuie
mesajele:
while (getmsg(msg)
{
switch(msg)
59
apsat butonul stng, etc. Alte mesaje, cum este de exemplu WM_CLOSE nu trebuie s
transmit nici o informaie suplimentar.
n momentul primirii unui mesaj Windows, programul cruia i este destinat
trebuie s identifice mesajul i s execute secvena de instruciuni corespunztoare.
Deci, o funcie foarte important ntr-un program este aceea care accept i
prelucreaz mesajele transmise de sistemul de operare. Pentru ferestrele clasice,
aceast funcie este o funcie special, numit procedura fereastr:
LRESULT CALLBACK WndProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
Funcia returneaz o valoare de tip ATOM. Tipul ATOM, cu tot numele lui ciudat, nu
este altceva dect un WORD care reprezint o referin la un ir de caractere, indiferent
dac irul conine majuscule sau minuscule. Astfel, spre exemplu, irul visual c va
fi echivalent cu irul VISUAL C. Funcia primete de asemenea ca i parametru un
pointer la o structur de tip WNDCLASS. Aceast structur definete de fapt felul n
care va arta o fereastr din clasa respectiv:
H. Vlean, 2004
60
UINT style
Tabelul 2.1
Stil
CS_BYTEALIGNWINDOW
CS_DBLCLKS
CS_HREDRAW
CS_VREDRAW
CS_NOCLOSE
Semnificaie
aliniaz fereastra pe orizontal n poziia dat de BYTE
ntiineaz fereastra cnd utilizatorul execut un dublu click cu mousele
redeseneaz ntreaga fereastr cnd utilizatorul ajusteaz dimensiunea
orizontal
redeseneaz ntreaga fereastr cnd utilizatorul ajusteaz dimensiunea
vertical
dezactiveaz comanda i butonul Close
61
HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
Int
x,
int
y,
int
nWidth,
int
nHeight,
HWND
hWndParent,
HMENU
hMenu,
HANDLE hInstance,
LPVOID lpParam
);
WS_VISIBLE
WS_VSCROLL
Semnificaie
creeaz o fereastr cu o linie subire ca margine
creeaz o fereastr care are o bar de titlu
creeaz o fereastr iniial dezactivat. O astfel de fereastr nu reacioneaz la
nici un stimul de intrare din partea utilizatorului
creeaz o fereastr cu bar de defilare orizontal
creeaz o fereastr iniial maximizat
creeaz o fereastr care are butonul de maximizare
creeaz o fereastr iniial minimizat
creeaz o fereastr care are butonul de minimizare
creeaz o fereastr cu bar de titlu i bordur
creeaz o fereastr cu stilurile implicite WS_OVERLAPPED,
WS_CAPTION,WS_SYSMENU,WS_THICKFRAME,WS_MINIMIZEBOX
i WS_MAXIMIZEBOX
creeaz o fereastr iniial vizibil
creeaz o fereastr cu bar de defilare vertical
H. Vlean, 2004
62
Tabelul 2.3
Valoare
SW_HIDE
SW_MAXIMIZE
SW_MINIMIZE
SW_RESTORE
SW_SHOW
Semnificaie
ascunde fereastra i activeaz o alta, dac exist
maximizeaz fereastra specificat
minimizeaz fereastra specificat
activeaz i afieaz fereastra n starea n care a fost creat
face fereastra vizibil
63
COADA DE MESAJE
S
A
L
Windows preia
evenimentele de
la tastatur i le
depune n coada
de mesaje
Bucla de
mesaje
U
T
WM_ CHAR
Procedura fereastr
L
U
T
Pentru preluarea mesajelor din coada de mesaje, orice program Windows va trebui
s conin o bucl de mesaje care s preia i s proceseze mesajele. Aceast bucl de
mesaje este un ciclu while, compus din 3 funcii, cu implementarea de mai jos:
MSG msg;
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Prima funcie utilizat, care stabilete condiia de ieire din bucla de mesaje este
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin,
UINT wMsgFilterMax);
H. Vlean, 2004
64
typedef struct
HWND
UINT
WPARAM
LPARAM
DWORD
POINT
} MSG;
tagMSG {
hwnd;
message;
wParam;
lParam;
time;
pt;
TranslateMessage().
Ea
cu parametrul
Funcia returneaz TRUE ori de cte ori este apsat o astfel de tast i genereaz
mesajul WM_CHAR. Dac mesajul transmis de sistemul de operare nu se refer la o
tast virtual, funcia TranslateMessage() va ignora mesajul. Cteva din codurile
tastelor virtuale (n afar de tastele caracter obinuite) sunt prezentate n tabelul 2.4:
Tabelul 2.4
Definiie
VK_BACK
VK_TAB
VK_LEFT
VK_RIGHT
VK_UP
VK_DOWN
VK_RETURN
VK_ESCAPE
VK_CONTROL
Tasta asociat
Backspace
Tab
Sgeat stnga
Sgeat dreapta
Sgeat n sus
Sgeat n jos
Enter
Esc
Ctrl
65
H. Vlean, 2004
66
wndCls.lpszClassName = "MainWndClass";
if (!RegisterClass(&wndCls))
return FALSE;
hwndMain = CreateWindow("MainWndClass", "PrimaFereastra",
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,
(HWND) NULL, (HMENU) NULL, hInstance, (LPVOID) NULL);
if (!hwndMain)
return FALSE;
ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);
switch(uMsg){
case WM_CLOSE:
PostMessage(hwnd, WM_QUIT, 0L, 0L);
return DefWindowProc(hwnd, uMsg, wParam, lParam);
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
67
unde:
hwnd
H. Vlean, 2004
68
69
H. Vlean, 2004
70
IDM_START, IDM_ARATA
IDM_START
IDM_ARATA
IDM_ASCUNDE
IDM_IESE
110
120
121
130
cu semnificaiile parametrilor:
HINSTANCE hInstance identificatorul instanei programului n care se ncarc
meniul;
LPCTSTR lpMenuName numele (din fiierul .rc) al meniului;
Meniul ncrcat este declarat ca i meniu implicit al ferestrei programului,
utiliznd funcia:
BOOL SetMenu(HWND hWnd, HMENU hMenu);
unde
HWND hWnd identificatorul ferestrei n care se ncarc meniul;
HMENU hMenu identificatorul meniului (generat de funcia LoadMenu());
Pentru ncrcarea meniului, vom completa fiierul PrimaFereastra.cpp ca mai jos:
if (!hwndMain)
return FALSE;
else
{
HMENU hnewMenu=LoadMenu(hInstance,"MENIUFEREASTRA");
SetMenu(hwndMain,hnewMenu);
}
71
Astfel meniul este ncrcat numai dac crearea ferestrei este reuit. n acest caz,
obinem interfaa din fig. 2.6.
unde
HWND hWnd
Pentru programul nostru, vom alege aceast din urm variant. S ne reamintim c
identificatorul elementului de meniu selectat este testat de secvena loword(wParam).
Va trebui s modificm procedura fereastr ca mai jos:
LRESULT CALLBACK WndProc( HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg){
case WM_CLOSE:
PostMessage(hwnd, WM_QUIT, 0L, 0L);
return DefWindowProc(hwnd, uMsg, wParam, lParam);
case WM_KEYDOWN:
LPCTSTR text;
...
H. Vlean, 2004
72
...
hwndMain = CreateWindow("MainWndClass", "PrimaFereastra",
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,
(HMENU) NULL, hInstance, (LPVOID) NULL);
hInst=hInstance;
if (!hwndMain)
...
73
switch(uMsg){
case WM_CLOSE:
...
case WM_COMMAND :
switch( LOWORD( wParam ) )
{
case IDM_ARATA:
hText = CreateWindow( "STATIC", "Eticheta Statica", WS_CHILD |
WS_VISIBLE | SS_LEFT,20, 20, 100, 15, hwnd,NULL, hInst, NULL );
hEdit = CreateWindow( "EDIT", "",WS_CHILD | WS_VISIBLE |
ES_LEFT | WS_BORDER,20, 40, 100, 20, hwnd,NULL,hInst, NULL );
hBtn = CreateWindow( "BUTTON", "Buton de Comanda", WS_CHILD |
WS_VISIBLE | BS_PUSHBUTTON, 20, 80, 150, 30, hwnd, NULL,
hInst, NULL );
hListb = CreateWindow( "LISTBOX", "", WS_CHILD | WS_VISIBLE |
WS_DLGFRAME , 20, 120, 150, 50, hwnd,NULL, hInst, NULL );
hCombo = CreateWindow( "COMBOBOX", "", WS_CHILD |
WS_VISIBLE , 20, 180, 150, 30, hwnd,NULL, hInst, NULL );
break;
case IDM_ASCUNDE:
DestroyWindow(hText);
DestroyWindow(hEdit);
DestroyWindow(hBtn);
DestroyWindow(hListb);
DestroyWindow(hCombo);
break;
case IDM_IESE:
DestroyWindow(hwnd);
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
74
descriere controln
END
75
BEGIN
MENUITEM "&Start", IDM_START
MENUITEM "&Arata", IDM_ARATA
MENUITEM "Asc&unde", IDM_ASCUNDE
END
POPUP "&Gata"
BEGIN
MENUITEM "&Iesire", IDM_IESE
END
END
CASETAMODALA DIALOG DISCARDABLE 22, 17, 200, 140
STYLE DS_MODALFRAME |WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
CAPTION "Caseta Modala/Nemodala"
FONT 10, "Times New Roman""
BEGIN
CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD
| WS_VISIBLE | WS_GROUP | WS_TABSTOP, 140, 10, 50, 14
CONTROL "Cancel", IDCANCEL, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD
| WS_VISIBLE | WS_GROUP | WS_TABSTOP, 140, 30, 50, 14
GROUPBOX "Butoane Radio", IDC_GRUPB, 10,10, 100, 50
RADIOBUTTON "Adevarat", IDC_RADIO1, 30, 25, 110,10, WS_GROUP
| WS_TABSTOP
RADIOBUTTON "Fals", IDC_RADIO2, 30, 40, 110,10, WS_TABSTOP
CONTROL "Introduceti textul", -1, "STATIC", SS_LEFT | WS_CHILD
| WS_VISIBLE | WS_GROUP, 15, 100, 80, 10
EDITTEXT IDC_EDIT1, 90, 95,100,20
END
130
201
202
203
204
H. Vlean, 2004
76
HINSTANCE hInstance
LPCTSTR lpTemplate
caseta;
WM_COMMAND
77
H. Vlean, 2004
78
unde
HWND hDlg
dialog;
int nResult
cu
WS_VISIBLE
Acest nou stil adugat nu influeneaz cu nimic afiarea modal a casetei. Acum,
va trebui s crem o nou intrare n meniu, care s permit lansarea nemodal. Fie
Deschide Nemodal aceast intrare. Pentru aceasta, va trebui s modificm fiierul de
resurse,
...
MENIU MENU DISCARDABLE
BEGIN
POPUP "&Caseta"
BEGIN
...
79
Cum funcioneaz? Dac pDlgNemod e NULL, adic nu este ncrcat cu adresa nici
unei casete nemodale, se apeleaz macrocomanda CreateDialog(). Dac aceasta se
execut cu succes, va actualiza identificatorul pDlgNemod cu adresa casetei nemodale.
Astfel, va exista la un moment dat o singur caset nemodal lansat, crearea i
afiarea unei noi casete nemodale fiind mpiedicat de condiia if(). Macrocomanda
CreateDialog() primete ca ultim argument un pointer spre o procedur dialog care
trateaz mesajele generate de Windows spre caset. Aceast procedur dialog am
numit-o Nemodal() i va trebui declarat i definit.
H. Vlean, 2004
80
140
141
81
case IDM_DNEMOD:
...
break;
case IDM_INEMOD:
if (pDlgNemod)
{
DestroyWindow(pDlgNemod);
pDlgNemod=NULL;
}
break;
...
Observm c modul de distrugere a casetei de dialog este similar cu cel din funcia
De aceast dat ns, funcia DestroyWindow() primete ca parametru
identificatorul pDlgNemodal. E corect, acesta identific caseta nemodal.
Nemodal().
Ca o observaie, vom putea lansa simultan caseta, att modal ct i nemodal. (fig.
2.7):
caseta nemodal
caseta modal
H. Vlean, 2004
82