Sunteți pe pagina 1din 62

Programarea n

Windows
Event driven programming
Formaliti

Prelegeri 30/14 ore = 2 ore/spt.


Lucr. lab. 30/14 ore = 2/1 ore/spt.
Ex.intermediar sptmna 5
O atestare - sptmna 8
Examen final (toate lab. susinute!!!!!)

3/20/2017 4:19:04 2
AM
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/20/2017 4:19:04 3
AM
PROVOCAREA
PROGRAMATORULUI
Filozofia de proiectare a programelor - s facem
lucrurile mai uoare pentru utilizatori
Principiul NNEMBDOMG
Eroi necunoscui de la Microsoft

3/20/2017 4:19:04 4
AM
CE ADUCE NOU WINDOWS
Interfaa grafic cu utilizatorul (GUI)
Apelurile de funcii
Programarea orientat pe obiecte
Arhitectura bazat pe mesaje
Procedura de fereastr

3/20/2017 4:19:04 5
AM
User Interface
Connection between the computer and the user
Two types:
Command Line
GUI: Graphical (Visual)

3/20/2017 4:19:04 6
AM
Command Line Interfaces
User types commands, must remember valid commands
Results Scroll by
Text-based
Interactive but hard to use
Only kind of interface available until 1970s

3/20/2017 4:19:04 7
AM
History of GUIs
DARPA SRI (late 60s)
Xerox PARC Alto (early 70s)
Microcomputers (late 70s to present)
PC (DOS command line)
Apple Lisa, Macintosh
First real microcomputer GUI
Microsoft Windows
Many versions
Well emphasize GUI Programming for Microsoft
Windows in this course

3/20/2017 4:19:04 8
AM
Other GUI-Windowing Systems
Sun Microsystems: Java
AWT
Swing
Platform independent
JDK is free
The X Window System
Developed at MIT, late 1980s
Networked graphics programming interface
Independent of machine architecture/OS (but
mostly used under UNIX/LINUX)

3/20/2017 4:19:04 9
AM
Classic Windows Processing
user events
via
keyboard or mouse

win32 API calls

windows

implements process
WinMain
message queue windows
messages and messages
implements
message
message loop
routing

provides
win32 API application
messages
functionality

register windows WinProc


"class"
implements
create window message application function calls
show window handling
update window for
get message application
dispatch message
windows
messages
controls

3/20/2017 4:19:04 10
AM
3/20/2017 4:19:04 11
AM
Ce nu ne place aici?
Hello, world!":
include <stdio.h>
main ()
{
printf ("Hello, world\n");
}

3/20/2017 4:19:04 12
AM
#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/20/2017 4:19:04 13
AM
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/20/2017 4:19:04 14
AM
hwnd = CreateWindow (szAppName, // window class name
"The Hello Program", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))


