Sunteți pe pagina 1din 62

Programarea n

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

CE ADUCE NOU WINDOWS


Interfaa grafic cu utilizatorul (GUI)
Apelurile de funcii

Programarea orientat pe obiecte


Arhitectura bazat pe mesaje
Procedura de fereastr

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

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/3/2015 10:50:50
PM

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/3/2015 10:50:50
PM

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/3/2015 10:50:50
PM

Classic Windows Processing


user events
via
keyboard or mouse

win32 API calls

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

application function calls

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

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/3/2015 10:50:50
PM

14

3/3/2015 10:50:50
PM

15

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/3/2015 10:50:50
PM

16

Rularea programului HELLOWIN

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.

WndProc este procedura de fereastr" a ferestrei


Nici o instruciune nu apeleaz direct funcia WndProc

3/3/2015 10:50:50
PM

18

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/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

EndPaint - ncheie o operaie de desenare


PostQuitMessage - insereaz un mesaj de ncheiere
DefWindowProc - execut operaiile prestabilite

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

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/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

Variabil handle a unei instane" - programul nsui

HWND

Variabil handle a unei ferestre

HDC

Variabil handle a unui context de dispozitiv

3/3/2015 10:50:50
PM

24

Notaia ungar
Prefix

Tip de date

char

by

BYTE (unsigned char)

short

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/3/2015 10:50:50
PM

25

Notaia ungar
Prefix

Tip de date

WORD (unsigned short)

LONG (long)

dw

DWORD (unsigned long)

fn

funcie

ir de caractere

sz

ir de caractere terminat cu zero

variabil handle

pointer

3/3/2015 10:50:50
PM

26

3/3/2015 10:50:50
PM

27

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/3/2015 10:50:50
PM

28

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/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

O parte dintre valorile din DC sunt atribute grafice.

3/3/2015 10:50:50
PM

33

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/3/2015 10:50:50
PM

34

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/3/2015 10:50:50
PM

35

Structura de informaii pentru desenare


typedef struct tagPAINTSTRUCT
{
Windows completeaz cmpurile cnd
HDC
hdc;
programul apeleaz funcia BeginPaint
BOOL
fErase;
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
}
rcPaint din structura PAINTSTRUCT PAINTSTRCUT;
dreptunghi de decupare" (clipping
rectangle) - Windows restricioneaz
desenarea n interiorul dreptunghiului.

3/3/2015 10:50:50
PM

36

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/3/2015 10:50:50
PM

37

Obinerea unei variabile


handle DC
n timpul prelucrrii altor mesaje
hdc = GetDC(hwnd);
[apelarea unor funcii GDI]
ReleaseDC(hwnd, hdc);

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

font cu dimensiune fix


font cu dimensiune variabil

Fontul sistem este un font de tip rastru: fiecare


caracter
3/3/2015este
10:50:50definit ca un bloc de pixeli
PM

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:

static int cxChar, cyChar;

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));

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


Aceeai sintax, dar este inclus n Windows!
3/3/2015 10:50:50
PM

43

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/3/2015 10:50:50
PM

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

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/3/2015 10:50:50
PM

53

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
3/3/2015
10:50:50
afiate
pe orizontal
n zona client:
PM
cxClient / cxChar

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).

SetScrollRange (hwnd, iBar, iMin, iMax, bRedraw) ;


SetScrollPos (hwnd, iBar, iPos, bRedraw) ;
3/3/2015 10:50:50
PM

56

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
care o conine.
3/3/2015 10:50:50
PM

57

Rspunderea pt ntreinerea i actualizarea

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