Documente Academic
Documente Profesional
Documente Cultură
Windows
Event driving programming
Formaliti
Prelegeri 30/14 ore = 4/2 ore/spt.
Lucr. lab. 30/14 ore = 2/1 ore/spt.
Ex.intermediar sptmna 4
O atestare - sptmna 6
Examen final (toate lab. susinute!!!!!)
3/3/2015 10:50:50
PM
Literatura
Charles Petzold. Programarea n Windows 95, - Editura Teora,
Bucureti, 1996, 1062 pp.
V.Beliu. Ciclu de prelegeri la disciplina Programarea n
Windows, Varianta de calculator, UTM,
http://elearning.utm.md/moodle/
V.Beliu .a. ndrumar metodic pentru lucrri de laborator la
disciplina Programarea n Windows, UTM, 2006, 68 pp.
Doru Turturea. Programarea aplicaiilor Windows n limbajul C.
Editura Tehnic, Bucureti, 1995, 540 pp.
Peter Norton, Paul Yao. Windows 3.1 Advanced Programming
Techniques. Sybex, 1992
Florica Moldoveanu, Gabriel Hera. Programarea aplicaiilor
Windows, - Editura Teora, Bucureti, 1994
3/3/2015 10:50:50
PM
PROVOCAREA
PROGRAMATORULUI
Filozofia de proiectare a programelor - s facem
lucrurile mai uoare pentru utilizatori
Principiul NNEMBDOMG
Eroi necunoscui de la Microsoft
3/3/2015 10:50:50
PM
3/3/2015 10:50:50
PM
User Interface
Connection between the computer and the user
Two types:
Command Line
GUI: Graphical (Visual)
3/3/2015 10:50:50
PM
3/3/2015 10:50:50
PM
History of GUIs
DARPA SRI (late 60s)
3/3/2015 10:50:50
PM
windows
WinMain
implements
message loop
messages
process
windows
messages
implements
message queue
and
message
routing
provides
win32 API
application
functionality
messages
WinProc
register windows
"class"
create window
show window
update window
get message
dispatch message
implements
message
handling
for
application
windows
controls
3/3/2015 10:50:50
PM
messages
10
Ce nu ne place aici?
Hello, world!":
include <stdio.h>
main ()
{
printf ("Hello, world\n");
}
3/3/2015 10:50:50
PM
11
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT,
WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static char szAppName[] = "HelloWin;
HWND hwnd;
MSG
msg;
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof (wndclass);
wndclass.style = CS_HREDRAW|CS_VREDRAW;
3/3/2015 10:50:50
PM
12
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackgr=(HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
RegisterClassEx (&wndclass);
3/3/2015 10:50:50
PM
13
14
3/3/2015 10:50:50
PM
15
16
3/3/2015 10:50:50
PM
17
Privire general
Fiierul conine numai dou funcii:
WinMain
WndProc
Funcia WinMain reprezint punctul de intrare n program.
3/3/2015 10:50:50
PM
18
Apelurile de funcii
LoadIcon - ncarc o pictogram
3/3/2015 10:50:50
PM
19
Apelurile de funcii
DispatchMessage - trimite un mesaj
PlaySound - red un fiier de sunet
BeginPaint - iniiaz o operaie de desenare a ferestrei
GetClientRect - obine dimensiunile zonei client
DrawText - afieaz un text
3/3/2015 10:50:50
PM
20
Identificatori cu majuscule
CS_HREDRAW, DT_VCENTER, WM_CREATE, IDC_ARROW,
WM_DESTROY, CW_USEDEFAULT, IDI_APPLICATION,
SND_ASYNC, WS_OVERLAPPEDWINDOW
Prefix
CS
IDI
IDC
WS
CW
WM
SND
DT
Categorie
Opiune pentru stilul clasei
Numr de identificare pentru o pictogram
Numr de identificare pentru un cursor
Stil de fereastr
Opiune de creare a unei ferestre
Mesaj de fereastr
Opiune pentru sunete
Opiune de desenare a textului
3/3/2015 10:50:50
PM
21
3/3/2015 10:50:50
PM
22
Structuri de date
Structura
MSG
WNDCLASSEX
PAINTSTRUCT
RECT
3/3/2015 10:50:50
PM
Semnificaie
Structura mesajului
Structura clasei de fereastr
Structur pentru desenare
Dreptunghi
23
Variabile handle
Identificator
Semnificaie
HINSTANCE
HWND
HDC
3/3/2015 10:50:50
PM
24
Notaia ungar
Prefix
Tip de date
char
by
short
int
x, y
3/3/2015 10:50:50
PM
25
Notaia ungar
Prefix
Tip de date
LONG (long)
dw
fn
funcie
ir de caractere
sz
variabil handle
pointer
3/3/2015 10:50:50
PM
26
3/3/2015 10:50:50
PM
27
Rezumat
28
Afiarea textului
Mesajul WM_PAINT
3/3/2015 10:50:50
PM
30
Dreptunghiuri valide i
invalide
Procedura ferestrei este pregtit s
actualizeze zona client cnd primete mesajul
WM_PAINT
deseori este necesar numai reactualizarea unei
poriuni mai mici
Windows pstreaz n interior o structur cu
informaii pentru desenare (PAINTSTRUCT) pentru
fiecare fereastr.
la recepionarea mesajului WM_PAINT, procedura
ferestrei poate obine coordonatele dreptunghiului
invalid.
3/3/2015 10:50:50
PM
31
Interfaa GDI
Pentru desenarea zonei client - funciile din
interfaa pentru dispozitivele grafice (GDI)
DrawText
TextOut (hdc, x, y, psString, iLength);
3/3/2015 10:50:50
PM
32
Contextul de dispozitiv
O structur de date ntreinut de interfaa GDI.
hdc - calea de acces a ferestrei la funciile GDI.
Atunci cnd vrea s deseneze
3/3/2015 10:50:50
PM
33
EndPaint
PAINTSTRUCT
ps
funcia BeginPaint completeaz cmpurile structurii ps.
Valoarea returnat de funcia BeginPaint este variabila
hdc
HDC
hdc;
EndPaint elibereaz hdc
3/3/2015 10:50:50
PM
34
35
3/3/2015 10:50:50
PM
36
37
3/3/2015 10:50:50
PM
38
Funcia TextOut
TextOut (hdc, x, y, psString,
iLength);
hdc - variabila handle a DC
psString - pointer la un ir,
iLength - numrul de caractere.
x i y - nceputul irului de
caractere.
Coordonatele GDI - coordonate
logice:
moduri de mapare - controleaz
transformarea coordonatelor logice,
transmise funciilor GDI, n
coordonate fizice ale pixelilor afiai
pe ecran, definite n contextul de
3/3/2015 10:50:50
dispozitiv.
PM
39
Fonturi
Fontul de sistem
n DC este definit fontul pe care Windows l
folosete pentru scrierea textului n zona client:
prestabilit este SYSTEM_FONT
Categorii
40
Fonturi
Dimensiunile unui caracter
Sunt obinute cu GetTextMetrics
TEXTMETRIC tm;
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm)
;
ReleaseDC(hwnd, hdc);
TEXTMETRIC conine cmpuri care
descriu limea unui caracter:
tmAveCharWidth (limea medie
a literelor mici)
tmMaxCharWidth (limea celui
mai mare caracter al fontului)
Limea medie a majusculelor: 150%
din valoarea tmAveCharWidth
3/3/2015 10:50:50
PM
41
Informaii despre
metrica textului
Dimensiunile fontului sistem nu se modific n timpul unei sesiuni
Windows: GetTextMetrics n WM_CREATE
Vrem s afim mai multe linii de text una sub alta. Obinem valorile
pentru nlimea i limea caracterelor:
case WM_CREATE:
hdc = GetDC (hwnd);
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight +
tm.tmExternalLeading;
3/3/2015 10:50:50
ReleaseDC (hwnd, hdc);
PM
42
Fomatarea i extragerea
textului
int iLenght;
char szBuffer [40];
[alte Iinii de program]
iLenght = sprintf (szBuffer, "The sum of %d and %d is %d", nA, nB, nA +
nB);
TextOut (hdc, x, y, szBuffer, iLength);
Sau:
TextOut (hdc, x, y, szBuffer, sprintf (szBuffer, "The sum of %d and %d is %d", nA, nB,
nA + nB));
43
44
SYSMETS1
#include <windows.h>
#include <string.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc (HWND,
UINT,
WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE
hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
3/3/2015
10:50:50
{
PM
45
SYSMETS1
WNDCLASSEX wndclass ;
wndclass.cbSize
= sizeof (wndclass) ;
wndclass.style
= CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon
= LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor
= LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject
(WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm
= LoadIcon (NULL, IDI_APPLICATION) ;
RegisterClassEx
(&wndclass) ;
3/3/2015 10:50:50
PM
46
SYSMETS1
hwnd = CreateWindow (szAppName, "Get System Metrics No. 1",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}3/3/2015 10:50:50
PM
47
SYSMETS1
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
{
static int cxChar, cxCaps, cyChar ;
char
szBuffer[10] ;
HDC
hdc ;
int
i;
PAINTSTRUCT ps ;
TEXTMETRIC tm ;
3/3/2015 10:50:50
PM
48
SYSMETS1
switch (iMsg)
{
case WM_CREATE
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily&1?3:2)*cxChar/2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd, hdc);
return 0;
3/3/2015 10:50:50
PM
49
SYSMETS1
case WM_PAINT
hdc = BeginPaint (hwnd, &ps) ;
for (i = 0 ; i < NUMLINES ; i++)
{
TextOut(hdc, cxChar, cyChar*(1+i), sysmetrics[i].szLabel, strlen
(sysmetrics[i].szLabel));
TextOut(hdc, cxChar+22*cxCaps, cyChar*(1+i), sysmetrics[i].szDesc,
strlen(sysmetrics[i].szDesc));
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
TextOut(hdc, cxChar+22*cxCaps+40*cxChar, cyChar*(1+i), szBuffer,
wsprintf (szBuffer, "%5d, GetSystemMetrics
(sysmetrics[i].iIndex)));
SetTextAlign (hdc, TA_LEFT | TA_TOP);
}
EndPaint (hwnd, &ps);
10:50:50
50
return3/3/2015
0;
PM
SYSMETS1
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
3/3/2015 10:50:50
PM
51
Fereastra afiat de
SYSMETS1
3/3/2015 10:50:50
PM
52
3/3/2015 10:50:50
PM
53
54
Barele de derulare
Caset de derulare
Perspectiva programatorilor este diferit de cea a
utilizatorilor
Includem n fereastra aplicaiei o bar de derulare
orizontal sau vertical: WS_VSCROLL i/sau
WS_HSCROLL n stilul de fereastr din apelul
funciei CreateWindow
Windows se ocup de modul de utilizare a mouse-ului
pentru barele de derulare, dar barele de derulare ale
ferestrelor nu au o interfa automatizat cu
tastatura
3/3/2015 10:50:50
PM
55
Domeniul i poziia
Poziia 0
Poziia 1
Poziia 2
Poziia 3
Poziia 4
Poziia 0
Poziia 1
Poziia 2
Poziia 3 Poziia 4
domeniu" (pereche de
numere ntregi care
reprezint valorile
maxim i minim)
poziie" (punctul n care
se afl caseta de derulare
n domeniul asociat barei
de derulare).
56
Sistemul de operare:
Trateaz operaiile executate cu
mouse-ul asupra barei de derulare.
Afieaz n video invers zona pe care
utilizatorul execut clic.
Mut caseta de derulare atunci cnd
utilizatorul o trage cu ajutorul
mouse-ului.
Trimite mesaje din partea barei de
derulare ctre procedura de
fereastr
care o conine.
3/3/2015 10:50:50
PM
57
Programul:
Iniializarea domeniului barei de
derulare.
Prelucrarea mesajului primit de la bdd.
Actualizarea poziiei casetei.
3/3/2015 10:50:50
PM
58
Mesaje de la barele de
derulare
WM_VSCROLL,
WM_HSCROLL
Cuvntul mai puin semnificativ
al wParam - aciunea efectuat
Numere care corespund unor
identificatori SB: SB_LINEUP,
SB_PAGEUP, SB_PAGEDOWN,
SB_LINEDOWN,
SB_ENDSCROLL
SB_THUMBTRACK sau
SB_THUMBPOSITION
cuvntul mai semnificativ al
parametrului conine poziia
curent
pe bara de derulare.
3/3/2015 10:50:50
PM
59
Procedura de fereastr
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cxCaps, cyChar, cyClient, iVscrollPos ;
char
szBuffer[10] ;
HDC
hdc ;
int
i, y ;
PAINTSTRUCT ps ;
TEXTMETRIC tm ;
case WM_SIZE :
switch (iMsg)
cyClient = HIWORD (lParam) ;
{
case WM_CREATE :
return 0 ;
hdc = GetDC (hwnd) ;
GetTextMetrics (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
cyChar = tm.tmHeight + tm.tmExternalLeading ;
ReleaseDC (hwnd, hdc) ;
SetScrollRange (hwnd, SB_VERT, 0, NUMLINES, FALSE) ;
SetScrollPos
(hwnd, SB_VERT, iVscrollPos, TRUE) ;
3/3/2015
10:50:50
60
return
0
;
PM
Procedura de fereastr
case WM_VSCROLL :
case SB_THUMBPOSITION :
switch (LOWORD (wParam))
iVscrollPos = HIWORD (wParam) ;
{
break ;
case SB_LINEUP :
iVscrollPos -= 1 ;
default :
break ;
break ;
case SB_LINEDOWN :
}
iVscrollPos += 1 ;
iVscrollPos = max (0, min (iVscrollPos, NUMLINES));
break ;
if (iVscrollPos != GetScrollPos (hwnd, SB_VERT))
case SB_PAGEUP :
{
iVscrollPos -= cyClient /
SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE);
cyChar;
InvalidateRect (hwnd, NULL, TRUE);
break ;
}
case SB_PAGEDOWN :
return 0;
iVscrollPos += cyClient /
cyChar ;
break ;
3/3/2015 10:50:50
PM
61
SYSMETS 3
1. S derulm ecranul pan cnd ultima linie de text devine
vizibil. Programul va calcula un nou domeniu pentru bara de
derulare (i probabil i o nou poziie a casetei de derulare)
n timpul prelucrrii mesajului WM_SIZE. Domeniul barei de
derulare este calculat n funcie de numrul de linii de text,
de limea textului i de dimensiunea zonei client. Ca
rezultat se obine un domeniu mai mic - numai att ct este
nevoie pentru afiarea textului care iese n afara zonei
client
2. Eliminarea barei din fereastr dac nu mai este necesar
3. SYSMETS3 s prelucreze i operaiile SB_THUMBTRACK
3/3/2015 10:50:50
PM
62