{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
3/20/2017 4:19:04 15
AM
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam,
LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (iMsg)
{
case WM_CREATE :
PlaySound ("hellowin.wav", NULL, SND_FILENAME | SND_ASYNC);
return 0 ;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rect);
DrawText (hdc, "Hello, Windows 95! ", -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
Programul HELLOWIN
3/20/2017 4:19:04 16
AM
Rularea programului HELLOWIN

3/20/2017 4:19:04 17
AM
Privire general

Fiierul conine numai dou funcii:


WinMain
WndProc
Funcia WinMain reprezint punctul de intrare n program.

WndProc este procedura de fereastr" a ferestrei

Nici o instruciune nu apeleaz direct funcia WndProc

3/20/2017 4:19:04 18
AM
Apelurile de funcii
LoadIcon - ncarc o pictogram
LoadCursor - ncarc un indicator pentru mouse
GetStockObject - obine un obiect grafic
RegisterClassEx - nregistreaz o clas de fereastr
CreateWindow - creeaz o fereastr pe baza unei clase
ShowWindow - afieaz o fereastr pe ecran
UpdateWindow - cere unei ferestre s se redeseneze
GetMessage - preia un mesaj din coada de mesaje.
TranslateMessage - convertete unele dintre mesaje

3/20/2017 4:19:04 19
AM
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
EndPaint - ncheie o operaie de desenare
PostQuitMessage - insereaz un mesaj de ncheiere
DefWindowProc - execut operaiile prestabilite

3/20/2017 4:19:04 20
AM
Identificatori cu majuscule
CS_HREDRAW, DT_VCENTER, WM_CREATE, IDC_ARROW,
WM_DESTROY, CW_USEDEFAULT, IDI_APPLICATION,
SND_ASYNC, WS_OVERLAPPEDWINDOW

Prefix Categorie
CS Opiune pentru stilul clasei
IDI Numr de identificare pentru o pictogram
IDC Numr de identificare pentru un cursor
WS Stil de fereastr
CW Opiune de creare a unei ferestre
WM Mesaj de fereastr
SND Opiune pentru sunete
DT Opiune de desenare a textului

3/20/2017 4:19:04 21
AM
Noi tipuri de date
UINT unsigned int
PSTR - pointer la un ir de caractere, char*
WPARAM - UINT
LPARAM - LONG
WinMain este de tipul WINAPI
WndProc este de tipul CALLBACK

3/20/2017 4:19:04 22
AM
Structuri de date
Structura Semnificaie
MSG Structura mesajului
WNDCLASSEX Structura clasei de fereastr
PAINTSTRUCT Structur pentru desenare
RECT Dreptunghi

3/20/2017 4:19:04 23
AM
Variabile handle
Identificator Semnificaie
HINSTANCE Variabil handle a unei instane" - programul nsui

HWND Variabil handle a unei ferestre

HDC Variabil handle a unui context de dispozitiv

3/20/2017 4:19:04 24
AM
Notaia ungar
Prefix Tip de date
c char
by BYTE (unsigned char)
n short
i int
x, y int (folosit pentru coordonate)
cx, cy int (dimensiuni pe x si y, c de la contor")
b sau f BOOL (int); f vine de la flag" (indicator)

3/20/2017 4:19:04 25
AM
Notaia ungar
Prefix Tip de date
w WORD (unsigned short)
l LONG (long)
dw DWORD (unsigned long)
fn funcie
s ir de caractere
sz ir de caractere terminat cu zero
h variabil handle
p pointer

3/20/2017 4:19:04 26
AM
3/20/2017 4:19:04 27
AM
Rezumat
Punctul de intrare n program
nregistrarea clasei de fereastr
Crearea ferestrei
Afiarea ferestrei
Ciclul de mesaje
Procedura de fereastr
Prelucrarea mesajelor
Redarea unui fiier de sunet
Mesajul WM_PAINT
Mesajul WM_DESTROY

3/20/2017 4:19:04 28
AM
Afiarea textului
Mesajul WM_PAINT

diferena dintre fereastra aplicaiei i zona client


funciile GDI
afiarea liniilor de text
fontul prestabilit
desenarea i redesenarea
primul mesaj WM_PAINT
Windows informeaz c o parte a zonei client trebuie s
fie actualizat

3/20/2017 4:19:04 30
AM
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/20/2017 4:19:04 31
AM
Interfaa GDI

Pentru desenarea zonei client - funciile din


interfaa pentru dispozitivele grafice (GDI)
DrawText
TextOut (hdc, x, y, psString, iLength);

3/20/2017 4:19:04 32
AM
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
O parte dintre valorile din DC sunt atribute grafice.

3/20/2017 4:19:04 33
AM
Obinerea unei variabile
handle DC

BeginPaint

EndPaint
PAINTSTRUCT ps
funcia BeginPaint completeaz cmpurile structurii ps.

Valoarea returnat de funcia BeginPaint este variabila


hdc
HDC hdc;

EndPaint elibereaz hdc

3/20/2017 4:19:04 34
AM
Obinerea unei variabile
handle DC
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
[apelarea unor funcii GDI]
EndPaint (hwnd, &ps) ;
return 0 ;

DefWindowProc prelucreaz mesajele WM_PAINT:


case WM_PAINT:
BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
return 0 ;
3/20/2017 4:19:04 35
AM
Structura de informaii pentru desenare

typedef struct tagPAINTSTRUCT


{
HDC hdc; Windows completeaz cmpurile cnd
BOOL fErase; programul apeleaz funcia BeginPaint
RECT rcPaint; fErase valoarea TRUE - Windows a
BOOL fRestore; ters fondul dreptunghiului invalid
BOOL fIncUpdate;
rcPaint al structurii PAINTSTRUCT
BYTE rgbReserved[32];
este o structur de tip RECT
}
PAINTSTRCUT; rcPaint din structura PAINTSTRUCT -
dreptunghi de decupare" (clipping
rectangle) - Windows restricioneaz
desenarea n interiorul dreptunghiului.
3/20/2017 4:19:04 36
AM
Limitele unui dreptunghi
invalid

Pentru desenarea n afara


dreptunghiului rcPaint n timpul
prelucrrii mesajului WM_PAINT:
InvalidateRect (hWnd, NULL, TRUE);
naintea apelrii funciei
BeginPaint.

Dac ultimul parametru are


valoarea FALSE, fondul nu este
ters i desenul va fi fcut peste
ceea ce exist deja

3/20/2017 4:19:04 37
AM
Obinerea unei variabile
handle DC

n timpul prelucrrii altor mesaje


hdc = GetDC(hwnd);
[apelarea unor funcii GDI]
ReleaseDC(hwnd, hdc);

3/20/2017 4:19:04 38
AM
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/20/2017 4:19:04
dispozitiv. 39
AM
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
font cu dimensiune fix
font cu dimensiune variabil

Fontul sistem este un font de tip rastru: fiecare


caracter este
3/20/2017 4:19:04definit ca un bloc de pixeli 40
AM
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/20/2017 4:19:04 41
AM
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:
static int cxChar, cyChar;

case WM_CREATE:
hdc = GetDC (hwnd);
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight +
tm.tmExternalLeading;
AM ReleaseDC (hwnd, hdc);
3/20/2017 4:19:04 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));

Dac nu afim numere n virgul mobil, folosim wsprintf n locul sprintf.


Aceeai sintax, dar este inclus n Windows!

3/20/2017 4:19:04 43
AM
S punem totul la un loc
GetSystemMetrics(iIndex) returneaz informaii despre dimensiunea
unor elemente grafice din Windows, cum ar fi pictograme, cursoare, bare
de titlu sau bare de derulare.
#define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
struct
{
int iIndex ;
char* szLabel ;
char* szDesc ;
}
sysmetrics [ ] =
{
SM_CXSCREEN, "SM_CXSCREEN", "Screen width in pixels",
SM_CYSCREEN, "SM_CYSCREEN", "Screen height in pixels",
SM_CXVSCROLL, "SM_CXVSCROLL", "Vertical scroll arrow width",
...
}

3/20/2017 4:19:04 44
AM
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)
AM
{
3/20/2017 4:19:04 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/20/2017 4:19:04 46
AM
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/20/2017 4:19:04 47
AM
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/20/2017 4:19:04 48
AM
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/20/2017 4:19:04 49
AM
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);
return3/20/2017
0; 4:19:04 50
AM
SYSMETS1
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}

3/20/2017 4:19:04 51
AM
Fereastra afiat de
SYSMETS1

3/20/2017 4:19:04 52
AM
Dimensiunea zonei client
Prelucrarea mesajului WM_SIZE n procedura de fereastr:

lParam - limea zonei client n LoWORD


nlimea - n cuvntul mai semnificativ (HiWORD).

Codul pentru prelucrarea acestui mesaj arat astfel:


static int cxClient, cyClient;
[alte linii de program]
case WM_SIZE
cxClient = LOWORD (lParam);
cyClient = HIWORD (lParam);
return 0;
3/20/2017 4:19:04 53
AM
Dimensiunea zonei client
LOWORD i HIWORD sunt definite n fiierele antet din
Windows. Mesajul WM_SIZE este urmat de un mesaj
WM_PAINT, deoarece la definirea clasei am specificat
urmtorul stil al clasei de fereastr:
CS_HREDRAW | CS_VREDRAW
Acest stil cere SO s foreze redesenarea ferestrei de fiecare
dat cnd se modific dimensiunea vertical sau orizontal a
acesteia.

Putem calcula numrul de linii de text afiate n zona client:


cyClient / cyChar
Aceast valoare poate fi zero dac zona client este prea mic.

Putem calcula numrul aproximativ de caractere care pot fi


afiate pe orizontal
3/20/2017 4:19:04 n zona client: 54
AM
cxClient / cxChar
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/20/2017 4:19:04 55
AM
Domeniul i poziia
domeniu" (pereche de
Poziia 0 numere ntregi care
Poziia 1 reprezint valorile
Poziia 2 maxim i minim)
Poziia 3
poziie" (punctul n care
Poziia 4
se afl caseta de derulare
n domeniul asociat barei
Poziia 0 Poziia 1 Poziia 2 Poziia 3 Poziia 4 de derulare).
SetScrollRange (hwnd, iBar, iMin, iMax, bRedraw) ;
SetScrollPos (hwnd, iBar, iPos, bRedraw) ;
3/20/2017 4:19:04 56
AM
Rspunderea pt ntreinerea i actualizarea
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
3/20/2017 4:19:04
care o conine. 57
AM
Rspunderea pt ntreinerea i actualizarea

Programul:
Iniializarea domeniului barei de
derulare.
Prelucrarea mesajului primit de la bdd.
Actualizarea poziiei casetei.

3/20/2017 4:19:04 58
AM
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/20/2017 4:19:04 59
AM
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 ;
switch (iMsg)
{
case WM_CREATE :
hdc = GetDC (hwnd) ;
GetTextMetrics (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cxCaps = (tm.tmPitchAndFamilycase& 1 ?WM_SIZE : /2;
3 : 2) * cxChar
cyChar = tm.tmHeight + tm.tmExternalLeading
cyClient ;= HIWORD (lParam) ;
ReleaseDC (hwnd, hdc) ; return 0 ;
SetScrollRange (hwnd, SB_VERT, 0, NUMLINES, FALSE) ;
SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
return 0 ;

3/20/2017 4:19:04 60
AM
Procedura de fereastr
case WM_VSCROLL :
switch (LOWORD (wParam))
{ case SB_THUMBPOSITION :
case SB_LINEUP : iVscrollPos = HIWORD (wParam) ;
iVscrollPos -= 1 ; break ;
break ;
case SB_LINEDOWN : default :
iVscrollPos += 1 ; break ;
break ; }
case SB_PAGEUP : iVscrollPos = max (0, min (iVscrollPos, NUMLINES));
iVscrollPos -= cyClient / if (iVscrollPos != GetScrollPos (hwnd, SB_VERT))
cyChar; {
break ; SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE);
case SB_PAGEDOWN : InvalidateRect (hwnd, NULL, TRUE);
iVscrollPos += cyClient / }
cyChar ; return 0;
break ;

3/20/2017 4:19:04 61
AM
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/20/2017 4:19:04 62
AM