Вы находитесь на странице: 1из 592

Win32 API.

Windows

. capuu

re

. Cepue.o

erop

32.973.2-018.2

004.451
.

95

Win32 API.
592 .: .

Windows. -

.: ,

2008. -

ISBN 978-5-388-00301-0
mre : IWeI : I
/++

Windows

se

Win32.APl

:ra emp : : :upOIpaCO,

:, 8CIplO ,
++, OIIlolll aonc roe: I Wdows.
lIpaIcrxa , ' orpac apaary
are , FC I Wdows

Forms, a6o.I W32 !,

C'I'III8C ctpcII , : OJICO xor O8J[


:. aupom, :upcpa:po: W32 ! 03O.J!R 8Th
om .

Win32

.! JIJDIercJI [ ero

II.

000

2008

.
.
, , , 8eJlbCJO
. , ,

, .

ISBN 978-5-388-00301-0

73, . 29.
005-93, 2; 95 3005 - rrepa U[.
28.05.08. 7lOl16. Ycn. . . 47,73. paz2500.
Omea JI CtP IIea'l1 . . .
197110, Cahrr-IIeep, :nn:& ., 15.

000 Ihrrep
IUI -

198206, Cabrr-IIeep,

cme , .

CI yI


............................................................................... 13
1. Hello, World!,
Windows ......... 16
2. GDI
. , , ......... 58
3. GDI. , , ....................... 159
4. ........................................................ 213
5. Windows- ............................. 242
6. ..................................... 272
7. .................................................... 304
8. ....... 379
9. .................................................... 441
10. ..................................................... 485
11. DLL ........ 515
12. ..................................... 539
1. Visual C++ 6.0 ....... 563
2. Visual Studio.NET .. 577
3. Spy++ ............................. 584
............................................................................... 587
........................................................... 588

............................................................................... 13
........................................................................ 14
............................................................................... 14
........................................................................................ 15

1. Hello, World!,
Windows ........... 16
................................................................................... 16
................................................. 16
.................................................................................. 17
............................................................................ 18
................................................. 19
DLL ......................................................................... 19
- ................................... 20
Win32 .............................................................................. 20
, .................................................. 21
.............................................................................. 22
................................................................................... 23
.................................................................. 25
Windows ................................................... 25
Hello, world! ........................................... 30
....................................................... 31
...................................................................... 32
...................................................................................... 35
CreateWindowEx ............................................. 38
............................................................... 39
.......................................................................... 40
.............................................................................. 42

Hello, world! ............................................ 46


.......................................................................... 49
................................................................ 50
............................................................ 51
Windows .......................................... 52
................................................ 53
..................................................... 54
.................... 55
................................. 55

....................................... 56
Spy++ ............................................................ 57

2. GDI .
, , .......................................... 58
.................................................................................. 59
................................................................. 59
Windows. ............................................................... 60
................................................................................. 60
WM_PAINT .................................................. 63
................................................................................ 65
( ) .......................................... 65
....................................................................... 66
.................................................................. 66
...................................................... 66
, ...................................... 66
.................................................................. 67
............................................................ 68
............................................................. 68
....................... 69
................................................................. 72
................................. 74
. .......................................................... 76
HLS .................................................................. 76
RGB ................................................................. 76
.......................................... 77
.................................................................................... 78

, ......................... 78
. ............................... 79
............ 81
............................................ 81
........................................................................................ 82
.............................................................................. 83
..................................................................................................... 84
....................................................................................... 86
........................................................................................................ 87
............................................................................... 88
...................................................................................... 89
.............................................................................. 93
......................................................................................................... 96
............................................................................... 97
....................................................................... 97
.................................................................................... 101
................................................................................... 101
, , ............. 105
.................................................................................... 107
................................................................................. 109
............................................................................... 109
.......................................................... 111
........................................................................... 111
............................................................................................ 112
.................................................................................. 113
............................................................. 114
Unicode ................................................................................................. 117
............................................................................................... 118
........................................................................................ 129
........................................................ 141
.................................................................................... 146
.......................................................... 146

................................................... 153

3. GDI. , , ......................... 159


.................................................................................................... 159
........................................ 159

............................................................................... 161
.............................................................................. 166
....................................................................................................... 174
- ........................................................... 175
- ............................................................... 193
DIB- ........................................................................................... 200
........................................................... 202
............................................................................................... 206
............................................................................ 207
................................................................ 210

4. .......................................................... 213
................................................................................................ 213
.......................................................................................... 214
.............................................................................. 215
........................................................................ 215
........................................................................ 217
................................................................................ 219
....................................................... 220
........................................................................................................ 225
, ...................................................... 226
................................................................................. 226
................................................................. 227
................................................ 227
...................................................................................... 228
................................................................ 234
................. 237

5. Windows- ................................ 242


.................................................................................. 243
............................................................................................. 243
................ 246
.................................................... 250
.............................. 251
................................................. 252
.................................................................................................... 256
..................................................................................... 260
, .................................................... 263

................................................................... 263
........................................................... 264
.......................................................................................... 268

6. ....................................... 272
........................................................................ 272
.............................................................................. 273
................................................................................... 274
............................................................ 273
............................................................................ 275
......................................................................... 275
, ............................................ 276
........................................................... 276
....................................................................................... 276
......................................................................... 277
......................................................................... 278
........................................................................................ 279
i- .......................... 279
................................... 280
....................................................... 280
..................................................................... 281
CheckMenuItem ....................................................................... 282
CheckMenuRadioItem .............................................................. 282
EnableMenuItem ...................................................................... 283
ModifyMenu ............................................................................. 283
.......................................... 284
....................................................................................... 284
MenuDemo1 ........................................................................... 286
...................................................................... 293
........................................... 293
...................................................................................... 293
.......................................................................................... 293
MenuDemo2 ...................................................................... 294
...................................................................................... 299
............................................ 299
..................................................................... 300
....................................................... 301

.......................................... 301
MenuDemo3 ...................................................................... 302

7. ....................................................... 304
.............................................................................. 304
................................................. 305
................................................... 307
.................................................................... 307
.................................................................. 308
.................................................................................... 308
............................ 309
.......................................... 311
........................................ 312
..................... 314
......................... 316
......................................... 320
........................................... 323
.................................................................................................. 323
Owner draw ............................................................................... 325
................................................................................................. 331
.................................................................................... 333
.................................................................................. 333
, .. 334
.... 340
........................................................................... 341
.................................................................................................. 344
..................................................................... 356
................................................................................. 366
........... 366
............................. 367
........................................................................................ 372
...................................................... 374

8. .......... 379
.................................................................................. 380
.................................................................. 380
......................... 382
.............................. 383

10

............................................................................. 384
........................................................ 385
........................................................................... 385
.................................................................................... 406
KWnd KWndEx ................................................. 408
................................................................................. 413
.................................................................... 423
............................................................................. 423
............................................................................................. 428
................................................................ 435
............................................................................... 435

9. ....................................................... 441
............................................................................................ 441
.................................................................................... 443
.............................................................................. 444
.......................... 445
............................................................................ 447
CreateProcess ................................................. 447
........................................................................... 448
........................................... 449
................................................................................ 451
CreateThread ........................................................................... 451
Sleep ...................................................................................... 452
................................................... 452
..................... 456
.......................................................................................... 459
Interlocked- ............................ 459
............................................................................. 460
Wait- ........................................................................................ 461
................................................................................................ 464
............................................................................................. 466
............................................................................................. 467
........................................................... 469
. ........................ 470
, ............................................... 472
.. 472

11

- ...................................................................... 473
WM_COPYDATA ....................... 474
ServerApp ......................................................................... 475
ClientApp .......................................................................... 479
.......................................................... 483
? ................................................ 484

10. ..................................................... 486


Windows .......................................................................................... 486
....................................................................................... 487
................................................. 488
...................... 488
RDTSC ............................................................ 489
...................................... 497
Sleep .............................................................. 498
uDelay KTimer ........................................ 501
QTimer ........................................................................................ 502
................................................................................. 504
......................... 504
.......................... 508
........................................................................... 509
timeSetEvent timeKillEvent .................................................... 509
............................................. 511

11. DLL ........ 515


DLL ..................................................... 514
DLL ........................................................................ 517
DLL .............................................................................. 519
DLL ............................................................................. 519
DLL ............................................................................... 521
DLL ..................................................................... 523
DLL .......................................................................... 525
/ .............................................................................. 527
(TLS) ................................................................. 529
TLS ................................................................................ 531
TLS ................................................................................... 538

12

12. ..................................... 539


.................................................................................................. 539
................................................ 539
.......................................................................... 543
................................................................. 547
............ 547
....................................... 548

1. Visual C++ 6.0 ....... 563


IDE. .................................................................. 563
..................................................................... 565
................................. 566
...................................................................... 568
, .................................. 568
......................................................................... 569
..................................................... 569
,
...................................................... 569
........................................................... 570
............................................................................ 570
....................................................... 574

2. Visual Studio.NET .... 577


.......................................................................... 578
......................................................... 580
, ........................................................... 582
................................................................. 583

3. Spy++ ............................. 584


.................................................................. 587
........................................................... 588


API Application Programming Interface ( 
). API 
, (), 
.
Win32 API , 
Microsoft Windows 98, Windows NT Windows 2000.
32, .
Windows
, 
MSDN, 
. , , 
, .
,

.

Windows C/C++ Win32 API.
.
, Windows
. , 
, , .

DLL. : ,
. C/C++

Windows.


, , MFC (Microsoft Foundation
Classes) Windows Forms.
, MFC, Windows Forms,
Windows API.
Win32 API 
Windows. , ,
MFC Windows Forms, 
, 

14

. , , Win32
API, 
.
, 
. , MFC Windows Forms 
, 
.
(, 
),
Win32 API.
:
 , Windows
(Charles Petzold) [1], (Jeffrey
Richter) [5] (Feng Juan) [6];
 ;
 Windows
 
, .
, , 
Win32 API. , 
2006 . ,
DLL.


. 
, , ,
, C++, 
Windows.
, C/C++ ,
, .
, , 
.
:)



C/C++ Win32 API. , 
. 
Win32 API, 
.

Microsoft Windows 2000 Professional Microsoft Visual Studio
6.0. Windows 98, Windows NT/2000

15

Windows XP. Visual


Studio 6.0, , 
1.
Microsoft Visual Studio.NET,
,
2.

. 
, , 
.
, ,
, 
. K,
MFC.

, ,
.  
, 
, .

Windows. ,
Windows.
, ,
,
shupak@mail.ru.


, 
comp@piter.com ( , ).
!
, , http://
www.piter.com/download.
 
: http://www.piter.com.

16

1. Hello, World!, Windows

Hello, World!,


Windows

, , 
Windows. , ,
Microsoft Word 
Microsoft Office. , 
, Windows. ,
,

Windows.


Windows
MSDOS , 
. :
 ;



Graphical User Interface1 (GUI) 
.
,
.
, , 
.
.
1

17

, , 
, , 
.
Windows , .

,
. , 
, 
Windows,
.



. , Visual Studio 6.0 
, ,
, 
Windows Media. explorer.exe 

.
Windows
( ) ,
,
. , 

. Windows 95 . 
,
, .
Windows .
Windows (process). 
, 
.
() (thread),
, .

, 
.
,
. 

.
? , 
.
, . ,
COM,
.

18

1. Hello, World!, Windows

, , , 
. (top
level window)1, (child windows).
(parent windows). 1.1 
.

. 1.1. ,

, 
.
,
. , . ,
, ,
.


.
,
, .
, , . 
, 
.
Windows
. ,
,
. , 
1

19

, 
,
. , Windows, 
, 
DLL (dynamic link libraries). Windows 
DLL.
Windows, , 
.

Windows. Win32 API 32
.


Windows
. , Windows,
, , ,
. 
Win32 API, (Graphics De
vice Interface, GDI).
GDI 
.
(, LineTo )
. , 
Win32 API, .
, , Win32 API,
,
Windows. 
, . . Windows
,
, SDK (Software Development
Kit ) / DDK (Driver Development Kit
). 
,
.

DLL
Win32 API ,
. Windows 
. windows.h.
.
Win32 API 
C/C++. ,
C/C++ 
( ),
Windows

20

1. Hello, World!, Windows

( ). 
(DLL) .dll. 
SYSTEM 
Windows.

, . 

, . ,
, 
Win32 API.

-
Windows 
, , 
. ,
, , ,
.
, 
. 
.
,
, , 
.
, 
.
.
Windows.
Windows, ,
, , ,
, , , .
, Windows 
, . 
handle1. .

. Windows
.

Win32
, C/C++,
Windows .
#define #typedef Win32.
. 1.1
Windows.
1

21

1.1. Win32

BOOL

( bool)

BYTE

(8- )

DWORD

32-

HANDLE

HBITMAP

( )

HBRUSH

HCURSOR

HDC

HFONT

HICON

()

HINSTANCE

HMENU

HPEN

HWND

INT

32-

LONG

32-

LPARAM

, lParam,

LPCSTR

C-1

LPCTSTR

LPCWSTR, UNICODE, LPCSTR

LPCWSTR

Unicode-2

LPSTR

C-

LPTSTR

LPWSTR, UNICODE, LPSTR

LPWSTR

Unicode-

LRESULT

LONG,

NULL

((void*) 0)

TCHAR

Wchar_t (Unicode-), UNICODE, char

UINT

32-

WPARAM

, wParam,

,

.
, , 
, ,
1

C . 
ANSI. , , 
C.

Unicodec , 
. UNICODE, 
, 2.

22

1. Hello, World!, Windows

. 
, ,
. ,
, .
, :
 , ;


() ;

, .
, Windows . 
, ,
,
. Windows 
? 
, . 
, , ,
. Windows , , 
, 
.
, ,
. , , 
,
.
, Windows 
, .
.
, , 
, :




, .
,
, , 
.
, 
, , Windows.
, , .
. , 
.
.
CALLBACK.
:
LRESULT CALLBACK _(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

23

LRESULT (. . 1.1),
hWnd , , uMsg ,
wParam lParam . 
, WndProc.

switch, 
.
Windows 
.
#define winuser.h. 
.
(window messages),
WM_, : WM_PAINT, WM_SIZE, WM_MOVE
. , 
: BM_ , 
EM_ , LB_ .

. 
, , .
.
.
.
.


(window class), ,
. 
, , ,
. , ,
,
.
CreateWindow,
.

, ,
. , Windows
BUTTON. ,
,
. 
, , , . 

.
Windows 
, .
,
.

24

1. Hello, World!, Windows

Windows C++ , ,
MFC. ,
Windows - .

, ? 
.


Windows 
. WinMain. 
,

.
? , ,
, Windows 
. GetMessage.
WM_QUIT, ,
.
WM_QUIT, 
DispatchMessage, Windows.
Windows
, Windows . 
Windows ,
DispatchMessage, .
, , , ...

Windows

Microsoft Visual C++ 6.0, , , 
1, , 
, , 
.
OK! ?.. .
Win32 Application HelloFromMsgBox.
HelloFromMsgBox.cpp
:
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "Hello, Win32 world!", "Hello from Message Box", MB_OK);
return 0;
}

Windows

25

. ,
. 
, . , 
. 1.2.

. 1.2. HelloFromMsgBox

?
Hello, Win32 world!. . ,
. . OK. .
. 
, .
, ?.. 
,
WinMain?
. 
:
#include <windows.h>

Windows
.
WinMain:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)

main DOS UNIX,


.
int :
 HINSTANCE hInstance , Windows 
.


HINSTANCE hPrevInstance Win32


1.

LPSTR lpCmdLine , 
, .
, Norton Commander. 
, , 
.
EXE. (
EXE), 
.

, Object.

Windows 3.x, 
.

26

1. Hello, World!, Windows

int nCmdShow ,
ShowWindow. .
WINAPI ,
Win32 . 
, ,
WinMain .
, .
MessageBox, , , 
.
?
?.. :
MessageBox.
,
MessageBox, MSDN1.

F1.
MessageBox .
MessageBox, , ,
. ,
.
2:


int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);




:
hWnd . NULL, 
.

lpText , .

lpCaption ,
.

uType ,
, .
MessageBox 
7. ,
,
.
, Windows. , 
MessageBox,
, .


Microsoft Developer Network (MSDN) , 



Microsoft. MSDN (MSDN Library), 
Microsoft Visual Studio 6.0,
, Win32 API. 
MSDN MSDN.

( ) ,
.

Windows

27

, 
, Windows.
, , 
.
, , ! , ,
WinMain . . 
MessageBox. .
Windows, , 
,
Microsoft (Charles Simonyi).
, ,
. . 
, , 
, . ,
nMyVariable . 
. 1.2.
1.2.

b
by
c
dw
fn
h
i
l
lp
lpsz
n
p
pfn
psz
pv
sz
u
v
w
x

BOOL
BYTE
har
DWORD

INT
LONG

,
short int


,
void
,
UINT
void
WORD
, x

, y

, , ,
, lpText uType. ,
,
. , 

, , 
.

28

1. Hello, World!, Windows

Windows, 
, Win32
:
 (screen coordinates);


(window coordinates);

(client coordinates).
. 1.3 ,
.


. 1.3. Windows


, .
,
. 
. 
. 
, Move (),
Size (), Minimize (), Maximize (), Close (). 
,
.
,
, .

29

Hello, World!

.
.
.
, Windows 
. .

Hello, World!
Win32 
:
 WinMain ,
;
WndProc , 
.
Windows
:


WinMain ( )
{
;
;
{
;
Windows ;
}
;
}
WndProc ( )
{
;
;
}

, , 
Hello, World!. ,
1.1, Hello1.cpp.
1.1. Hello1
//////////////////////////////////////////////////////////////////////
// Hello1.cpp
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
nCmdShow)
{
HWND hMainWnd;
char szClassName[] = "MyClass";

30

1. Hello, World!, Windows

1.1 ()
MSG msg;
WNDCLASSEX wc;
//
wc.cbSize
= sizeof(wc);
wc.style
= CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc
= WndProc;
wc.cbClsExtra
= 0;
wc.cbWndExtra
= 0;
wc.hInstance
= hInstance;
wc.hIcon
= LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor
= LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm
= LoadIcon(NULL, IDI_APPLICATION);
//
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, "Cannot register class", "Error", MB_OK);
return 0;
}
//
hMainWnd = CreateWindow(
szClassName, "A Hello1 Application", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
(HWND)NULL, (HMENU)NULL,
(HINSTANCE)hInstance, NULL
);
if (!hMainWnd) {
MessageBox(NULL, "Cannot create main window", "Error", MB_OK);
return 0;
}
//
ShowWindow(hMainWnd, nCmdShow);
// UpdateWindow(hMainWnd); // . " "
//
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
switch (uMsg)

Hello, World!

31

{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, "Hello, World!", -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER );
EndPaint(hWnd, &ps);
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

Hello1, . 
,
. 1.4.

. 1.4. Hello1

. Hello1 
, .


Hello1.cpp : WinMain WndProc. WinMain
. WndProc

32

1. Hello, World!, Windows

. , 
, ,
.
Hello1.cpp WndProc
Windows. WinMain
WndProc ( wc.lpfnWndProc),
WndProc , 
WinMain.
, 
. Windows.
 ,
, CS_HREDRAW, IDI_APPLICATION, IDC_ARROW,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT. .
, .
. 1.3.
1.3.

CS_

CW_

DT_

IDC_

IDI_

()

WM_

WS_

,
Windows. . 1.1.


WinMain
. WNDCLASSEX,
RegisterClassEx.
WNDCLASSEX :
typedef struct tagWNDCLASSEX {
UINT cbSize;
//
UINT style;
//
WNDPROC lpfnWndProc;
// ( )
int cbClsExtra;
// ,
//
int cbWndExtra;
// ,
//
HINSTANCE hInstance;
// ,
//
HICON hIcon;
//
HCURSOR hCursor;
//
HBRUSH hbrBackground; // ,
//

Hello, World!

33

LPCTSTR lpszMenuName;

// , ,
//
LPCTSTR lpszClassName; // ,
HICON hIconSm;
//
} WNDCLASSEX;

,
.
LP lp (long pointer), 16- Windows, 16- 32-
. Win 32 API 32 .
lpfn (long pointer to a function). cb
(counter of bytes). hbr (handle
to a brush).

WNDCLASSEX.
, cbSize, .
, style, 
, . 1.41.
1.4.

CS_GLOBALCLASS

, .
DLL

CS_HREDRAW

CS_NOCLOSE

Close

CS_OWNDC

CS_VREDRAW

Windows , 
CS_, 32 ,
. , CS_VREDRAW
0x0001, CS_HREDRAW 0x0002. 
(bit flags).
C++.

CS_HREDRAW | CS_VREDRAW. , 
, 
. A Hello1
Application, ,
.
.
, lpfnWndProc, ( 
WndProc).
1

. . MSDN.

34

1. Hello, World!, Windows

46 1.
, hIcon, , 
. (: , ) 
, Windows 
. hIcon LoadIcon,
:
HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);

, lpIconName,
, hInstance2.
() 
, NULL.
, 
IDI_ ( ID for icon). 
. 1.5.
1.5.

IDI_APPLICATION
IDI_ASTERISK
IDI_ERROR
IDI_EXCLAMATION
IDI_HAND
IDI_INFORMATION
IDI_QUESTION
IDI_WARNING


, IDI_INFORMATION
.
, IDI_WARNING
, IDI_ERROR
i,
?
!,

IDI_WINLOGO

Windows

hCursor , 
. hCursor 
LoadCursor, :
HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName);

, (lpCursorName), , (hInstance)3.
(
) , NULL. 
. 1.6.
1.6.

IDC_APPSTARTING

IDC_ARROW

cbClsExtra cbWndExtra .

5.

5.

Hello, World!

35

IDC_CROSS

IDC_HELP

IDC_IBEAM

IDC_NO

IDC_SIZEALL

IDC_SIZENESW

, - -

IDC_SIZENS

IDC_SIZENWSE

, - -

IDC_SIZEWE

IDC_UPARROW

IDC_WAIT

, hbrBackground, , 
. (brush) 
, 
, . Windows
. GetStockObject 
WHITE_BRUSH . 
HGDIOBJ, HBRUSH.
, lpszMenuName, , , 
.
, NULL.
lpszClassName , . 
lpClassName CreateWindow.
, hIconSm, , 
,
. 16 16 .
NULL, , hIcon,
.
, . 
, RegisterClassEx. 
1 RegisterClass Windows.
RegisterClass, 
WNDCLASS ( WNDCLASSEX).


,
. CreateWindow,
:
HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
1

//
//
//
//

Ex, extended .

36

1. Hello, World!, Windows


int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lParam

//
//
//
//
//
//
//
// ,
//WM_CREATE

);

, , Create
Window ,
, , 
Windows.
, lpClassName, , 
. , 
RegisterClassEx RegisterClass, 
, . 1.7.
1.7.

BUTTON

, , ,
, LISTBOX
EDIT.
LISTBOX
( ),
,
.
, MDI-
Rich Edit 1.0.
EDIT

Rich Edit 2.0 3.01.
RICHEDIT

.

BS_

COMBOBOX

EDIT
LISTBOX
MDICLIENT

RICHEDIT

RICHEDIT_CLASS

SCROLLBAR
STATIC

CBS_

ES_
LBS_

ES_

ES_

SBS_
SS_

, lpWindowName, ,
. . ,
(. . 1.3), 
BUTTON .
1

Windows, .

Hello, World!

37

, dwStyle, , 
, . 1.8. 
.
,
. ,
. 1.71.
1.8.

WS_BORDER
WS_CAPTION

WS_THICKFRAME
WS_VISIBLE


, (
WS_BORDER)
.
WS_POPUP
,



, , .

( )

,

,

.

WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU,
WS_THICKFRAME, WS_MINIMIZEBOX WS_MAXIMIZEBOX
.
WS_CHILD
WS_BORDER, WS_POPUP WS_SYSMENU.
,
WS_CAPTION

, ,
TAB
,
,

WS_VSCROLL

WS_CHILD
WS_CLIPCHILDREN
WS_CLIPSIBLINGS
WS_DLGFRAME
WS_GROUP
WS_HSCROLL
WS_MAXIMIZE
WS_MAXIMIZEBOX
WS_MINIMIZE
WS_MINIMIZEBOX
WS_OVERLAPPED
WS_OVERLAPPEDWINDOW
WS_POPUP
WS_POPUPWINDOW

WS_SYSMENU
WS_TABSTOP


WS_OVERLAPPEDWINDOW.
, , ,
1

.
MSDN.

38

1. Hello, World!, Windows

,
, .
, x,
. x y ,

.
x , CW_USEDEFAULT.
Windows x y . , 
,
.
, y, .
x CW_USEDEFAULT, y .
, nWidth, .
CW_USEDEFAULT, nWidth nHight
.
, nHight, . nWidth
CW_USEDEFAULT, nHight .
, hWndParent,
NULL, . 
, , 
, .
, hMenu,
. .
, ( lpszMenuName WNDCLASSEX), hMenu NULL.
, hMenu
, 
. , ,
WM_COMMAND, .
, hInstance,
, WinMain.
, lParam,
NULL. 
, 
WM_CREATE.
, CreateWindow . ,
.  ,
NULL. 
, 
MessageBox.

CreateWindowEx
CreateWindow
CreateWindowEx, :
HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName,
LPCTSTR lpWindowName, DWORD dwStyle,
int x, int y, int nWidth,

Hello, World!

39

int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance,


LPVOID lParam);

, , , 
CreateWindow. , dwExStyle, ,
, dwStyle. 
, ,
. 1.9.
MSDN.
1.9.

WS_EX_ACCEPTFILES

WS_EX_CLIENTEDGE

WS_EX_CONTROLPARENT


Tab

WS_EX_MDICHILD

WS_EX_STATICEDGE

.
,

WS_EX_TOOLWINDOW

WS_EX_TRANSPARENT

. ,
, WM_PAINT
,

WS_EX_WINDOWEDGE

CreateWindowEx , CreateWindow, 
,
Windows.
1.


ShowWindow,
:
BOOL ShowWindow(HWND hWnd, int nCmdShow);

,
, .

,
nCmdShow WinMain.
, 
. 1.102.
1

7, 
8.

. . MSDN.

40

1. Hello, World!, Windows

1.10. nCmdShow ShowWindow

SW_HIDE

SW_MAXIMIZE

SW_MINIMIZE

SW_SHOW

SW_SHOWMINNOACTIVE

, Win32 API,
MSDN ShowWindow UpdateWindow, WM_PAINT,
. , . , ShowWindow
WM_SIZE WM_MOVE, WM_SIZE, WM_PAINT. UpdateWindow .



. 
. Windows (message queue)
, .
Windows ,
.
, , 
(message loop):
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

msg MSG, 
Windows :
typedef struct tagMSG
HWND
hwnd;
UINT
message;
WPARAM wParam;
LPARAM lParam;
DWORD
time;
POINT
pt;

{
// ,
// ()
// wParam
// lParam
//
// ( )
//

} MSG;

wParam lParam .
POINT :

Hello, World!

41

typedef struct tagPoint {


LONG x;
LONG y;
} POINT;


GetMessage, :
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)


lpMsg MSG, 
.

hWnd , . 
NULL,
.

wMsgFilterMin 
. .

wMsgFilterMax
.
, .
GetMessage TRUE 
, WM_QUIT. WM_QUIT, 
FALSE. 
, ,
msg.wParam.
?
:
TranslateMessage DispatchMessage.
, TranslateMessage , 
. , 

Windows
.
, : WM_KEYDOWN
, WM_KEYUP 
. WM_KEYDOWN
1 .
TranslateMessage , WM_KEYDOWN WM_KEYUP,
WM_CHAR, (wParam)
TCHAR2. WM_CHAR , 
GetMessage .
, DispatchMessage msg Windows.
Windows. Windows 
,
.


, .

TCHAR char, UNICODE . 


wchar_t (Unicode).

42

1. Hello, World!, Windows

, 
, . WndProc
( ),
, 
, Windows ( DLL).
Windows 
, DispatchMessage, while, 
.
,
, WM_QUIT. 
.


(window
procedure). , 
, , .
:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)


MSG. , 
. .
Win32 0 1024.
, 
.
WndProc ,
lpfnWndProc wc.
MyClass. 
hMainWnd CreateWindow. 
hWnd hMainWnd.

(, , ), 
hWnd , 
.
switch , 
. 
, . ,
,
DefWindowProc. ,
DefWindowProc.
, ,
. Hello1 
: WM_PAINT, WM_CLOSE WM_DESTROY.

WM_PAINT
WM_PAINT Win
dows. ,

Hello, World!

43

(invalid) .
WM_PAINT ,
,
Hello1.
?
, ,
. .
, 
, CS_HREDRAW |
CS_VREDRAW style . .
Hello1, 
, , Windows
. .
, ,
, Windows 
. .
, .
, , 
,
WM_PAINT. ,
, ShowWindow.
WM_SIZE WM_MOVE, 
WM_SIZE, WM_PAINT.
,
.
WM_PAINT 
BeginPaint:
hDC = BeginPaint(hWnd, &ps);

, 
, ps PAINTSTRUCT.
, BeginPaint, 
1. 

.
(device context) 
, . 
Windows .
,
, ,
, , , . 
, hDC
.
,
BeginPaint.
1

PAINTSTRUCT 2.

44

1. Hello, World!, Windows

, BeginPaint, Windows
, 1. 
, hbrBackground
WNDCLASSEX.
, BeginPaint 
(valid), . 
WM_PAINT , 
, .
BeginPaint 
GetClientRect,
:
GetClientRect(hWnd, &rect);

rect RECT. 
RECT, (rectangle), 
Windows :
typedef
LONG
LONG
LONG
LONG
} RECT;

struct tagRECT {
left;
top;
right;
bottom;

(left, top) 
(right, bottom) .
GetClientRect left top 
, right bottom
. , 
rect, DrawText.
Hello, World!
DrawText, :
BOOL DrawText(
HDC hdc,
LPCTSTR lpString,
int nCount,
LPRECT lpRect,
UINT uFormat
);

//
//
//
//
//

2 lpString ,
RECT, ,
uFormat. nCount.
nCount 1, lpString
. 
, .
DT_SINGLELINE |
DT_CENTER | DT_VCENTER,
1

ps.

DrawText. 
2.

Hello, World!

45

Windows. , , 
, 
. Hello, World!
.
(, 
), WndProc WM_PAINT. 
, GetClientRect
.

WM_PAINT 
EndPaint.
,
, . , ,
. , 
, .


SetTextColor
(text color) . SetBkColor
(background color), 
, . 
(background mix mode), SetBkMode. 
OPAQUE1,
, 
. TRANSPARENT2,
, 
.
, 
, . 1.11.
1.11.

OPAQUE

Hello1.

WM_CLOSE WM_DESTROY
WM_CLOSE ,
Alt+F4. , 
: , DefWindowProc 
DestroyWindow.
 ,
1

46

1. Hello, World!, Windows

?, . 
, WM_DESTROY .
DestroyWindow, , 
. WM_DESTROY.
, WM_DESTROY ,
. 
.
WM_DESTROY,
,
. PostQuitMessage,
WM_QUIT.
WM_QUIT, .
: Hello1
Hello, World!.
, ?.. ,
.

Hello, World!
Hello, World! Windows
. , 
: ,
WinMain, Hello1.cpp1, 
.
, , 
, C++.
,
? , 
? , .
. KWnd, 
, ,
, .
[9],
: .h,
.cpp. ,
, 1.22.
1.2. Hello2
//////////////////////////////////////////////////////////////////////
// KWnd.h
#include <windows.h>
class KWnd {

, 1.

Hello, World!

47

public:
KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow,
LRESULT (WINAPI *pWndProc)(HWND,UINT,WPARAM,LPARAM),
LPCTSTR menuName = NULL,
int x = CW_USEDEFAULT, int y = 0,
int width = CW_USEDEFAULT, int height = 0,
UINT classStyle = CS_HREDRAW | CS_VREDRAW,
DWORD windowStyle = WS_OVERLAPPEDWINDOW,
HWND hParent = NULL);
HWND GetHWnd() { return hWnd; }
protected:
HWND hWnd;
WNDCLASSEX wc;
};
//////////////////////////////////////////////////////////////////////
// KWnd.cpp
#include "KWnd.h"
KWnd::KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow,
LRESULT (WINAPI *pWndProc)(HWND,UINT,WPARAM,LPARAM),
LPCTSTR menuName, int x, int y, int width, int height,
UINT classStyle, DWORD windowStyle, HWND hParent)
{
char szClassName[] = "KWndClass";
wc.cbSize
wc.style
wc.lpfnWndProc
wc.cbClsExtra
wc.cbWndExtra
wc.hInstance
wc.hIcon
wc.hCursor
wc.hbrBackground
wc.lpszMenuName
wc.lpszClassName
wc.hIconSm

=
=
=
=
=
=
=
=
=
=
=
=

sizeof(wc);
classStyle;
pWndProc;
0;
0;
hInst;
LoadIcon(NULL, IDI_APPLICATION);
LoadCursor(NULL, IDC_ARROW);
(HBRUSH)GetStockObject(WHITE_BRUSH);
menuName;
szClassName;
LoadIcon(NULL, IDI_APPLICATION);

//
if (!RegisterClassEx(&wc)) {
char msg[100] = "Cannot register class: ";
strcat(msg, szClassName);
MessageBox(NULL, msg, "Error", MB_OK);
return;
}
//
hWnd = CreateWindow(szClassName, windowName, windowStyle,
x, y, width, height, hParent, (HMENU)NULL, hInst, NULL);
if (!hWnd) {
char text[100] = "Cannot create window: ";
strcat(text, windowName);
MessageBox(NULL, text, "Error", MB_OK);
return;

48

1. Hello, World!, Windows

1.2 ()
}
//
ShowWindow(hWnd, cmdShow);
}
//////////////////////////////////////////////////////////////////////
// Hello2.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
nCmdShow)
{
MSG msg;
KWnd mainWnd("A Hello2 application", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
int userReply;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, "Hello, World!", -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER );
EndPaint(hWnd, &ps);
break;
case WM_CLOSE:
userReply = MessageBox(hWnd, " ?",
"", MB_YESNO | MB_ICONQUESTION);
if (IDYES == userReply)
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:

49

return DefWindowProc(hWnd, uMsg, wParam, lParam);


}
return 0;
}
//////////////////////////////////////////////////////////////////////

:
KWnd 12 . 
, 
.

,
LRESULT. 
WINAPI __stdcall.

, , 
KWnd.

WinMain mainWnd KWnd,


.

WM_CLOSE 
. MessageBox 
.
MB_YESNO : YES NO.
YES IDYES,
DestroyWindow.
( Hello2), 
.
mainWnd. ,


KWnd mainWnd("Hello application", hInstance, nCmdShow, WndProc);


KWnd mainWnd("Hello application", hInstance, nCmdShow, WndProc, NULL, 50,
100, 200, 150);

.
Hello, World! . 
KWnd 
.

KWnd, KWnd.h
KWnd.cpp, #include "KWnd.h" , .


Win32 API ,
, . . 1.12 
.

50

1. Hello, World!, Windows

1.12.

BringWindowToTop

CloseWindow

EnableWindow

FindWindow

GetActiveWindow

GetClassInfo

WNDCLASS

GetClassLong


WNDCLASSEX

GetClientRect

GetFocus

GetParent

GetWindow

GetWindowInfo

WINDOWINFO

GetWindowLong

GetWindowRect

IsChild

IsIconic

IsZoomed

IsWindowEnabled

MoveWindow

SetActiveWindow

SetClassLong

32- WNDCLASSEX ,

SetFocus

SetWindowLong

(
CreateWindow)

SetWindowPos

SetWindowText

ShowWindow

UpdateWindow


WM_PAINT ,


. 1.13 , 
.

51

1.13.

WM_CLOSE

, .

,
DestroyWindow. ( WM_CLOSE ) DefWindowProc DestroyWindow

WM_COMMAND

WM_CREATE

, CreateWindow
CreateWindowEx. ,
, . ,
, , .

. 1, , CreateWindow
NULL

WM_DESTROY

WM_INITDIALOG

1 , . ,

WM_MOVE

WM_PAINT

WM_SIZE

WM_TIMER

, ,
SetTimer,


, , KWnd, 
: SetClassLong
SetWindowLong.
SetClassLong, 
WNDCLASSEX. , 
RegisterClassEx
.
SetClassLong :
DWORD SetClassLong(
HWND hWnd,
//
int nIndex,
// ,
LONG dwNewLong
//
);

7.

52

1. Hello, World!, Windows

nIndex ( ) 1 ,
, , . 1.14.
1.14. nIndex SetClassLong

GCL_HBRBACKGROUND

GCL_HCURSOR

GCL_HICON

GCL_HICONSM

GCL_MENUNAME

GCL_STYLE

GCL_WNDPROC

Hello2, 
.
WndProc, switch, 
:
case WM_CREATE:
SetClassLong(hWnd, GCL_HBRBACKGROUND,
(LONG) CreateSolidBrush(RGB(200,160,255)));
break;

, 
2.

hDC = BeginPaint(hWnd, &ps);

:
SetBkMode(hDC, TRANSPARENT);

Windows
, 
. 
Windows
, .
UpdateWindow (. . 1.12) ,
Windows WM_PAINT
, . 
. ,
, Windows.
1

, cbClsExtra.

CreateSolidBrush (RGB (200, 160, 255)) , 


: (200), (160)
(255). .
CreateSolidBrush 2.

Windows

53


, Windows
. 
.
, Windows 
.
. ,
,
(WM_KEYDOWN WM_KEYUP), (WM_MOUSEMOVE)
(WM_LBUTTONDOWN). , 
(WM_TIMER),
(WM_PAINT) (WM_QUIT).
,
PostMessage.
, , . 

. ,
DefWindowProc, Windows , 
. , 
SendMessage.
, (reentrant
program). , Windows WndProc
, DefWindowProc WndProc 
.
 , 
.
, ,
Hello1. ,
Windows WM_SYSCOMMAND
WndProc.
DefWindowProc. DefWindowProc ,
WM_CLOSE . 
DestroyWindow.
, DefWindowProc ,
DestroyWindow. DestroyWindow
Windows WM_DESTROY. ,
WndProc, , PostQuitMessage, 
WM_QUIT 
. WM_QUIT WinMain,
.
.
, 
. , , 
, ,
, 
.

54

1. Hello, World!, Windows



.
,
.

SendMessage

. :
LRESULT SendMessage(
HWND hWnd,
//
UINT Msg,
//
WPARAM wParam, //
LPARAM lParam
//
);

, , .
SendMessage, Windows, ,
hWnd, .
,
Windows , SendMessage.
, ,
,
.
HWND_BROADCAST, 
,
.
wParam lParam , 
. 
MSDN ,
, WM_PAINT, WM_TIMER, WM_SETFONT 
.

SendNotifyMessage
SendNotifyMessage , SendMessage.
, , ,
SendNotifyMessage
SendMessage. 
, .
, , ,
SendNotifyMessage
, 
.

PostMessage
PostMessage . 
, SendMessage.
SendMessage, PostMessage 
, , hWnd.

Windows

55

, , 
.



, , 
 ,
.
. Hello1 
GetClientRect.
WM_SIZE.
lParam 
, . ,
WndProc:
int width, height;

WM_SIZE, 
:
case WM_SIZE:
width = LOWORD(lParam);
height = HIWORD(lParam);
return 0;

LOWORD HIWORD ,
Windows; ,
32 .
GetClientRect
WM_PAINT :
rect.left = 0;
rect.top = 0;
rect.right = width;
rect.bottom = height;

, 
.
, WndProc 
.
. width height
(static), .

switch, static!
.


Win32 API
. ,

56

1. Hello, World!, Windows

hInstance WinMain
.
hInstance WinMain,
, , 
hInstance? .
(, C++)

HINSTANCE hInst;

WinMain hInstance. ,
.
hInst .
GetClassLong:
hInst = (HINSTANCE)GetClassLong(hWnd, GCL_HMODULE);

GetModuleHandle:
hInst = GetModuleHandle(NULL);



, 
, .
Windows , 
,
 ,
. 
.
. .
. , 
(, Play) 
:
void OnPlay() {
while (!fReadData.eof()) {
fReadData.read(buf, 512);
DoSomething();
// -
}
}

fReadData ifstream. while


fReadData 512
DoSomething. ,
5 , DoSomething 10 .
5335040 / 512 = 10420 , OnPlay
105 .
.
, 
. 
, Windows ,
. Win32 API

Windows

57

PeekMessage.
GetMessage:
BOOL PeekMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);

//
//
//
//
//

, 
. ,
, .
wRemoveMsg :
 PM_NOREMOVE ;
PM_REMOVE .
, OnPlay, PeekMessage,
:


void OnPlay(HWND hWnd) {


MSG message;
while (!fReadData.eof()) {
fReadData.read(buf, 512);
//
if (PeekMessage(&message, hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
DoSomething();

// -

}
}

PeekMessage , 
, .
ProgressBar,
8.

Spy++
, 
Windows . 
Visual Studio 6 
Spy++.
:
ToolsSpy++.
Spy++ 3.

58

2. GDI

GDI
.
,
,

(graphics device interface (GDI)) 


Win32 API, 
, . Windows
.
GDI, GDI
, 
(. 2.1). GDI gdi32.dll, 
.
Windows, 
.

. 2.1. , GDI

59


GDI
.
(device context) , 

, , .
:
 (pen) .


(brush) .

(bitmap) .

(palette) .

(font) .

(region) .
( 
), 
. ,
Windows 
.
GDI, , 
.
,
GDI. GDI 
, 
. 
.
Hello1 DrawText,
, 
, ,
, 
. , , , 
, , 
.
, 
GDI, .



Win32 API :
 ;


( );

60

2. GDI

, .
, WM_PAINT 
Hello1 ( 1). WM_PAINT ,
.
, , 
Windows , ,
, 
.

Windows.
Windows 
. , ,
, . 
,
.
, 
1.
Win32 GDI.
(update region), , , 
(invalid region) ,
.
(visible region) , 
. ,
, ,
, .
(clipping region) , 
. 
BeginPaint, 
.

SetWindowRgn, SelectClipPath SelectClipRgn.
CreateWindow
WS_CLIPCHILDREN WS_CLIPSIBLINGS,
,
. 
.



. . Windows 
, ( ) 
.
1


Windows [6].

61


WM_PAINT. 
BeginPaint, :
HDC BeginPaint(
HWND hwnd,
LPPAINTSTRUCT lPaint
);

//
// PAINTSTRUCT


.
PAINTSTRUCT, 
:
typedef struct tagPAINTSTRUCT {
HDC hdc;
//
BOOL fErase; //
RECT rcPaint; //
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT;

.
rcPaint RECT
.
,
InvalidateRect. 
.
fErase , Windows 
. fErase TRUE, ()
. InvalidateRect
InvalidateRgn,
.
, BeginPaint
WM_ERASEBKGND. ,
.
DefWindowProc,
, hbrBackground .
, BeginPaint NULL,
, , .
WM_PAINT ,
.
BeginPaint
WM_NCPAINT. 
,
. ,
DefWindowProc.
WM_PAINT :
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
[ GDI ]
EndPaint(hWnd, &ps);
return 0;

62

2. GDI


EndPaint, .

WM_PAINT .



WM_ PAINT, . , , 
, (,
GetTextMetrics),
WM_PAINT. 
GetDC:
hdc = GetDC(hWnd);

GetWindowDC:
hdc = GetWindowDC(hWnd);


hWnd, . hWnd
NULL, 
.
GDI 
ReleaseDC, :
hDC = GetDC(hWnd);
[ GDI ]
ReleaseDC(hWnd, hDC);

, , ,
BeginPaint, , GetDC, 
, . ,
,
, .
BeginPaint, GetDC 
.

, 
, , . 


WM_PAINT. , 
,
WM_PAINT.
. Win32
API , 
1.
1

,
16 Windows 
32 .

63


, BeginPaint, GetDC, GetWindowDC, (common),
(private) ,
( style WNDCLASS).

,
. 
, 
, .
Windows
. 
. 
.
, 
, .

CS_OWNDC style
WNDCLASS . 

.
,
. 
, 
.

, 
(CAD), , 
.

WM_PAINT
 , WM_PAINT.
,
. , 
:
 ;



, ;

.
,
WM_PAINT , InvalidateRect, InvalidateRgn
UpdateWindow.
UpdateWindow WM_PAINT 
, .
WM_PAINT 
,


64

2. GDI

Windows. , 
, , ,
. 
, WM_PAINT. ,
: ,
.

InvalidateRect InvalidateRgn
 WM_PAINT
,
InvalidateRect InvalidateRgn.
InvalidateRect :
BOOL IvalidateRect(HWND hWnd, CONST RECT* lpRect, BOOL bErase);


:
hWnd , .
NULL, 
, WM_ERASEBKGND WM_NCPAINT 
.
lpRect RECT, 
, .
NULL,
.

bErase , , .
TRUE, ,
BeginPaint. FALSE, .
. , 
. TRUE,
FALSE,
.  , 
. , 
rcUpdate, 
, NULL.
InvalidateRgn :


BOOL InvalidateRgn(HWND hWnd, HRGN hRgn, BOOL bErase);

, , , 
. hRgn ,
.
CreateRectRgn, CreatePolygonRgn ,
.
, InvalidateRect, InvalidateRgn 
, .
, hWnd WM_PAINT.


 ,
WM_PAINT DefWindowProc. 
:

65

case WM_PAINT:
return 0; // !!!

, , , Windows
WM_PAINT . 
BeginPaint, 
. Windows WM_PAINT.
, .



, CreateDC.
, , , 
. 
, 
. ,
DeleteDC.

( )

, . 
,
.
, . 
( ) 
.
, :
HDC CreateCompatibleDC (HDC hdc);

hdc 
, . 
NULL, , 
.
, 
.
, .
, 
. 
, (bitmap)
. SelectObject
CreateCompatibleBitmap.

: , ,
.
, 
, DeleteDC.
3.

66

2. GDI


, 
, .

GDI. 
GDI .
,
.
,
,
, 
, 
.

3.



.
, , 
, ,
GDI.
CreateIC,
:
HDC CreateIC(
LPCTSTR lpszDriver,
LPCTSTR lpszDevice,
LPCTSTR lpszOutput,
CONST DEVMODE* lpDvm
);

//
//
//
//




DEVMODE

Win32 
NULL.
DEVMODE, 
.
, 
, DeleteDC.


,
. 
. 
(x, y). x , y
. .

67


(screen coordinates),
. RECT, 
.
(window coordinates),
(client coordinates) (. . 1.3).
Win32 GDI, 
,
MSDN. 
.



, , , 
.
.
Win32 GDI 
, , 
, .
 (world space) 
, .


(page space)
, 
, .
.

(device space)
. ,

.

(physical device space)


. 
.

, SetWorldTransform.

. . 2.2 
, SetWorldTransform.


. 2.2.

68

2. GDI



. .
X , Y .
227 227 .

1.
. , GetWindowRect 
. 
, WM_NCMOUSEMOVE. 

.
, , 
. , 
, . 

GetDeviceCap.


(device coordinates) 
. 
.
, CreateDC, CreateIC Create
CompatibleDC, 
.
, ( 
GetDC, GetWindowDC BeginPaint), 
.
, 
(0, 0), X , Y
. , 

GetDCOrgEx.
,
, 

( ). Win32 API
:
BOOL ClientToScreen(HWND hWnd, LPOINT lpPoint);
BOOL ScreenToClient(HWND hWnd, LPOINT lpPoint);


.
, , WM_MOUSEMOVE WM_ LBUTTON DOWN.
1

. , .

69




 . 
, 
.
, Win32
GDI 
, .
, .
Win32 API 
. , 
16 Windows 
Win32 Windows 95/98. ,
, Windows NT/2000.
Windows 
.

:
 (window);
(viewport).
,
, 
.

.

. , 
, .
.

.
(window) 
:
 xWO (xorigin).


yWO (yorigin).

xWE (xextent).

yWE (yextent).
(viewport) 
:
 xVO (xorigin).


yVO (yorigin).

xVE (xextent).

yVE (yextent).

70

2. GDI

(x, y) (x', y')


:
x' = (x xWO) xVE / xWE + xVO;
y' = (y yWO) yVE / yWE + yVO.

.
 . 
(0, 0, 1, 1). x' = x, y' = y,
.


. (0, 0, 1, 1), 
(dx, dy, 1, 1). x' = x + dx, y' = y + dy. 

(dx, dy).

. (0, 0, 1, 1), 
(0, 0, mx, my). x' = x mx, y' = y my.

(mx, my).

. (0, 0, w, h),
(w, h, w, h). x' = w x, y' = h y.


. 
,
.

.
Win32 API
:


BOOL SetWindowOrgEx (
HDC hdc,
//
int X,
//
int Y,
//
LPPOINT lpPoint //
//
);
BOOL SetWindowExtEx (
HDC hdc,
//
int nXExtent,
//
int nYExtent,
//
LPSIZE lpSize
//
//
);


x-
y-
POINT


X
Y
SIZE

, , 
. , 
. 
:
BOOL SetViewportOrgEx (
HDC hdc,
//

71


int X,
// X-
int Y,
// Y-
LPPOINT lpPoint //
);
BOOL SetViewportExtEx
HDC hdc,
//
int nXExtent,
//
int nYExtent,
//
LPSIZE lpSize
//
);

(

X
Y


NULL, .
SetWindowOrgEx SetViewportOrgEx 
. ,
(0, 0) 1. 
, , 
(0, 0) . , 
! ,
.

2.3.
Win32 API
, (mapping modes).

. 

. ,
,
.
:
int SetMapMode (HDC hDC, int iMapMode);

iMapMode
, . 2.1.
2.1.

MM_TEXT

MM_LOMETRIC

0,1

MM_HIMETRIC

0,01

MM_LOENGLISH

0,01

MM_HIENGLISH

0,001

MM_TWIPS

1 / 1440

MM_ISOTROPIC

(x == y)

MM_ANISOTROPIC

(x != y)

, (0, 0)
.

72

2. GDI

SetMapMode , 
MM_TEXT.
, 

.
, , , , 
. ,
SetPixel 
1 . 
CreatePen nWidth . 
.

( 2.3).


,
Win16 GDI API:
 , 
.


API. , 
Y. ,
X , .

.
, 
. , 
GDI .
Windows NT/2000 
. 
 32 , 
.



, Windows NT/2000, 
. 
, .
, 
2 3. Win32 API
XFORM:
typedef struct _XFORM {
FLOAT eM11;
FLOAT eM12;
FLOAT eM21;
FLOAT eM22;
FLOAT eDx;
FLOAT eDy;
} XFORM;

73

, ,
(x, y) (x', y') :
x' = eM11 x + eM21 y + eDx;
y' = eM12 x + eM22 y + eDy.


:
. (1, 0, 0, 1, 0, 0).
x' = x, y' = y.

. (1, 0, 0, 1, dx, dy).


x' = x + dx, y' = y + dy.

. (mx, 0, 0, my, 0, 0). 


x' = mx x, y' = my y.

. (1, 0, 0, 1, 0, 0).
x' = x, y' = y.

. (cos(), sin(), sin(), cos(), 0, 0).


x' = cos() x sin() y y' = sin() x + cos() y.

. (1, s, 0, 1, 0, 0)1. 
x' = x + s y y' = y.

.

.

Win32 API
(Windows NT/2000)

. 16
GDI. , 
.

SetGraphicsMode
(hDC, GM_ADVANCED).

, . 
, 
SetGraphicsMode(hDC, GM_COMPATIBLE).
, SaveDC RestoreDC.

. 
:
BOOL SetWorldTransform(HDC hDC, CONST XFORM* lpXform);
BOOL ModifyWorldTransform(HDC hDC, CONST XFORM* lpXform, DWORD iMode);

SetWorldTransform 
, XFORM.
1

x , y.

74

2. GDI

ModifyWorldTransform iMode
:
 MTW_IDENTIFY ;


MTW_LEFTMULTIPLY
lpXform ;

MTW_RIGHTMULTIPLY 
lpXform .

GetWorldTransform.
12.





. GetDeviceCaps, 

, :
int GetDeviceCaps(HDC hdc, int nIndex);

nIndex . 2.21.
2.2. nIndex

DRIVERVERSION

TECHNOLOGY

(DT_PLOTTER, DT_RASDISPLAY, DT_RASPRINTER


)

HORZSIZE

VERTSIZE

HORZRES

VERTRES

LOGPIXELSX

LOGPIXELSY

BITSPIXEL

PLANES

NUMBRUSHES

NUMPENS

NUMFONTS

NUMCOLORS

CLIPCAPS

SIZEPALETTE

. MSDN.

75

COLORRES

PHYSICALWIDTH

( )

PHYSICALHEIGHT

( )

PHYSICALOFFSETX

PHYSICALOFFSETY

RASTERCAPS

.
: RC_BITBLT
; RC_BITMAP64
,
64 ; RC_DEVBITS ; RC_NONE
; RC_PALETTE ,
; RC_SCALING ;
RC_STRETCHBLT StretchBlt;
RC_STRETCHDIB StretchDiBIts

CURVECAPS

.
: CC_CHORD
; CC_CIRCLES
; CC_ELLIPSWS ;
CC_INTERIORS ;
CC_NONE

LINECAPS

.
: LC_STYLED
; LC_WIDE
; LC_POLYLINE
; LC_INTERIORS ;
LC_NONE

POLYGONALCAPS

.
:
PC_STYLED ;
PC_WIDE ; PC_POLYGON
; PC_INTERIORS
; PC_NONE

TEXTCAPS

.
: TC_CR_90
90; TC_CR_ANY
; TC_EA_DOUBLE
; TC_IA_ABLE
; TC_RA_ABLE
; TC_VA_ABLE

, 1
, 
, WM_CREATE:
HDC hdc = GetDC(hwnd);
int logPixelY = GetDeviceCaps(hdc, LOGPIXELY);
// logPixelY ...
ReleaseDC(hwnd, hdc);

76

2. GDI

.

. 
, .
,
.
, , 
, , , ,
. 0 ( 
) 255 ( ). 
.
, 
RGB, : Red (
), Green ( ) Blue ( 
).
. 
, CMYK,
, , 
.
, 
.
HLS.

HLS
HLS (Hue),
(Lightness) (Saturation).
0 360. 
, 60 , 120 , 180 , 240
, 300 .
. 
. , 
, .
, , 
. ,
.
.

RGB
Windows RGB 
, .

COLORREF, .
: 0 RGB, 1 PALETTEINDEX, 2 PALETTERGB.
RGB . 2.3.

77

. 2.3. COLORREF, RGB

(0) .
(255) .
RGB, 224
, 16,7 .
Win32 API , 
RGB 32 COLORREF , ,
COLORREF RGB.
, wingdi.h, 
(inline) :
COLORREF RGB(BYTE byRed, BYTE byGreen, BYTE byBlue);
BYTE GetRValue(COLORREF rgb);
BYTE GetGValue(COLORREF rgb);
BYTE GetBValue(COLORREF rgb);

RGB 
, :
const
const
const
const
const
const
const
const

COLORREF
COLORREF
COLORREF
COLORREF
COLORREF
COLORREF
COLORREF
COLORREF

black
red
green
blue
yellow
magenta
cyan
white

=
=
=
=
=
=
=
=

RGB(0, 0, 0);
RGB(255, 0, 0);
RGB(0, 255, 0);
RGB(0, 0, 255);
RGB(255, 255, 0);
RGB(255, 0, 255);
RGB(0, 255, 255);
RGB(255, 255, 255);

//
//
//
//
//
//
//
//

RGB(0x0, 0x0, 0x0);


RGB(0xFF, 0x0, 0x0);
RGB(0x0, 0xFF, 0x0);
RGB(0x0, 0x0, 0xFF);
RGB(0xFF, 0xFF, 0x0);
RGB(0xFF, 0x0, 0xFF);
RGB(0x0, 0xFF, 0xFF);
RGB(0xFF, 0xFF, 0xFF);


, 16 777 216
RGB COLORREF. , 
, 256 .
.
3. 
COLORREF, .
Win32 API PALETTEINDEX PALETTERGB, 
COLORREF. 
. 2.4.

. 2.4. COLORREF, PALETTEINDEX PALETTERGB

78

2. GDI


:
COLORREF GetPixel(HDC hdc, int X, int Y);
BOOL SetPixelV(HDC hdc, int X, int Y, COLORREF color);
COLORREF SetPixel(HDC hdc, int X, int Y, COLORREF color);

X Y . 
color, , 
RGB1.
GetPixel 
.
SetPixelV SetPixel 
, . 
, , . 
,
 , 1.
, , SetPixelV SetPixel 
. 
NtGdiSetPixel, , ,
:
 ;


COLORREF ;

DrvBitBlt;

.
[6] ,
1000 . 
, GetPixel 6000
.
, ,
. 
12.


,

,
, 
.

, RGB
PALETTERGB.

79

.

. SetPixel(hDC, x,
y, color), x y color.
SetPixel . 
, , , 
.
Windows
. 
S ( ) D ( 
).
(, SetPixel)
f(D, S), 
:
D = f(D, S).
, , GDI 
. 
, , , 
. Windows ,
, (raster operation
(ROP)). , 
(binary raster operation (ROP2)).
MSDN
P, 
:
D = f(D, P).
, . 2.3, 
,
SetPixel.
2.3.
P:
D:

1100
1010

ROP2

0000
0001
0010

D=0
D = ~(D | P)
D = D & ~P

R2_BLACK
R2_NOTMERGEPEN
R2_MASKNOTPEN

0011
0100

D = ~P
D = P & ~D

R2_NOTCOPYPEN
R2_MASKPENNOT

0101
0110

D = ~D
D=D^P

R2_NOT
R2_XORPEN

0111
1000

D = ~(D & P)
D=D&P

R2_NOTMASKPEN
R2_MASKPEN

0 ( )
R2_MERGEPEN







R2_MASKPEN

80

2. GDI

2.3 ()
P:
D:

1100
1010

ROP2

1001
1010
1011

D = ~(D ^ P)
D=D
D = D | ~P

R2_NOTXORPEN
R2_NOP
R2_MERGENOTPEN

1100
1101

D=P
D = P | ~D

R2_COPYPEN
R2_MERGEPENNOT

1110
1111

D=P|D
D=1

R2_MERGEPEN
R2_WHITE

R2_XORPEN



( )


1 ( )

GDI ,
(drawing mode). ROP2.
SetROP2:
int SetROP2(HDC hdc, int fnDrawMode);

fnDrawMode ROP2,
. 2.3. .
GetROP2.
R2_COPYPEN, 
.
,
RGB, 
RGB.
,
. , 
(RGB(0xFF, 0, 0)) R2_XORPEN, 
(RGB(0xFF, 0xFF, 0xFF))
(cyan), 
RGB(0, 0xFF, 0xFF). ,
, 
. 
R2_XORPEN .

, .
.
R2_BLACK ,
R2_WHITE . R2_NOTCOPYPEN 
. R2_NOP ,
.
R2_XORPEN R2_NOTXORPEN 

. , ,
.
, 
.
R2_XORPEN R2_NOTXORPEN
,

81

. 
.



GDI : 
(foreground) (background). , 
, 1 , ,
2 .
,
. 
, 
.

. (background color) 
,
SetBkColor.
. 
,
, , .
. 
Hello1 .
.
,
, 
(background mix mode)3.
OPAQUE4.
, Windows ( background
color) . ,
. 
SetBkMode, TRANSPARENT5.
, , 
GetBkMode.


, GDI , 
. 
1

(glyph) .

82

2. GDI

, , , , . 

:
1. .
2. .
3. , .
4. , .
5. .
GDI Create,
.

SelectObject ( SelectPalette).
SelectObject :
HGDIOBJ SelectObject(
HDC hdc,
//
HGDIOBJ hgdiobj
// GDI-
);

hgdiobj
hdc.
.

( 3)
( 4).
, , Delete
Object.
, GDI
Create. 
() , 
(, , . .) , 
GetStockObject.

DeleteObject.
.


,
SetPixel x y. ,
, , ,
.

, 
, . Win32 GDI 
.

83


Windows , 
.
1 .
.


.
POINT. 
(0, 0). , 
MoveToEx:
BOOL MoveToEx(
HDC hdc,
int X,
int Y,
LPPOINT lpPoint
);

//
//
//
//


x-
y-

,
NULL.
.
,

GetCurrentPositionEx(hDC, &pt);

pt POINT.


LineTo:
BOOL LineTo(
HDC hdc,
//
int xEnd, // x-
int yEnd
// y-
);

, ,
, (xEnd, yEnd), . 
. 
, ,
(xEnd, yEnd).
,
. , , 
, ,
, :
{
POINT pt[5] = {{100,100}, {200,100}, {200,200},
{100,200}, {100,100}};
MoveToEx(hDC, pt[0].x, pt[0].y, NULL);
for (int i = 0; i < 5; ++i)
LineTo(hDC, pt[i].x, pt[i].y);
}

84

2. GDI

Hello2 ( 1)
DrawText, , . 

switch.

( )

Polyline:
BOOL Polyline(HDC hdc, CONST POINT* lppt, int cPoints);

,
.
:
{
POINT pt[5] = {{100,100}, {200,100}, {200,200},
{100,200}, {100,100}};
Polyline(hDC, pt, 5);
}

, ,
Polyline .
PolylineTo 
:
BOOL PolylineTo(HDC hdc, CONST POINT* lppt, DWORD cPoints);



. ,
Polyline :
MoveToEx(hDC, pt[0].x, pt[0].y, NULL);
PolylineTo(hDC, pt + 1, 4);

PolyPolyline
. :
BOOL PolyPolyline(
HDC hdc,
CONST POINT* lppt,
CONST DWORD* lpPolyPoints,
DWORD cCount
);

//
//
//
//

Windows .
. 
. 
(xLeft, yTop) (xRight, yBottom), 
(x0, y0), x0 = xLeft + (xRight xLeft)/2, y0 = yTop + (yBottom yTop)/2.
Arc, ArcTo AngleArc.
,
Arc:

85

BOOL Arc(HDC hdc, int xLeft, int yTop, int xRight, int yBottom,
int xStart, int yStart, int xEnd, int yEnd);


. ,
(xStart, yStart)
(xEnd, yEnd). , 
(xStart, yStart). 
, 
(xEnd, yEnd). .
Windows 95/98 . Windows NT/2000

, GetArcDirection 
SetArcDirection.
SetArcDirection, :
AD_COUNTERCLOCKWISE, 
, AD_CLOCKWISE, .
AD_ COUNTERCLOCKWISE.
. 2.5 ,
Arc(hDC, 100, 100, 400, 300, 350, 50, 50, 300);

. 2.5. , Arc (
)

Arc
SetArcDirection(hDC, AD_CLOCKWISE);

Arc , . 2.6.
Arc .
ArcTo Arc , 
, 
.
.
AngleArc, Windows NT/2000,
,
:
BOOL AngleArc(HDC hdc, int X, int Y, DWORD radius, FLOAT startAngle,
FLOAT sweepAngle);

86

2. GDI

. 2.6. , Arc ( )

X Y , radius . , 
, . , 
.
startAngle ,
sweepAngle . ,
, . 
sweepAngle , 
.
AngleArc, ArcTo,
, 
.


, , Windows 
, . 
( ) , 
p1, p2, p3 p4. p1
, p4 . p2, p3 
, 
, , p1 p4. 
2.7.

. 2.7.

87

.
(P.Bezier)
. ,
.
Win32 GDI ,
:
BOOL PolyBezier(HDC hdc, CONST POINT* lppt, DWORD cPoints);
BOOL PolyBezierTo(HDC hdc, CONST POINT* lppt, DWORD cCount);

n PolyBezier lppt,
3n + 1 , cPoints
3n + 1. , lppt[0], lppt[1], lppt[2], lppt[3], 
. lppt[3]
. . PolyBezier
.
PolyBezier, PolyBezierTo 3n lppt,
cCount 3n. ,
, , , 
. 
, PolyBezier. 
lppt.

[6].

,
(pen), .
, BLACK_PEN.
1
. , 
, , ,
!
Win32 GDI
.
. 
,
.
, , 
.
GDI,
. 
.
GDI HGDIOBJ; 
HPEN (handle to a pen). 
, HGDIOBJ Windows
void, HPEN

88

2. GDI

. , HPEN
HGDIOBJ, HGDIOBJ HPEN 
.
, hPen :
HPEN hPen;

. 
.
, GDI, 
. , , 
DeleteObject1.


Win32 GDI ,
. 2.4.
2.4.

BLACK_PEN

WHITE_PEN

NULL_PEN

( )

DC_PEN

DC 1 .
.

SetDCPenColor

Windows 2000


GetStockObject, , 
:
hPen = (HPEN)GetStockObject(WHITE_PEN);

GetStockObject HGDIOBJ, 
.
, 
:
SelectObject(hDC, hPen);

, , WHITE_PEN
, 
.
hPen,
GetStockObject SelectObject :
SelectObject(hDC, GetStockObject(WHITE_PEN));

89



, , :
HPEN hOldPen = (HPEN)SelectObject(hDC, GetStockObject(WHITE_PEN));
// ... WHITE_PEN
//
SelectObject(hDC, hOldPen);

DC, GetStockObject(DC_PEN),
GDI. GDI 
. , ,
. GDI,
.
.
DC ,
.
SetDCPenColor, :
COLORREF SetDCPenColor(HDC hdc, COLORREF crColor);

crColor DC. 
DC.
,
:
{
HGDIOBJ hOld = SelectObject(hDC, GetStockObject(DC_PEN));
for (int i = 0; i < 256; ++i) {
SetDCPenColor(hDC, RGB(255-i, 128, i));
MoveToEx(hDC, 10, i+10, NULL);
LineTo(hDC, 266, i+10);
}
SelectObject(hDC, hOld);
}

Hello2 ( 1)
DrawText, 1.
, 2, .
, DC_PEN . 
, (
#include <windows.h>) :
#define

_WIN32_WINNT

0x500


. 
,
1


switch.

Visual C++ 6.0.

90

2. GDI

. CreatePen
CreatePenIndirect.
CreatePen :
HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);

, 
.
. 2.5.
2.5.

PS_SOLID

PS_DASH

nWidth <= 1

PS_DOT

nWidth <= 1

PS_DASHDOT

nWidth <= 1

PS_DASHDOTDOT

nWidth <= 1

PS_NULL

PS_INSIDEFRAME

nWidth > 1

. 2.8 , . 
1 .

. 2.8.

CreatePen 
. , 
MM_TEXT,
.
, 
,
, .
,
. , 
. 
, .
nWidth . 
1 .
(PS_DASH, PS_DOT, PS_DASHDOT,
PS_DASHDOTDOT) , Windows 
PS_SOLID. , () 
1 . ,
.

91

CreatePen
COLORREF. RGB,
PALETTERGB1. ,
, 24 RGB
, , 
. ( PALETTERGB) , 
, , ,
256 . Windows 
RGB .
, ,
, 
, . , 
PS_INSIDEFRAME, , 
. PS_INSIDEFRAME
. ,
nWidth , . ,
. 2.5 2.6 PS_INSIDEFRAME.
nWidth , PS_INSIDEFRAME 
PS_SOLID.
CreatePen. 
() 5 
:
hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));

,
. , nWidth
.
CreatePenIndirect:
HPEN CreatePenIndirect(CONST LOGPEN* lplgpn);

LOGPEN:
typedef struct tagLOGPEN
UINT
style; //
POINT
width; //
COLORREF color; //
} LOGPEN;

width POINT, Windows 


width.x width.y.
, LOGPEN, :
LOGPEN logpen;

, :
logpen.style = PS_SOLID;
logpen.width.x = 10;
logpen.color = RGB(255, 0, 0);

CreatePenIndirect:
hPen = CreatePenIndirect(&logpen);

. . .

92

2. GDI

, CreatePenIndirect, 
, , CreatePen.
, CreatePen CreatePenIndirect
. ,
, SelectObject.
.
, : 2,
5 .
:
static HPEN hPen1, hPen2, hPen3;

WM_CREATE:
hPen1 = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
hPen2 = CreatePen(PS_SOLID, 5, RGB(0, 255, 0));
hPen3 = CreatePen(PS_DASH, 1, RGB(0, 0, 255));

WM_PAINT 
:
SelectObject(hDC, hPen1);
// ...
SelectObject(hDC, hPen2);
// ...

WM_DESTROY
:
DeleteObject(hPen1);
DeleteObject(hPen2);
DeleteObject(hPen3);

. . , 
WM_PAINT 
EndPaint .
, ,
CreatePen SelectObject :
SelectObject(hDC, CreatePen(PS_DOT, 0, RGB(255, 255, 0)));


. , .
, ?
SelectObject ,
. ,
BLACK_PEN ,
SelectObject:
DeleteObject(SelectObject(hDC, GetStockObject(BLACK_PEN)));

.
, SelectObject:
hPen = SelectObject(hDC, CreatePen(PS_DOT, 0, RGB(255, 255, 0)));

SelectObject
, hPen BLACK_PEN.

:
DeleteObject(SelectObject(hDC, hPen));

93


, ,
. , 1 
, , 
.
Win32 API
ExtCreatePen, :
HPEN ExtCreatePen(
DWORD dwPenStyle,
DWORD dwWidth,
CONST LOGBRUSH* lplb,
DWORD dwStyleCount,
CONST DWORD* lpStyle
);

//
//
//
//
//


lpStyle
,

dwPenStyle ,
, , 
. . 2.62.9.
2.6.

PS_COSMETIC

. 1

PS_GEOMETRIC

. 2.6 , 
.
2.7.

PS_ALTERNATE

Windows NT/2000

PS_SOLID

PS_DASH

Windows 95:
. Windows 98:

PS_DOT

Windows 95/98:

PS_DASHDOT

Windows 95:
. Windows 98:

PS_DASHDOTDOT

Windows 95:
. Windows 98:

PS_NULL

PS_INSIDEFRAME

PS_USERSTYLE

dwStyleCount lpStyle

Windows NT/2000

94

2. GDI

, PS_INSIDEFRAME, . 
.
2.8. ,

PS_ENDCAP_ROUND

PS_ENDCAP_SQUARE

PS_ENDCAP_FLAT

2.9. ,

PS_JOIN_BEVEL

PS_JOIN_MITER

PS_JOIN_ROUND


1 . 
Windows PS_SOLID.
PS_DASH, PS_DOT, PS_DASHDOT PS_DASHDOTDOT 
, . , 
, ,
OPAQUE.
PS_ALTERNATE
, 1 
1 .
PS_USERSTYLE 
: dwStyleCount lpStyle. 
, 
, . .
.


, , 
, , .
. 
, , 3 
, MM_TEXT
1 . 
, , .

.
, 
, . 2.9.
, 
, PS_ENDCAP_ROUND. ,
ExtCreatePen

95

. 2.8. . 2.10 , Z,
. 
LineTo. 
, . , 
, .

. 2.9. 10

. 2.10.

, LineTo 
R2_XORPEN, 
, . 2.11, .
Z , Polyline ( . 2.11
), . 
. 
lbStyle LOGBRUSH
BS_HATCHED, lbHatch HS_DIAGCROSS1.

. 2.11. R2_XORPEN

Polyline GDI,
. 
, .
, 
. 2.9.
PS_JOIN_ROUND. . 2.12 
. 
Polyline.
1

96

2. GDI

. 2.12. Polyline

.
, ,
Windows ,
. ,
, , (
) .
, .
, , 
, . 
, ,
.

8 8 ,
. Windows 
(dithering) , 
, . 
, ,
64 . 
,
.
Win32 GDI 
. ,
. 
.
, .
.

97

HBRUSH (handle to
a brush), :
HBRUSH hBrush;

. 
. ,
SelectObject,
. 
,
, DeleteObject.

. 
.


, GDI, . 2.10.
2.10.

BLACK_BRUSH
DKGRAY_BRUSH
DC_BRUSH
GRAY_BRUSH
HOLLOW_BRUSH
LTGRAY_BRUSH
NULL_BRUSH


-
DC ; ;
SetDCBrushColor

( )
-
, HOLLOW_BRUSH

WHITE_BRUSH

, , , 8 8
. DC, Windows 2000,
GDI. DC, DC
. 
SetDCBrushColor.
,
GetStockObject , . 2.10, :
hBrush = (HBRUSH) GetStockObject(GRAY_BRUSH);


,
. Windows
, : ,
.


CreateSolidBrush:
HBRUSH CreateSolidBrush(COLORREF crColor);

98

2. GDI

crColor
COLORREF. RGB PALETTERGB1.
,
, 24 RGB. 
.
, .
Windows PALETTERGB
. ,
,
(dithering).
3 6.


CreateHatchBrush:
HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);

fnStyle, ,
HS_HORIZONTAL, HS_VERTICAL, HS_BDIAGONAL, HS_FDIAGONAL, HS_CROSS HS_DIAGCROSS.
. 2.13 ,
64 64 ( ).
, 
. 8 8 
.

. 2.13.

. . 2.13 
. 
clrref,
, 
SetBkColor.
, OPAQUE.
GDI 
SetBrushOrgEx:
BOOL SetBrushOrgEx(HDC hdc, int nXOrg, int nYOrg, LPPOINT lppt);

(nXOrg, nYOrg), , 
.
. lppt 
POINT, .
(0, 0).
1

. . .

99

, , 1 
, . ,

,

SetBrushOrgEx(hDC, xLeft + 1, yTop + 1, NULL);

xLeft yTop .
, 
.


( ) CreatePatternBrush:
HBRUSH CreatePatternBrush(HBITMAP hbmp);

hbmp GDI.
GDI (bitmap), 
(DDB)1, , 

.
.
MS Paint 32 32 ,
, . 2.14.
Star.bmp.

. 2.14. , MS Paint

Hello2, ,
:
{
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "Star.bmp", IMAGE_BITMAP, 0,
0, LR_LOADFROMFILE);
HBRUSH hBrush = CreatePatternBrush(hBmp);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
Rectangle(hDC, 32, 32, 288, 160);
DeleteObject(SelectObject(hDC, hOldBrush));
}

LoadImage 
(DIB)2 Star.bmp,
GDI hBmp. 
CreatePatternBrush, . hBrush
1

3.

  3.

100

2. GDI


, Rectangle1.
Star.bmp, 
Hello2. 
, . 2.15.

. 2.15.

Windows 95/98 
. 8 8 
. 8 8
.
11.

LOGBRUSH CreateBrushIndirect
Win32 GDI CreateBrushIndirect,
:
HBRUSH CreateBrushIndirect(CONST LOGBRUSH* lplb);

lplb LOGBRUSH, 
:
typedef struct tagLOGBRUSH {
UINT
lbStyle;
COLORREF lbColor;
LONG
lbHatch;
} LOGBRUSH;

lbStyle ,
. 2.11.
2.11. lbStyle

BS_SOLID
BS_HATCHED
BS_HOLLOW
BS_NULL
BS_PATTERN



( )
, BS_HOLLOW
,

, BS_PATTERN
, -
(DIB device-independent bitmap),
lbHatch

BS_PATTERN8X8
BS_DIBPATTERN

, , .

101

BS_DIBPATTERN8X8

, BS_DIBPATTERN

BS_DIBPATTERNPT

, -
(DIB). lbHatch DIB

lbColor .
lbStyle . 2.12.
2.12. lbColor
lbStyle

lbColor

BS_HOLLOW BS_PATTERN

BS_HATCHED BS_SOLID

COLORREF

BS_DIBPATTERN BS_DIBPATTERNPT

lbColor
DIB_PAL_COLORS DIB_RGB_COLORS.
, bmiColors,
BITMAPINFO, 16-
, ,
bmiColors RGB-

lbHatch . 
lbStyle . 2.13.
2.13. lbHatch
lbStyle

lbHatch

BS_SOLID BS_HOLLOW

BS_PATTERN

GDI (bitmap)

BS_HATCHED

HS_HORIZONTAL, HS_VERTICAL,
HS_BDIAGONAL, HS_FDIAGONAL, HS_CROSS, HS_DIAGCROSS

BS_DIBPATTERN

DIB-

BS_DIBPATTERNPT

DIB-

LOGBRUSH ,
. , . 2.11 
.


, Windows
, , , 
.
.

Windows 
.

102

2. GDI

, ,
. Win32 API

,
.


1, 
:
typedef
LONG
LONG
LONG
LONG
} RECT;

struct tagRECT {
left;
top;
right;
bottom;

(left, top)
(right, bottom) .
, :
RECT rect;

rect
:
rect.left = x_left;
rect.top = y_top;
rect.right = x_right;
rect.bottom = y_bottom;

SetRect, :
BOOL SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom);

:
SetRect(&rect, x_left, y_top, x_right, y_bottom);

Win32 API
RECT. . 2.14 .
2.14. RECT

SetRect(&rect, xLeft, yTop, xRight, yBottom);

OffsetRect(&rect, dX, dY);

X
dX Y dY

InflateRect(&rect, dX, dY);

SetRectEmpty(&rect);

rect

CopyRect(&DestRect, &SrcRect);

IntersectRect(&DestRect, &SrcRect1, &SrcRect2);


UnionRect(&DestRect, &SrcRect1, &SrcRect2);

bEmpty = IsRectEmpty(&rect);

bInRect = PtInRect(&rect, point);

, point
rect

103


Rectangle, FillRect,
FrameRect, InvertRect DrawFocusRect.
Rectangle
Rectangle :
BOOL Rectangle(HDC hdc, int xLeft, int yTop, int xRight, int yBottom);

, . 
xLeft yTop , xRight yBottom 
. .

.
MSDN , xLeft < xRight
yTo p < yBottom, , 
,
, Windows
.
,
:
 , (GM_COMPATIBLE)
(GM_ADVANCED);


( ).
2.16 Rectangle
.


. 2.16. Rectangle

, 
, , (GRAY_BRUSH),
.
, , 
1, , 
(xRight 1, yBottom 1).
1

. .

104

2. GDI

, , .
,
,
(xRight, yBottom).
PS_NULL, 
.
,
. nWidth , 
, (nWidth 1)/2
. , 
nWidth (nWidth 1)
?

.
, 
PS_INSIDEFRAME. .
. 
, .

, .
FillRect
FillRect :
BOOL FillRect(HDC hdc, CONST RECT* lprc, HBRUSH hbr);

, RECT,
lprc. , 
hbr.

(lprc.right 1, lprc.bottom 1), 
.
:
 ,
;



.

FrameRect
FrameRect :
BOOL FrameRect(HDC hdc, CONST RECT* lprc, HBRUSH hbr);

lprc hbr. 
.
, , . 
. 
, ,
, .

105

FrameRect, 
1.
InvertRect
InvertRect :
BOOL InvertRect(HDC hdc, CONST RECT* lprc);

.
, 
. ,
, RGB .
InvertRect 
.
DrawFocusRect
DrawFocusRect :
BOOL DrawFocusRect(HDC hdc, CONST RECT* lprc);

FrameRect, 

. 
.
Win32 API,
. , DrawFocusRect 
,
. ,
DrawFocusRect.
DrawFocusRect
.

,
,

Win32 GDI ,
, 
.

Ellipse, 
:
BOOL Ellipse(HDC hdc, int xLeft, int yTop, int xRight, int yBottom);

, 
xLeft, yTop, xRight, yBottom.


Ellipse.
1

. PS_ALTERNATE .

106

2. GDI


Arc. , 
, .
Chord:
BOOL Chord(HDC hdc, int xLeft, int yTop, int xRight, int yBottom,
int xStart, int yStart, int xEnd, int yEnd);

, Arc. 
(xStart, yStart)
(xEnd, yEnd). , ,
, Arc. . 2.17 
Chord.

. 2.17. Chord

, , 
.
Pie, :
BOOL Pie(HDC hdc, int xLeft, int yTop, int xRight, int yBottom,
int xStart, int yStart, int xEnd, int yEnd);

, Arc. 
,
Arc. . 2.18 Pie.

RoundRect,
:
BOOL RoundRect(HDC hdc, int xLeft, int yTop, int xRight, int yBottom,
int roundWidth, int roundHeight);

, 
. 
Rectangle.
, , 
. 2.19.

107

. 2.18. Pie

. 2.19. , RoundRect

roundWidth roundHeight ,
RoundRect . roundWidth xRight xLeft
roundHeight yBottom yTop, RoundRect
.

. 
Polygon:
BOOL Polygon(HDC hdc, CONST POINT* lpPoints, int nCount);

Polyline.
, 
. Polyline, Polygon 
. Polygon,
Polyline, .

.
, , , ,

108

2. GDI

. 
. Win32 GDI 
: ALTERNATE WINDING.
, , 
SetPolyFillMode. 
ALTERNATE. . 2.20
.

. 2.20. , :
ALTERNATE; WINDING

ALTERNATE 
:
1. 
.
2. 
.
3. 
, .
, . 2.21.
WINDING 

:
1. 
.
2. count 
.
3. 
.
, count 
, , .
4. count , 
, .
, . 2.21.

PolyPolygon:
BOOL PolyPolygon(HDC hdc, CONST POINT* lpPoints, CONST int* lpPolyCounts,
int nCount);


. .

109


.

. 2.21.
: ALTERNATE; WINDING

, 
.
. ,
. 
.


.
, .
. , 
, , , GDI.
,
HRGN. ,
DeleteObject. 
, .


. 
:
HRGN hRgn;

:
hRgn = CreateRectRgn(xLeft, yTop, xRight, yBottom);

hRgn = CreateRectRgnIndirect(&rect);

, :
hRgn = CreateEllipticRgn(xLeft, yTop, xRight, yBottom);

hRgn = CreateEllipticRgnIndirect(&rect);

110

2. GDI


:
hRgn = CreateRoundRectRgn(xLeft, yTop, xRight, yBottom, roundWidth,
roundHeight);

Polygon:
hRgn = CreatePolygonRgn(point, iCount, iPolyFillMode);

point POINT. iCount


, iPolyFillMode ALTERNATE
WINDING.
, 
CreatePolyPolygonRgn:
hRgn = CreatePolyPolygon(point, polyCounts, iCount, iPolyFillMode);

PolyPolygon.


,
.
. 2.15 , .
2.15.

BOOL PtInRegion(HRGN hrgn, int X, int Y);

, (X, Y)
hrgn
BOOL RectInRegion(HRGN hrgn, CONST RECT *lprc); ,
lprc hrgn
BOOL EqualRgn(HRGN hRgn1, HRGN hRgn2);
, hRgn1
hRgn2
int GetRgnBox(HRGN hrgn, LPRECT lprc);
lprc

int CombineRgn(HRGN hrgnDest, HRGN hrgnSrc1,
, hrgnSrc1
HRGN hrgnSrc2, int fnCombineMode);
hrgnSrc2,
fnCombineMode.
hrgnDest
int OffsetRgn(HRGN hrgn, int nXOffset, int nYOffset); hrgn
nXOffset X nYOffset
Y
DWORD GetRegionData(HRGN hRgn,
lpRgnData
DWORD dwCount, LPRGNDATA lpRgnData);
RGNDATA ,
hRgn
HRGN ExtCreateRegion(CONST XFORM *lpXform,
RGNDATA
DWORD nCount, CONST RGNDATA *lpRgnData);
,
XFORM

.
PtInRegion 
,
. , 
, PtInRegion 
WM_MOUSEMOVE .

111

OffsetRgn 
. ,
, 
, .
CombineRgn 
, . 
, hrgnDest.
, 
, hrgnDest, , 
. fnCombineMode 
, , . 2.16.
2.16. , CombineRgn
fnCombineMode

RGN_AND

RGN_OR

RGN_XOR

RGN_DIFF

hrgnSrc1, hrgnSrc2

RGN_COPY

hrgnSrc1

, hrgnSrc1 hrgnDest
, hrgnSrc1.
CombineRgn 
.
. 2.17.
2.17. , CombineRgn

NULLREGION

SIMPLEREGION

COMPLEXREGION

ERROR

(
)


, hrgn, 
, . 2.18.

.

, . ,
GDI ( 
, ), 
. 
, .
, 

112

2. GDI

.
, ,
.
CombineRgn.
2.18.

BOOL FillRgn(HDC hdc, HRGN hrgn, HBRUSH hbr);

hbr

BOOL PaintRgn(HDC hdc, HRGN hrgn);

BOOL FrameRgn(HDC hdc, HRGN hrgn,


HBRUSH hbr, int nWidth, int nHeight);

hbr.
nWidth,

nHeight

BOOL InvertRgn(HDC hdc, HRGN hrgn);


(
InvertRect)


. , Windows 
, :
 ( ) , 
.
, InvalidateRect
InvalidateRgn.


, 
. 
.

, . 
,

. , 
, SetWindowRgn SelectClipRgn.
, 
.



SetWindowRgn .
, Windows .
:
int SetWindowRgn(
HWND hWnd,
//
HRGN hRgn,
//
BOOL bRedraw
//
);

113

,
.

.


hRgn, 
,
. 
SelectClipRgn:
SelectClipRgn(hDC, hRgn);

GDI
. SelectClipRgn hRgn
.
,
SelectClipRgn NULL:
SelectClipRgn(hDC, NULL);

, 
, . 
, 
,
, (. 12).
2.2 
12.


1
(. 1.1). DrawText. 
, , ,

, (. 2.19).
2.19. ,

SYSTEM_FONT

SelectObject

SetTextColor

SetBkColor

OPAQUE

SetBkMode

MM_TEXT

SetMapMode

, 
GDI. , 
, SetTextColor. ,

114

2. GDI

SYSTEM_FONT , 
.
, ,
.


, 

. (character set).

ASCII1. ASCII (. 2.22) 
7 ,
27 = 128 .

. 2.22. ASCII

. 2.22 
. 
.
. , N 0x4E,
01001110 78.
32 ( 0x00 0x1F) 
. ( 0x0D)2, 
( 0x0A) 3.
( 0x20), , 
, . 
( 0x7F) .
ASCII
8 , 256 . 
128 ASCII.

IBM, IBM PC
80 . 
, 
. IBM
1

American Standard Code for Information Interchange.

, , Enter.

Windows .

115

, , BIOS.
,
Microsoft Windows, , 
, 0xB0
0xDF.
IBM,
(code pages). ,
, CP437 (code page 437).

. CP866 CP437 ,
, 
. CP866 
. 2.23.

. 2.23. CP866

Microsoft Windows 
ASCII,
MSDOS, 
. ANSI1, , , 
ISO2.
ANSI , 
, 
. . 2.20.
. 2.24 Windows Latin1 ( 
1252), . 2.25 Windows Cyrillic ( 
1251).

, ,
1

ANSI American National Standards Institute.

ISO International Organization for Standardization.

116

2. GDI

, .
. , 
932 ( ), 949 ( ) 950 (
) .
2.20. ANSI

0 .. 127

128 .. 255

1250 (Windows Latin2)

ASCII

1251 (Windows Cyrillic)

ASCII

1252 (Windows Latin1)

ASCII

1253

ASCII

1254

ASCII

...

...

...

. 2.24. Windows Latin 1 (1252)

. 2.25. Windows Cyrillic (1251)

117

Win API, 
,
EnumSystemCodePages.
Regional Settings ( )
Windows.

Unicode
, , 
, , 
. 
Unicode. Unicode,
, Apple, HewlettPackard, IBM, Microsoft, Sun 
. , 
65 536 . Unicode
.
Unicode . ,
0x0000 0x007F, 
ASCII. 29 902
, , .
Windows ANSI
, Unicode. Win32 API,
, ANSI Unicode.

, ANSI, Unicode.
#define UNICODE, 
Unicode, ANSI. , 

.
:
 char TCHAR,
char* LPTSTR, const char* LPCTSTR.


TEXT,
"abcd" TEXT("abcd").

C, ,
.
, #define UNICODE, 
, :
#ifdef UNICODE
#define sprintf swprintf
#define sscanf swscanf
#define strcpy wcscpy
#define strcat wcscat
#define strlen wcslen
#endif

ANSI, 
.

118

2. GDI

, Windows, 
:
 (typeface) , 
. 
Arial, Times New Roman, Courier New.


, 
.

. Windows 
(normal) , (italic), (bold),
(underline), (strike out).
, .

. 
. . 
. i 
, m.
.

(glyph) 
. 
.
. 2.26 , ,
.


. 2.26.

Arial Times New Roman 


, Courier New . ,
Times New Roman Courier New 
, Arial .
, ,
(family). . 2.21.
2.21.

(
Windows)

Don't care

FF_DONTCARE

0x00


( )

Roman

FF_ROMAN

0x10


(), Times New Roman

Swiss

FF_SWISS

0x20

,
Arial

Modern

FF_MODERN

0x30


, Courier New

119

(
Windows)

Script

FF_SCRIPT

0x40

, Monotype
Corsiva

Decorative

FF_DECORATIVE

0x50

, Old English


Windows : GDI
(device fonts). GDI ,
.
. , 
.
GDI :
 ;


TrueType.

.
. , 
. , ,
. 
, 
, , ,
.
Windows.

, . 
. 
, ,
,
.
. , , 
.fon.
TrueType Windows 3.1 
. TrueType
, Apple Computer Inc. Microsoft
Corporation. 
. TrueType , 
. , Windows
, . 
.
TrueType ,
, WYSIWYG (WhatYou
SeeIsWhatYouGet)1.


120

2. GDI

TrueType
, Windows . 
.
,
, ,
,
.
.
TrueType .ttf. 
Windows OpenType.
PostScript,
TrueType. OpenType .otf.
OpenType OpenType .
, TrueType, 
.ttc.


, 
, (system
font table), 
. , 
,
EnumFontFamilies ChooseFont.
: AddFontResource
AddFontResourceEx. 
. ,
.
, 
Windows.
,
RemoveFontResource.
, ,
WM_FONTCHANGE. 
, ,
.
[6].



.
, ,

.
(font embedding) 
. 
, 
.

121


. TrueType/
OpenType GetOutlineTextMetrics 
otmfsType OUTLINETEXTMETRIC.


Win32 GDI ,
. 2.27.

. 2.27.

.
. 
.
 tmHeight 
.


tmAscent 
.

tmDescent 
.

tmInternalLeading
, .

tmExternalLeading 
.
. 0,01389
(1/71,99424). 1/72 .

.
, , 
GetTextMetrics:


BOOL GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm);

TEXTMETRIC
lptm. TEXTMETRIC :
typedef
LONG
LONG
LONG
LONG

struct tagTEXTMETRIC
tmHeight;
tmAscent;
tmDescent;
tmInternalLeading;

{
//
//
//
//

122

2. GDI
LONG
LONG
LONG
LONG
LONG

tmExternalLeading;
tmAveCharWidth;
tmMaxCharWidth;
tmWeight;
tmOverhang;

//
//
//
// ()
//
//
LONG tmDigitizedAspectX; //
LONG tmDigitizedAspectY; //
TCHAR tmFirstChar;
// ,
//
TCHAR tmLastChar;
// ,
TCHAR tmDefaultChar;
// ,
TCHAR tmBreakChar;
//
//
BYTE tmItalic;
//
BYTE tmUnderlined;
//
BYTE tmStruckOut;
//
BYTE tmPitchAndFamily;
// ,
BYTE tmCharSet;
//
} TEXTMETRIC;


(. . 2.27) , ,
.
tmWeight () . 
0 1000, 400
, 700 .
tmOverhang ,
,
, . TrueType 
, .
tmDigitizedAspectX tmDigitizedAspectY MSDN 
(horizontal aspect of the device) 
(vertical aspect of the device) ,
. , ,
GetDeviceCaps LOGPIXELSX LOGPIXELSY,
1 
1 .
, tmDigitizedAspectY /
tmDigitizedAspectX, (aspect ratio).
tmDefaultChar . 
, , 
, tmDefaultChar.
. 2.222.25 , Windows 
.
tmBreakChar (0x20).
tmPitchAndFamily , 
. . 
. 2.22.
.
Windows . 2.21.

123


2.22.

TMPF_FIXED_PITCH

0x01

, ,
. ,

TMPF_VECTOR

0x02

TMPF_TRUETYPE

0x04

, True Type

TMPF_DEVICE

0x08

tmCharSet .
, wingdi.h. 
. 2.23.
2.23.

ANSI_CHARSET

DEFAULT_CHARSET

SYMBOL_CHARSET

SHIFTJIS_CHARSET

128

HANGUL_CHARSET

129

GB2312_CHARSET

134

CHINESEBIG5_CHARSET

136

GREEK_CHARSET

161

Windows NT/2000

TURKISH_CHARSET

162

Windows NT/2000

HEBREW_CHARSET

177

Windows NT/2000

ARABIC_CHARSET

178

Windows NT/2000

RUSSIAN_CHARSET

204

Windows NT/2000

EASTEUROPE_CHARSET

238

Windows NT/2000

OEM_CHARSET

255

GetTextMetrics, 
TEXTMETRIC, :
TEXTMETRIC tm ;


GetTextMetrics:
hDC = GetDC(hWnd) ;
GetTextMetrics(hDC, &tm) ;


tm. :
ReleaseDC(hWnd, hDC) ;

. , 96 dpi1,
: ) Arial, 
18 ; ) MM_TEXT, 
, .
1

dpi dot per inch ( ).

124

2. GDI

GetTextMetrics tm
:
{18, 15, 3, 2, 1, 7, 43, 400, 0, 96, 96, 30, 255, 31, 32, 0, 0, 0, 39, 204}

, tmPitchAndFamily
, 39 
0x27.


,
. 
, 
. .
GDI,
. GDI 
, .
GDI 
. 
, HFONT.

SYSTEM_FONT,
,
. , 
, ,
ANSI.

OEM1. 
() GetStockObject,
, . 2.24.
2.24.

OEM_FIXED_FONT
ANSI_FIXED_FONT
ANSI_VAR_FONT
SYSTEM_FONT

10
11
12
13

DEVICE_DEFAULT_FONT

14

SYSTEM_FIXED_FONT

16

DEFAULT_GUI_FONT

17

OEM
ANSI
ANSI
ANSI
, , , ,

,

ANSI .
(
Windows 3.0)

, (
Windows NT/2000)

OEM Original Equipment Manufacturers

125

,
SelectObject. 
.


. 
. GDI 
CreateFont, CreateFontIndirect CreateFontIndirectEx.
CreateFontIndirectEx, 
OpenType
Microsoft. MSDN.
CreateFont 14 
, . 
CreateFontIndirect. 
LOGFONT, 14 .
:
HFONT CreateFontIndirect(CONST LOGFONT* lplf);

LOGFONT wingdi.h :
typedef struct tagLOGFONT
{
int lfHeight;
int lfWidth;
int lfEscapement;
int lfOrientation;
int lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
char lfFaceName[LF_FACESIZE];
} LOGFONT;


:
lfHeight .
, .
, tmHeight . 2.27.
, 12 (
). 
, tmHeight tmInternalLeading.

lfWidth .
lfWidth , 

.

lfEscapement X 
. .

126

2. GDI

lfOrientation X 
. .
(GM_ADVANCED), 
Windows NT/2000, lfEscapement
lfOrientation .
(GM_COMPATIBLE) lfEscapement ,
. MSDN 
lfEscapement lfOrientation.

lfWeight () 0 1000. 
, 400 , 700 .
. 2.25 , 
. FW_DONTCARE
.

2.25. 1

FW_DONTCARE

FW_THIN

100

FW_EXTRALIGHT

200

FW_ULTRALIGHT

200

FW_LIGHT

300

FW_NORMAL

400

FW_REGULAR

400

FW_MEDIUM

500

FW_SEMIBOLD

600

FW_DEMIBOLD

600

FW_BOLD

700

FW_EXTRABOLD

800

FW_ULTRABOLD

800

FW_HEAVY

900

FW_BLACK

900

lfItalic , TRUE.

lfUnderline .

lfStrikeOut .

lfCharSet . ,
. 2.23.

lfOutPrecision
. GDI
. 
. 2.26.

, ,
FW_NORMAL, FW_REGULAR FW_BOLD.

127


2.26. lfOutPrecision

OUT_DEFAULT_PRECIS
OUT_TT_PRECIS
OUT_DEVICE_PRECIS
OUT_RASTER_PRECIS
OUT_TT_ONLY_PRECIS
OUT_OUTLINE_PRECIS

0
4
5
6
7
8


True Type


True Type
True Type

lfClipPrecision , 
. . 2.27,
. , 
, CLIP_DEFAULT_PRECIS.

2.27. lfClipPrecision

CLIP_DEFAULT_PRECIS
CLIP_LH_ANGLES

0
0x10

CLIP_EMBEDDED

0x80


,

( ).
,
,

,

lfQuality . ,
. 2.28. TrueType DRAFT_QUALITY
PROOF_QUALITY , 
.

2.28. lfQuality

DEFAULT_QUALITY
DRAFT_QUALITY

0
1

PROOF_QUALITY

NONANTIALIASED_QUALITY
ANTIALIASED_QUALITY

3
4



.
GDI ,


,

(antialiasing)
(antialiasing),

lfPitchAndFamily . 
( ) , 
. 2.29, , . 2.21.

128

2. GDI

2.29. ,

DEFAULT_PITCH

0x0

FIXED_PITCH

0x1

VARIABLE_PITCH

0x2

fFaceName , 
. , , 
32 . , 
, EnumFontFamiliesEx.
fFaceName , GDI
, .
CreateFontIndirect
HFONT :


HFONT hFont;

LOGFONT:
LOGFONT lf;

, 
. 0. 
lf static:
static LOGFONT lf;


lf .
, 
,
lf ChooseFont. 
. 
7 ( ).
lf , CreateFontIndirect:
hFont = CreateFontIndirect(&lf);

hFont 
:
HFONT hOldFont = (HFONT)SelectObject(hDC, hFont);

,
, , 
hFont:
DeleteObject(SelectObject(hDC, hOldFont));

2.3.

, CreateFont CreateFontIndirect,
,
SelectObject. 
,
SelectObject, (font mapping).

129

. GDI
, LOGFONT, ,
, .
,
. , 
.

, lfCharSet.
, 
. lfOutPrecision. 
.
lfFaceName, lfPitchAndFamily.
,
. 
GDI , lfHeight, lfWidth,
lfItalic, lfUnderline, lfStrikeOut.

,

.
GetTextMetrics, , 
.
, :
int GetTextFace(HDC hDC, int nCount, LPTSTR lpFaceName);

. 
, LOGFONT.

lpFaceName. ( ) 
nCount.
, ,
. . GetTextFace
, NULL.
.
GetTextCharSet(HDC hDC)
, .

, GetFontLanguageInfo,
GetTextCharSetInfo GetOutlineTextMetrics.
, . 
MSDN [6].


Win32 GDI 
.
, , 
, , . 

130

2. GDI

, ,
,
. 
.


TextOut 
:
BOOL TextOut (
HDC hdc,
int nXStart,
int nYStart,
LPCTSTR lpString,
int cbString
);

//
//
//
//
//


x-
y-

lpString, 
. 
,
, .
lpString 
, cbString. 
. 
.

, . ,
(reference point): (nXStart, nYStart) 
. ,
( )
: .
SetTextAlign:
UINT SetTextAlign(HDC hdc, UINT fMode);

, 1 
, . 2.30. 
. 0x00 
.
2.30.

TA_NOUPDATECP

0x00


(nXStart, nYStart).

TA_UPDATECP

0x01

131

TA_LEFT

0x00

TA_RIGHT

0x02

TA_CENTER

0x06

TA_TOP

0x00

TA_BOTTOM

0x08

TA_BASELINE

0x18

TA_RTLREADING

0x100

( )

TextOut 2.1,
.


, TextOut , 
\n \t. ,
 ( SYSTEM_FONT) 
.

, 
. Windows 
TabbedTextOut GetTabbedTextExtent.
TabbedTextOut :
LONG TabbedTextOut(HDC hDC, int X, int Y, LPCTSTR lpString, int nCount,
int iNumTabs, CONST LPINT lpnTabStops, int xTabOrigin);

, TextOut. 
, iNumTabs, . 
, lpnTabStops, ,
. 
.
NULL,
,
. ,
lpnTabStops , 
.
, xTabOrigin,
. ,
,
lpnTabStops .
\t, GDI
, . GDI 
, 

132

2. GDI

(
), . GDI
. . 
. ,
, n
n .
lpnTabStops .
GDI , 
,
.
TabbedTextOut 32
, ,
. .
GetTabbedTextExtent ,
.

TabbedTextOut. , , 
:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
int tabstop[] = { -130, 150, 250 };
int i;
const char* lines[] = {
"Group""\t" "Result" "\t" "Function"
"\t" "Parameters",
"Font" "\t" "HFONT"
"\t" "CreateFont" "\t" "(int nHeight, ...)",
"Text" "\t" "COLORREF""\t" "SetTextColor""\t" "(HDC hdc, ...)",
"Text" "\t" "BOOL"
"\t" "TextOut"
"\t" "(HDC hdc, ...)"
};
int x = 50, y = 50;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
for (i = 0; i < 4; i++) {
if (i == 1) y += 10;
y += HIWORD(TabbedTextOut(hDC, x, y, lines[i], strlen(lines[i]),
sizeof(tabstop)/sizeof(int), tabstop, x));
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}

133

for. , , 
TabbedTextOut, , 
y . 
x,
. , , GDI
, tabstop, x.
.2.28.
, ,
, MoveToEx, LineTo
TextOut. , 
. 
180, 50 + 130.

. 2.28.


, 
, (extra space). 
, , 
GDI . .
SetTextCharacterExtra 
, . GetTextCharacterExtra
.
,
. , 
SetTextCharacterExtra,
. for :
SetTextCharacterExtra(hDC, 4);
for (i = 0; i < 4; i++) {
if (i == 1) {
y += 10;
SetTextCharacterExtra(hDC, 0);
}
y += HIWORD(TabbedTextOut(hDC, x, y, lines[i], strlen(lines[i]),
sizeof(tabstop)/sizeof(int), tabstop, x));
}

,
.

(1)
TextOut ,
. 
1

, 
.

134

2. GDI

. (
). , 
, . 
,
.
GDI
GetTextExtentPoint32 SetTextJustification.
,
x x + width. , 
width . 
:
1.
SIZE size;
GetTextExtentPoint32(hDC, lpString, nCount, &size);

lpString, 
nCount .
size. size.cx 
, size.cy .
2. nBreak lpString. 
, 
 . , 
, GetTextMetrics
tmBreakChar TEXTMETRIC.
3. ,
nBreak :
int breakExtra = width - size.cx;

4.
SetTextJustification(hdc, breakExtra, nBreak);

breakExtra nBreak. SetTextJustification , 


, ,
TextOut ExtTextOut.
5. ,
TA_LEFT ( ).
TextOut .
, SetTextJustification 
, breakExtra nBreak. 
GetTextExtentPoint32 ,
GetTextExtentPoint32
SetTextJustification(hdc, 0, 0);

2.1 ,
.

135


2.1. TextJust
//////////////////////////////////////////////////////////////////////
// TextJust.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL TextJustOut(HDC hdc, int x, int y, LPCTSTR lpStr, int width,
char breakChar = ' ');
//////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Text Justification", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
char* text[6] =
{ "",
" ",
"
"
"
"
};

",
, ",
, ",
, ."

int x = 20, y = 20;


SIZE size;
int nWidth, i;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetTextExtentPoint32(hDC, text[5], strlen(text[5]), &size);
nWidth = size.cx;
for (i = 0; i < 6; i++) {
TextJustOut(hDC, x, y, text[i], nWidth);
y += size.cy + 2;
}
EndPaint(hWnd, &ps);

136

2. GDI

2.1 ()
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////
BOOL TextJustOut(HDC hdc, int x, int y, LPCTSTR lpStr, int width,
TCHAR breakChar)
{
SIZE size;
int nCount = strlen(lpStr);
SetTextJustification(hdc, 0, 0);
GetTextExtentPoint32(hdc, lpStr, nCount, &size);
int nBreak = 0;
for (int i = 0; i < nCount; ++i)
if (lpStr[i] == breakChar)
nBreak++;
int breakExtra = width - size.cx;
if (breakExtra < 0) breakExtra = 0;
SetTextJustification(hdc, breakExtra, nBreak);
return TextOut(hdc, x, y, lpStr, nCount);
}
//////////////////////////////////////////////////////////////////////

KWnd,
KWnd.h KWnd.cpp, 1.2, 
Project Workspace .
, ,
TextJustOut. TextJustOut ,
text. nWidth
text[5]. . 2.29.

. 2.29.


Windows
, . , ,
. 
Win32 GDI DrawText DrawTextEx.

137

DrawText :
int DrawText(
HDC hDC,
LPCTSTR lpString,
int nCount,
LPRECT lpRect,
UINT uFormat
);

//
//
//
//
//

, DrawText 
. 

. 1 nCount,
.
, nCount.
DrawText , 
lpRect. , uFormat, 
. ,
.
. 2.31 ( . MSDN).
2.31. DrawText

DT_LEFT
DT_CENTER
DT_RIGHT
DT_TOP
DT_VCENTER

0x0000
0x0001
0x0002
0x0000
0x0004

DT_BOTTOM

0x0008

DT_WORDBREAK

0x0010

DT_SINGLELINE

0x0020

DT_EXPANDTABS

0x0040

DT_NOPREFIX

0x0800

DT_PATH_ELLIPSIS

0x4000

DT_END_ELLIPSIS

0x8000





(
DT_SINGLELINE)
(
DT_SINGLELINE)

, . ,
DT_SINGLELINE
.
( )
\t , .
&. DrawText &
, && &. DT_NOPREFIX
& ,

,

( DT_SINGLELINE)
,
( DT_SINGLELINE)

138

2. GDI

uFormat , Windows
, (\r 0x0D)
(\n 0x0A). ,
. 
. 
, .
, ,
, .
, DT_WORDBREAK.
, DT_ SINGLELINE.
.
DrawText
.
.
DT_VCENTER DT_BOTTOM.
.

, .
DrawText. . 2.30

DrawText(hDC, text1, -1, &rect, uFormat);


char text1[] = "&Open C:\\WINNT\\system32\\gdi32.dll";

uFormat:
) 0;
) DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX;
) DT_SINGLELINE | DT_RIGHT | DT_BOTTOM.
rect 
Rectangle.

. 2.30. text1 rect

. 2.31 
, . 
uFormat:
) 0;
) DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS;
) DT_SINGLELINE | DT_BOTTOM | DT_PATH_ELLIPSIS.
, DrawText 
, ,
, 
.

139

. 2.32
DrawText(hDC, text2, -1, &rect, DT_SINGLELINE | DT_VCENTER | DT_EXPANDTABS);


char text2[] = "&Open \tC:\\WINNT\\system32\\gdi32.dll";

\t.

. 2.31. text1 ,

. 2.32. text2,

. 2.33
char text3[] = "Warning: this computer program \n is protected by copyright law \n and
international treaties";


DrawText(hDC, text3, -1, &rect, DT_CENTER);

. 2.33. , (\n), DT_CENTER

, ,
char text4[] = "Warning: this computer program is protected by copyright law and
international treaties";


DrawText(hDC, text4, -1, &rect, DT_WORDBREAK);

, . 2.34.

. 2.34.
DT_WORDBREAK

DrawTextEx :
int DrawTextEx(HDC hDC, LPTSTR lpchTExt, int cchText, LPRECT lpRect,
UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams);

DrawText ,
DRAWTEXTPARAMS. 
, ,

140

2. GDI

. 
MSDN.

ExtTextOut
ExtTextOut, TextOut,
:
BOOL ExtTextOut(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT* lprc,
LPCTSTR lpString, UINT cbCount, CONST INT* lpDx);

hdc, X, Y, lpString, cbCount ,


TextOut. :
ExtTextOut(hDC, x, y, 0, NULL, lpString, cbCount, NULL);


TextOut(hDC, x, y, lpString, cbCount);

. fuOptions 
, . 
1 lprc , 
, ,
. lpDx
. . 2.32 
, , 
fuOptions.
2.32. ExtTextOut

ETO_OPAQUE

0x0002

ETO_CLIPPED
ETO_GLYPH_INDEX

0x0004
0x0010

ETO_RTLREADING

0x0080

ETO_NUMERICSLOCAL
ETO_NUMERICSLATIN
ETO_IGNORELANGUAGE
ETO_PDY

0x0400
0x0800
0x1000
0x2000

lprc

lprc
lpString
( ),
GetCharacterPlacement.
16-





lpDx ,
,

ExtTextOut
. 
, ,
ExtTextOut
ETO_OPAQUE ETO_CLIPPED.
1

NULL.

141


ETO_GLYPH_INDEX. 
, WYSIWYG.
, 
.
ExtTextOut [6].



.
:
 ( ).


GDI .
, 
. [6].



,
. ,
, ,
. (scroll bars) 
. 
.
:
 ;
Scroll bar.
7.
, 
, , . 2.35.
, CreateWindow 
WS_VSCROLL ( ) WS_HSCROLL ( 
) dwStyle.
, . 
. 
, , 
.
.

.
(thumb).

.
.


142

2. GDI

. 2.35.

, , , 
, .
Windows . 
. 
,
(
4).


:
 (range), , 
(nMin) (nMax)
.
, 1 
. range range = nMax nMin + 1.


(position) , 
.
,
.
.

(page) ,
, 
. Windows 
. 
, .
, , 

1 .

143

.
, 
.
0 100.
. ,
nLine , 
. nMin = 0 nMax =
= nLine 1. nMin = 1 nMax = nLine.
, 
, .
,
SetScrollInfo:


int SetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL fRedraw);

hwnd ,
, Scroll
Bar. fnBar.
fnBar . 
SB_VERT ( ), SB_HORZ ( 
) SB_CTL ( Scroll Bar). lpsi 
SCROLLINFO, .
bRedraw , 
SetScrollInfo.
SCROLLINFO winuser.h :
typedef struct tagSCROLLINFO
{
UINT cbSize;
//
UINT fMask;
// /
int nMin;
//
int nMax;
//
UINT nPage;
//
int nPos;
//
int nTrackPos;
// ,
} SCROLLINFO;

fMask ,
SetScrollInfo GetScrollInfo.
, . 2.33.

GetScrollInfo.
, ,
Windows 
. , Windows :
 ;



;

, 
;

144


2. GDI

, 
.

2.33. fMask

SIF_PAGE

nPage

nPos ,

nMin nMax

nTrackPos , (
GetScrollInfo)
SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS

. ,

SIF_POS
SIF_RANGE
SIF_TRACKPOS

SIF_ALL
SIF_DISABLENOSCROLL

:
;


Windows WM_VSCROLL
WM_HSCROLL, 
.
, wParam
, ,
. 
, SB_.
. 2.36 , Windows
. 
. ,
. 
SB_LINEUP SB_PAGEUP,
. 
SB_ENDSCROLL , . ,
SB_ENDSCROLL .
(thumb) 
SB_THUMBTRACK. wParam 
SB_THUMBTRACK SB_THUMBPOSITION, wParam
.
wParam . 
lParam, , 
.

145

. 2.36. wParam

, 
. : yInc 
xInc .
. , .
ScrollWindow:
BOOL ScrollWindow(
HWND hWnd,
int XAmount,
int YAmount,
CONST RECT* lpRect,
CONST RECT* lpClipRect
);

//
//
//
//
//

XAmount YAmount . 
lpRect lpClipRect NULL, 
.
, WM_VSCROLL
:
ScrollWindow(hWnd, 0, -yStep * yInc, NULL, NULL);

WM_HSCROLL :
ScrollWindow(hWnd, -cxChar * xInc, 0, NULL, NULL);

yStep ,
cxChar . 
,
.

. , 
:
si.nPos += yInc;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

si SCROLLINFO.

146

2. GDI

, ScrollWindow 
.
, 

InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);

, UpdateWindow WM_PAINT
. , 
, 
( SB_THUMBTRACK). ,
InvalidateRect 
WM_PAINT ,
.
, WM_PAINT
,
.
2.2.



TextViewer
. : ,
TextOut TabbedTextOut, 
.
, 
, .
KDocument , , 
.
KDocument.h,
KDocument.cpp.
, 
2.21.
2.2. TextViewer
//////////////////////////////////////////////////////////////////////
// KDocument.h
#include <windows.h>
#include <vector>
#include <string>
using namespace std;
class KDocument {
1

, KWnd.h KWnd.cpp ( 1.2


1) Project Workspace
.


public:
BOOL
void
void
void
void
void

147

Open(const char* file);


Initialize(LPTEXTMETRIC tm);
ScrollSettings(HWND hwnd, int width, int height);
UpdateHscroll(HWND hwnd, int xInc);
UpdateVscroll(HWND hwnd, int yInc);
PutText(HWND hwnd, HDC hdc);

int cxChar;
//
int yStep;
// ()
int lineLenMax;
//
SCROLLINFO vsi;
//
int vertRange;
//
SCROLLINFO hsi;
//
int horzRange;
//
private:
vector<string> lines; //
};
//////////////////////////////////////////////////////////////////////
// KDocument.cpp
#include <windows.h>
#include <fstream>
#include "KDocument.h"
BOOL KDocument::Open(const char* file) {
ifstream finp(file);
char buf[200];
if(!finp.good()) {
MessageBox(NULL, " ", "Error", MB_OK);
return FALSE;
}
// , lines
while(!finp.eof()) {
finp.getline(buf, 199);
buf[199] = 0;
lines.push_back(string(buf));
}
//
lineLenMax = 0;
for (int i = 0; i < lines.size(); ++i) {
int lineLen = lines[i].size();
// ,
int iTabPos = 0;
while (1) {
iTabPos = lines[i].find('\t', iTabPos);
if (iTabPos != -1) {
lineLen += 8;
iTabPos++;
}
else break;
}
if (lineLen > lineLenMax) lineLenMax = lineLen;
}
return TRUE;
}
void KDocument::Initialize(LPTEXTMETRIC tm) {

148

2. GDI

2.2 ()
cxChar = tm->tmAveCharWidth;
yStep = tm->tmHeight + tm->tmExternalLeading;
vsi.nMin = vsi.nPos = 0;
hsi.nMin = hsi.nPos = 0;
}
void KDocument::ScrollSettings(HWND hwnd, int width, int height) {
//
vsi.cbSize = sizeof(vsi);
vsi.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
vsi.nPage = height / yStep - 1;
vsi.nMax = lines.size() - 1;
if (vsi.nPage > vsi.nMax)
vsi.nPos = vsi.nMin;
vertRange = vsi.nMax - vsi.nMin + 1;
SetScrollInfo(hwnd, SB_VERT, &vsi, TRUE);
//
hsi.cbSize = sizeof(SCROLLINFO);
hsi.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
hsi.nPage = width/cxChar - 2;
hsi.nMax = lineLenMax;
if (hsi.nPage > hsi.nMax)
hsi.nPos = hsi.nMin;
horzRange = hsi.nMax - hsi.nMin + 1;
SetScrollInfo(hwnd, SB_HORZ, &hsi, TRUE);
}
void KDocument::UpdateVscroll(HWND hwnd, int yInc) {
//
yInc = min(yInc, vertRange - (int)vsi.nPage - vsi.nPos);
//
yInc = max(yInc, vsi.nMin - vsi.nPos);
if (yInc) {
ScrollWindow(hwnd, 0, -yStep * yInc, NULL, NULL);
vsi.nPos += yInc;
SetScrollInfo(hwnd, SB_VERT, &vsi, TRUE);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow (hwnd);
}
}
void KDocument::UpdateHscroll(HWND hwnd, int xInc) {
//
xInc = min(xInc, horzRange - (int)hsi.nPage - hsi.nPos);
//
xInc = max(xInc, hsi.nMin - hsi.nPos);
if (xInc) {
ScrollWindow(hwnd, -cxChar * xInc, 0, NULL, NULL);
hsi.nPos += xInc;
SetScrollInfo(hwnd, SB_HORZ, &hsi, TRUE);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow (hwnd);
}

149


}
void KDocument::PutText(HWND hwnd, HDC hdc) {
RECT rect;
GetClientRect(hwnd, &rect);
rect.left += cxChar;
rect.right -= cxChar;
HRGN hRgn = CreateRectRgnIndirect(&rect);
SelectClipRgn(hdc, hRgn);
int x = cxChar * (hsi.nMin - hsi.nPos + 1);
int y = yStep;
int amountLines = lines.size();
int iBeg = vsi.nPos;
int iEnd = (vsi.nPos+vsi.nPage < amountLines)? vsi.nPos+vsi.nPage :
amountLines;
for (int i = iBeg; i < iEnd; ++i) {
int iTabPos = lines[i].find('\t');
if (-1 == iTabPos)
TextOut(hdc, x, y, lines[i].c_str(), lines[i].size());
else
TabbedTextOut(hdc, x, y, lines[i].c_str(), lines[i].size(), 0, 0, x);
y += yStep;
}
SelectClipRgn(hdc, NULL);
}
//////////////////////////////////////////////////////////////////////
// TextViewer.cpp
#include <windows.h>
#include "KWnd.h"
#include "KDocument.h"
#define FILE_NAME "D:\\Program files\\Microsoft Visual
Studio\\VC98\\MFC\\SRC\\README.TXT"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
KDocument doc;
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if (!doc.Open(FILE_NAME)) return 0;
KWnd mainWnd("Text Viewer", hInstance, nCmdShow, WndProc, NULL,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, CS_HREDRAW | CS_VREDRAW,
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================

150

2. GDI

2.2 ()
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
TEXTMETRIC tm;
int cxClient=0, cyClient=0;
static int xInc, yInc;
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
doc.Initialize(&tm);
ReleaseDC(hWnd, hDC);
break;
case WM_SIZE:
hDC = GetDC(hWnd);
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
if (cxClient > 0)
doc.ScrollSettings(hWnd, cxClient, cyClient);
ReleaseDC(hWnd, hDC);
break;
case WM_VSCROLL:
switch(LOWORD(wParam)) {
case SB_LINEUP:
yInc = -1; break;
case SB_LINEDOWN:
yInc = 1; break;
case SB_PAGEUP:
yInc = -(int)doc.vsi.nPage; break;
case SB_PAGEDOWN:
yInc = (int)doc.vsi.nPage; break;
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - doc.vsi.nPos; break;
default: yInc = 0;
}
doc.UpdateVscroll(hWnd, yInc);
break;
case WM_HSCROLL:
switch(LOWORD(wParam)) {
case SB_LINELEFT:
xInc = -1; break;
case SB_LINERIGHT:
xInc = 1; break;
case SB_PAGELEFT:
xInc = -0.8 * (int)doc.hsi.nPage; break;
case SB_PAGERIGHT:
xInc = 0.8 * (int)doc.hsi.nPage; break;
case SB_THUMBTRACK:
xInc = HIWORD(wParam) - doc.hsi.nPos; break;
default: xInc = 0;
}

151

doc.UpdateHscroll(hWnd, xInc);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
doc.PutText(hWnd, hDC);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////


KDocument:
lines,
string.

Open . ,
\n. 
lines. for
lineLenMax . 
lines[i] find
string, \t
1, . ScrollSettings
lineLenMax 
.

Initialize . 
cxChar ,
yStep . 
, tm.

ScrollSettings
width height
.

UpdateVscroll 
.
ScrollWindow, 
SetScrollInfo
UpdateWindow.
.
.

. 

152

2. GDI

,
vertRange (int)vsi.nPage.

. ,
int vsi.nPage 
min.

, vsi.nMin.


UpdateHscroll 
. 
UpdateVscroll.

PutText 
.

( 
) hRgn.
CreateRectRgnIndirect,
rect, 
,
cxChar. 
SelectClipRgn.
for
vsi.nPos 
hsi.nPos . lines[i]
, TextOut. 
TabbedTextOut.
MM_TEXT,
.
y 
yStep.
hsi.nPos hsi.nMin, x,
cxChar (hsi.nMin hsi.nPo s + 1), cxChar.
, .
hRgn,
, x = cxChar.
hsi.nPo s > 0 x ,
, 
. 
, . 
, , Windows,
, . 
, , .
SelectClipRgn(hdc, NULL) 
.

153

, TextViewer.cpp:
doc KDocument.

WinMain Open doc, 


, FILE_NAME.
README.TXT, Microsoft Visual C++
6.01. ,
.

WS_VSCROLL | WS_HSCROLL, 
KWnd windowStyle.

.

WndProc Initialize doc 


WM_CREATE, ScrollSettings 
WM_SIZE.

WM_VSCROLL doc.UpdateVscroll(hWnd, yInc). WM_HSCROLL


doc.UpdateHscroll(hWnd, xInc).

WM_PAINT 
doc.PutText(hWnd, hDC).

.




U_T_Diagram 
, , , 
, .

. 
220 , 50 .
, .
. 2.37 U_T_Diagram .
, 
. , 
, 
.  ,
, 
.
T f
T = 1/f, 50 0,02 , 20 . 
, U 
Um U = 0,707 . Um. 
, 311,17 .
1

154

2. GDI

. 2.37. U_T_Diagram


, .
1 , X Y 3 , 5 
.
,
. 
, 
, ,
.
(viewport)
, GetClientRect. 

.
, (window).
, ,
, ,
. , 
. , , 
. . ,
,
mx my1. .

Win32 API . ,
CreatePen(penStyle, nWidth, crColor) nWidth 
. nWidth,
1

mx = xVE / xWE, my = yVE / yWE, xVE, yVE , xWE, yWE


.

155

1 
.
,
xVE = 952, yVE = 7021,
xWE = 60 (), yWE = 1000 (), 
mx = 952 / 60 = 15,86 , , 16 . 
my = 702 / 1000 = 0,72 , ,
.
 , . 2.37,
.
MM_ISOTROPIC, 
. 
. 
,
:
nPixPerVolt = yVE / 1000.0;
nPixPerMs = xVE / 60.0;

2.3.
2.3. U_T_Diagram2
//////////////////////////////////////////////////////////////////////
// U_T_Diagram.cpp
#include <windows.h>
#include <math.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DrawDiagram(HWND, HDC);
#define Pi 3.14159265
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd(" ",
hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================

,
.

KWnd.h KWnd.cpp (. 1.2 1).

156

2. GDI

2.3 ()
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
DrawDiagram(hWnd, hDC);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//====================================================================
void DrawDiagram(HWND hwnd, HDC hdc)
{
RECT rect;
GetClientRect(hwnd, &rect);
const int xVE = rect.right - rect.left;
const int yVE = rect.bottom - rect.top;
const int xWE = xVE;
const int yWE = yVE;
double nPixPerVolt = yVE / 1000.0;
double nPixPerMs = xVE / 60.0;
// n Pixels Per Millisec
SetMapMode (hdc, MM_ISOTROPIC);
SetWindowExtEx (hdc, xWE, yWE, NULL);
SetViewportExtEx (hdc, xVE, -yVE, NULL);
SetViewportOrgEx (hdc, 10*nPixPerMs, yVE/2, NULL);
const int
const int
const int
const int
const int
const int
int x, y;

tMin = 0;
tMax = 40;
uMin = -400;
uMax = 400;
tGridStep = 5;
uGridStep = 100;

//
//
//
//

ms
ms
V
V

char* xMark[] = { "0", "5", "10", "15", "20", "25", "30", "35", "40"};
char* yMark[] = { "-400","-300","-200","-100", "0", "100", "200", "300",
"400"};
//
HPEN hPen0 = CreatePen(PS_SOLID, 1, RGB(0, 160, 0));
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen0);
int u = uMin;

157

int xMin = tMin * nPixPerMs;


int xMax = tMax * nPixPerMs;
for (int i = 0; i < 9; ++i) {
y = u * nPixPerVolt;
MoveToEx(hdc, xMin, y, NULL);
LineTo(hdc, xMax, y);
TextOut(hdc, xMin-40, y+8, yMark[i], strlen(yMark[i]));
u += uGridStep;
}
int
int
int
for

t = tMin;
yMin = uMin * nPixPerVolt;
yMax = uMax * nPixPerVolt;
(i = 0; i < 9; ++i) {
x = t * nPixPerMs;
MoveToEx(hdc, x, yMin, NULL);
LineTo(hdc, x, yMax);
TextOut(hdc, x-6, yMin-10, xMark[i], strlen(xMark[i]));
t += tGridStep;

}
// "x"
HPEN hPen1 = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
SelectObject(hdc, hPen1);
MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, xMax, 0);
static LOGFONT lf;
lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
lf.lfItalic = TRUE;
lf.lfWeight = FW_BOLD;
lf.lfHeight = 20;
lf.lfCharSet = DEFAULT_CHARSET;
lstrcpy( (LPSTR)&lf.lfFaceName, "Arial" );
HFONT hFont0 = CreateFontIndirect(&lf);
HFONT hOldFont = (HFONT)SelectObject(hdc, hFont0);
SetTextColor(hdc, RGB(0, 0, 200));
TextOut(hdc, xMax+10, 10, "t (ms)", 6);
// "y"
MoveToEx(hdc, 0, yMin, NULL); LineTo(hdc, 0, yMax);
TextOut(hdc, -10, yMax+30, "u (V)", 5);
//
HPEN hPen2 = CreatePen(PS_SOLID, 5, RGB(200, 0, 100));
SelectObject(hdc, hPen2);
int tStep = 1;
double radianPerMs = 2 * Pi / 20;
const double uAmplit = 311.17;
// volt
t = tMin;
MoveToEx(hdc, 0, 0, NULL);
while (t <= tMax) {
u = uAmplit * sin( t * radianPerMs);
LineTo(hdc, t * nPixPerMs, u * nPixPerVolt);
t += tStep;
}
//
char* title = " . ";

158

2. GDI

2.3 ()
lf.lfItalic = FALSE;
lf.lfWeight = FW_BOLD;
lf.lfHeight = 30;
HFONT hFont1 = CreateFontIndirect(&lf);
SelectObject(hdc, hFont1);
SetTextColor(hdc, RGB(0, 200, 0));
TextOut(hdc, 0, yMax + 70, title, strlen(title));
SelectObject(hdc, hOldPen);
SelectObject(hdc, hOldFont);
}
//////////////////////////////////////////////////////////////////////

DrawDiagram, WM_PAINT.
, 
.
, 
, .
1 , 
1 .
,
SetViewportExtEx (hdc, xVE, -yVE, NULL);

, 
, .
:
SetViewportOrgEx (hdc, 10*nPixPerMs, yVE/2, NULL);


10 .
tMin, tMax, uMin, uMax,
tGridStep, uGridStep, . 
t, u. ( 
)
nPixPerMs, nPixPerVolt.
while  
sin(x). 
, u.
LineTo ,
u.
sin ,
= 2 . . f = 2 . / T
:
radianPerMs = 2 * Pi / 20;


, , , 
.

159

GDI. ,
,


GDI. , 
, , , . 
,
,
DIB DIB.

, 24
RGB1, . ,
, 256 .
, , 
.
, Windows , 

. , 
, GetDeviceCaps, RASTERCAPS,
, RC_PALETTE.
, ,
.


() , 
. 
.
Win32 GDI .
(system palette) ,
.
1

24 16 777 216 .

160

3. GDI. , ,

, , . 

. .
256 (), 20 
, 
. , ,
, .
(logical palette) . 
.
, 
. 
CreatePalette CreateHalftonePalette
RealizePalette. Windows
. 
, , Windows
, ,
(dithering) , 
.

, MSDN . , 
COLORREF,
PALETTERGB, RGB.
, 
(default palette), 20 ,
. , 
, 20 .
, 
, Windows 1
.
.

.
,
.

, , 
, Windows WM_QUERYNEWPALETTE.

, ,
.
WM_PALETTECHANGED , 
.
,
, .

, .

161



. , , 
, , 
, .
,
,
. , 
: .
. 
COMBOBOX 
.
, , , :
 256 ;


Hi Color (16 );

True Color (24 32 ).


256 
. 256 ,
. 
, 
.
256 PALETTEENTRY:


typedef struct {
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags;
} PALETTEENTRY;

PALETTEENTRY
RGB. peFlags .
. 

GetSystemPaletteEntries, :
UINT
GetSystemPaletteEntries(
HDC hdc,
//
UINT iStartIndex,
//
UINT nEntries,
//
LPPALETTEENTRY lppe
// PALETTEENTRY
);

lppe , 
. NULL,
.
.
, , , , 
.
20 
. . 3.1.

162

3. GDI. , ,

3.1.

RGB

0
1
2
3
4
5
6
7
8
9
246
247
248
249
250
251
252
253
254

0x00, 0x00, 0x00


0x80, 0x00, 0x00
0x00, 0x80, 0x00
0x80, 0x80, 0x00
0x00, 0x00, 0x80
0x80, 0x00, 0x80
0x00, 0x80, 0x80
0xC0, 0xC0, 0xC0
0xC0, 0xDC, 0xC0
0xA6, 0xCA, 0xF0
0xFF, 0xFB, 0xF0
0xA0, 0xA0, 0xA4
0x80, 0x80, 0x80
0xFF, 0x00, 0x00
0x00, 0xFF, 0x00
0xFF, 0xFF, 0x00
0x00, 0x00, 0xFF
0xFF, 0x00, 0xFF
0x00, 0xFF, 0xFF

-
-
-
-
-
-
-

-
-
-

255

0xFF, 0xFF, 0xFF









True Color
True Color
True Color
True Color






. ,
,
. , 
XOR
.
. 
, 255 (0xFF), 
. 1 
RGB(0x80, 0x00, 0x00). , 254 (0xFE),
. ,
 RGB (RGB(0x7F, 0xFF, 0xFF)),
.
8 8 ,
. 8, 9, 246, 247 .
RGB True Color. 256
RGB .
, ,
, 3.1.
3.1. SystemPalette
//////////////////////////////////////////////////////////////////////
// SystemPalette.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

163

//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("System palette", hInstance, nCmdShow, WndProc, NULL, 0, 0,
524, 543);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT r0;
RECT rect;
HBRUSH brush;
int dW, dH, i, j;
int index = 0;
PALETTEENTRY pal[256];
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetSystemPaletteEntries(hDC, 0, 256, pal);
GetClientRect(hWnd, &r0);
dW = (r0.right - 4) / 16;
dH = (r0.bottom - 4) / 16;
SetViewportOrgEx(hDC, 2, 2, NULL);
for (i = 0; i < 16; ++i)
for (j = 0; j < 16; ++j) {
SetRect(&rect, j*dW, i*dH, (j+1)*dW - 1, (i+1)*dH - 1);
brush = CreateSolidBrush(RGB(pal[index].peRed,
pal[index].peGreen, pal[index].peBlue));
FillRect(hDC, &rect, brush);
DeleteObject(brush);
index++;
}
EndPaint(hWnd, &ps);
break;
case WM_PALETTECHANGED:
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_DESTROY:

164

3. GDI. , ,
3.1. ()
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;

}
//////////////////////////////////////////////////////////////////////

WM_PAINT.
GetSystemPaletteEntries
pal.
GetClientRect 
r0, RECT. 
r0.left r0.top , r0.right
r0.bottom .
WinMain
516 516 . dW dH, 
rect, 
brush, 32.
WM_PALETTECHANGED
InvalidateRect, , , 
WM_PAINT .
1. 
256 , , 
. 3.1. ,  
, , ,
2. 
. ,
. 236 
RGB, 
. , , 
 , MS Paint.
, . ,
MS Paint
.
. ,
True Color3. System palette ,
. 3.2. , , 
. , 
RGB(0x00, 0x00, 0x00). , True Color 
, .

KWnd.h KWnd.cpp, 1.2.

,
(www.piter.com).

, .

165

. 3.1. 256-

. 3.2. True Color

166

3. GDI. , ,


, ,
COLORREF,
:
COLORREF PALETTEINDEX(WORD wPaletteIndex);
COLORREF PALETTERGB(BYTE bRed, BYTE bGreen, BYTE bBlue);

PALETTEINDEX 32 
.
.
PALETTERGB, RGB, ,
.

. PALETTERGB
, RGB
,
. ,
RGB ,
COLORREF.


,
, , 
20 .

, 8 ( 3.2).
3.2. ColorsWithDefaultPal
//////////////////////////////////////////////////////////////////////
// ColorsWithDefaultPal.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Colors with default palette", hInstance, nCmdShow, WndProc,
NULL, 0, 0, 800, 200);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;

167

RECT r0;
RECT rect[8];
int dW, dH, i;
static HBRUSH brush[8];
COLORREF rgbColor[8] = { RGB(128,0,0), RGB(192,0,0),RGB(255,0,0),
RGB(255,192,0), RGB(176,250,133), RGB(245,197,137),
RGB(255,128,128), RGB(255,128,255)};
switch (uMsg)
{
case WM_CREATE:
for (i = 0; i < 8; ++i)
brush[i] = CreateSolidBrush(rgbColor[i]);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &r0);
dW = r0.right / 8;
dH = r0.bottom;
for (i = 0; i < 8; ++i) {
SetRect(&rect[i], i*dW, 0, (i+1)*dW, dH);
FillRect(hDC, &rect[i], brush[i]);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
for (i = 0; i < 8; ++i)
DeleteObject(brush[i]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

True Color,
, . 3.3.

. 3.3. ( True Color)

8 , rgbColor:
, , , , , ,
, .

168

3. GDI. , ,

, 
RGB .
256 
. . 3.4.

. 3.4. (256- )

, . 

.
, 
.


, 
.
:
1. ( CreateHalftonePalette).
2. ( SelectPalette).
3. RealizePalette.
SelectPalette :
HPALETTE
SelectPalette(
HDC hdc,
//
HPALETTE hpal,
//
BOOL bForceBackground
// ( )
);

, (TRUE)
(FALSE) Realize
Palette. .
, RealizePalette 

, . 
, , .
RealizePalette
, , , 
.
3.3 , ,
, . 
WM_QUERYNEWPALETTE WM_PALETTECHANGED.

169

3.3. ColorsWithHalftonePal
//////////////////////////////////////////////////////////////////////
// ColorsWithHalftonePal.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Colors with halftone palette", hInstance, nCmdShow,
WndProc, NULL, 0, 0, 800, 200);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT r0;
RECT rect[8];
int dW, dH, i;
COLORREF paletteColor[8] = { PALETTERGB(128,0,0), PALETTERGB(192,0,0),
PALETTERGB(255,0,0), PALETTERGB(255,192,0), PALETTERGB(176,250,133),
PALETTERGB(245,197,137), PALETTERGB(255,128,128),
PALETTERGB(255,128,255)};
static HBRUSH brush[8];
static HPALETTE hPal;
HPALETTE hOldPal;
switch (uMsg)
{
case WM_CREATE:
for (i = 0; i < 8; ++i)
brush[i] = CreateSolidBrush(paletteColor[i]);
hDC = GetDC(hWnd);
hPal = CreateHalftonePalette(hDC);
ReleaseDC(hWnd, hDC);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
hOldPal = SelectPalette(hDC, hPal, FALSE);
GetClientRect(hWnd, &r0);
dW = r0.right / 8;
dH = r0.bottom;
for (i = 0; i < 8; ++i) {
SetRect(&rect[i], i*dW, 0, (i+1)*dW, dH);
FillRect(hDC, &rect[i], brush[i]);
}

170

3. GDI. , ,

3.3 ()
SelectPalette(hDC, hOldPal, TRUE);
EndPaint(hWnd, &ps);
break;
case WM_QUERYNEWPALETTE:
hDC = GetDC(hWnd);
SelectPalette(hDC, hPal, FALSE);
if (RealizePalette(hDC))
InvalidateRect(hWnd, NULL, TRUE);
ReleaseDC(hWnd, hDC);
break;
case WM_PALETTECHANGED:
hDC = GetDC(hWnd);
SelectPalette(hDC, hPal, FALSE);
if (RealizePalette(hDC))
InvalidateRect(hWnd, NULL, TRUE);
ReleaseDC(hWnd, hDC);
break;
case WM_DESTROY:
DeleteObject(hPal);
for (i = 0; i < 8; ++i)
DeleteObject(brush[i]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////


:
hPal WM_CREATE,
WM_QUERYNEWPALETTE,
WM_PALETTECHANGED. RealizePalette 
,
. , InvalidateRect.

WM_PAINT 
, .

256 
, ,
True Color (. . 3.3).


, 
. ,
.
, 
, , .
paletteColor :

171

COLORREF paletteColor[8] = { PALETTERGB(0,31,0), PALETTERGB(0,63,0),


PALETTERGB(0,95,0), PALETTERGB(0,127,0), PALETTERGB(0,159,0),
PALETTERGB(0,191,0), PALETTERGB(0,223,0), PALETTERGB(0,255,0)};

, , ,
.
,
. CreatePalette:
HPALETTE

CreatePalette(CONST

LOGPALETTE*

lplgpl);

lplgpl LOGPALETTE, 
:
typedef struct tagLOGPALETTE {
WORD
palVersion;
//
WORD
palNumEntries; //
PALETTEENTRY palPalEntry[1];
} LOGPALETTE;

Windows 3.0
 0x300.
palPalEntry PALETTEENTRY,
.
PALETTEENTRY .
RGB
, peFlags ,
. peFlags . 3.2.
3.2. peFlags

, RGB
. ,

PC_NOCOLLAPSE


() .

PC_EXPLICIT

.
PALETTEENTRY .

PC_RESERVED

, .
-
. ,

, LOGPALETTE palPalEntry
, , 
. 
LOGPALETTE,

LOGPALETTE. .

RealizePalette , .
3.4 , 
, 128 , 16 
, .

172

3. GDI. , ,

3.4. LogicPalette
//////////////////////////////////////////////////////////////////////
// LogicPalette.cpp
#include <windows.h>
#include "KWnd.h"
#define PAL_NUM_ENTRIES
#define NUM_RECT 16

128

typedef struct {
LOGPALETTE lp;
PALETTEENTRY ape[PAL_NUM_ENTRIES - 1];
} LogPal;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Colors with logic palette", hInstance, nCmdShow, WndProc,
NULL, 0, 0, 808, 200);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT r0;
RECT rect[NUM_RECT];
int dW, dH, i;
static LogPal pal;
LOGPALETTE* pLP = (LOGPALETTE*) &pal;
static COLORREF paletteColor[NUM_RECT];
static HBRUSH brush[NUM_RECT];
static HPALETTE hPal;
HPALETTE hOldPal;
BYTE green;
BYTE stepPal, stepBrush;
switch (uMsg)
{
case WM_CREATE:
//
pLP->palVersion = 0x300; // Windows
pLP->palNumEntries = PAL_NUM_ENTRIES; //
stepPal = 256 / PAL_NUM_ENTRIES;

173

green = 255;
for (i = 0; i < PAL_NUM_ENTRIES; i++) {
pLP->palPalEntry[i].peRed = 0;
pLP->palPalEntry[i].peGreen = green;
pLP->palPalEntry[i].peBlue = 0;
pLP->palPalEntry[i].peFlags = 0;
green -= stepPal;
}
hPal = CreatePalette (pLP);
//
stepBrush = 256 / NUM_RECT;
for (i = 0; i < NUM_RECT; ++i)
brush[i] = CreateSolidBrush(PALETTERGB(0, stepBrush * i, 0));
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
hOldPal = SelectPalette(hDC, hPal, FALSE);
GetClientRect(hWnd, &r0);
dW = r0.right / NUM_RECT;
dH = r0.bottom;
for (i = 0; i < NUM_RECT; ++i) {
SetRect(&rect[i], i*dW, 0, (i+1)*dW, dH);
FillRect(hDC, &rect[i], brush[i]);
}
SelectPalette(hDC, hOldPal, TRUE);
EndPaint(hWnd, &ps);
break;
case WM_QUERYNEWPALETTE:
hDC = GetDC(hWnd);
SelectPalette(hDC, hPal, FALSE);
if (RealizePalette(hDC))
InvalidateRect(hWnd, NULL, TRUE);
ReleaseDC(hWnd, hDC);
break;
case WM_PALETTECHANGED:
hDC = GetDC(hWnd);
SelectPalette(hDC, hPal, FALSE);
if (RealizePalette(hDC))
InvalidateRect(hWnd, NULL, TRUE);
ReleaseDC(hWnd, hDC);
break;
case WM_DESTROY:
DeleteObject(hPal);
for (i = 0; i < NUM_RECT; ++i)
DeleteObject(brush[i]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

174

3. GDI. , ,

LogPal
, LOGPALETTE. 
LOGPALETTE, 
PALETTEENTRY, (PAL_NUM_ENTRIES 1) .
LogPal WndProc:
static

LogPal

pal;

,
LOGPALETTE, LOGPALETTE,
pal:
LOGPALETTE*

pLP

(LOGPALETTE*)

&pal;

236, 20
.
PAL_NUM_ENTRIES, 128,
, 16 .

WM_CREATE. pal,
pLP, palPalEntry
. CreatePalette. 
WM_QUERYNEWPALETTE
WM_PALETTECHANGED. , WM_PAINT 

SelectPalette.
, . 3.5.

. 3.5. (256- )

, 2, , 
,
, , . 

. 
(vector graphics).
, 
, . 
(bitmap graphics). 
, , , ,

175

 , , ,
Microsoft Paint Adobe Photoshop.
, , (bitmap) 
.
, . 
.
.
, , 2n,
n . , VGA 
256 8 .
, 224 , 24
, RGB 8 .
Windows 
,  , DDB
(device dependent bitmap). DDB ,

. , 256 
, 8 . 
DDB ,
.
, 
, .
Windows 3.0, ,
 , DIB (device independent bitmap).
DIB
. 
RGB,

. , DIB, 
, 
, .
 (DDB) 
Windows,
,
.  (DIB), ,
,
Windows.
DIB,
DDB ,
Win32 GDI, DIB.

-
 (DIB) 
,
. , DIB, .bmp.
DIB
BMP.

176

3. GDI. , ,

BMP
BMP, 
, . 3.3.
3.3. DIB- ( BMP)


BITMAPFILEHEADER bmfHeader;

14


BITMAPINFOHEADER bmiHeader;

40


BITMAPV4HEADER (108 )
BITMAPV5HEADER (124 )


RGBQUAD bmiColors[];


BYTE aBitmapBits[][];


BITMAPFILEHEADER,
bmfHeader, :
typedef struct tagBITMAPFILEHEADER {
WORD
bfType;
//
DWORD bfSize;
//
WORD
bfReserved1; // ( )
WORD
bfReserved2; // ( )
DWORD bfOffbits;
//
} BITMAPFILEHEADER;

bfType ASCII B M, , ,
bitmap. 0x42
0x4D.
Windows . , WORD
, , , , 
bfType = 0x4d42.
bfSize .
bfOffbits .
BMP , bfOffbits
aBitmapBits.

bmiHeader,
. 
BITMAPINFOHEADER wingdi.h:
typedef
DWORD
LONG
LONG
WORD
WORD
DWORD
DWORD

struct
tagBITMAPINFOHEADER{
biSize;
// BITMAPINFOHEADER
biWidth;
//
biHeight;
// +
biPlanes;
// ( 1)
biBitCount;
//
biCompression;
//
biSizeImage;
//

177

LONG
biXPelsPerMeter; //
LONG
biYPelsPerMeter; //
DWORD biClrUsed;
//
DWORD biClrImportant; // ,
//
} BITMAPINFOHEADER;

biWidth biHeight .
biHeight ,
.
.
( ), 
. DIB 
(bottomup).
( ), DIB (topdown).
BMP 
.
biPlanes 
.
( ). DIB
, biPlanes 
.
biBitCount ,
. .
. 3.4.
3.4. biBitCount

21 (2)

1/8

.
bmiColors , RGBQUAD.
aBitmapBits
bmiColors. 0,
bmiColors[0], 1
bmiColors[1]

24 (16)

1/2

16 , , bmiColors
16 RGBQUAD.
aBitmapBits .
4-

28 (256)

256 , bmiColors
256 .
aBitmapBits
.


JPEG PNG ( Windows 98/2000)

178

3. GDI. , ,

3.4 ()

16

216 (65 536)

216 (
High Color). biCompression
BI_RGB, bmiColors
. (WORD)
aBitmapBits .
,

.

biCompression BI_BITFIELDS,


,

aBitmapBits
24

224 (16 777 216)

bmiColors

aBitmapBits ,
.
bmiColors
, .

, biClrUsed

32

224 (24 True Color).

224 (16 777 216)

224 (32-
True Color). biCompression
BI_RGB, bmiColors
.
(DWORD) aBitmapBits
.
,
.
.
biCompression BI_BITFIELDS,


,

aBitmapBits5

32 True Color 


, .
biCompression , 
. . 3.5.
biHeight , biCompression
BI_RGB BI_BITFIELDS,
.

179

3.5. biCompression

BI_RGB

0x0

BI_RLE8

0x1

8 /,
RLE

BI_RLE4

0x2

4 /,
RLE

BI_BITFIELDS

0x3

16 32 /. ,
RGB

biCompression BI_RGB. 
Microsoft, Visual Studio BMP
. 
. 
. 3.4. 
, .
DIB 4 8 /
RLE (RunLength
Encoding). 8
, ,
. 

, .
RLE [6].
BITMAPINFOHEADER biSizeImage,
. biCompression 
BI_RGB, biSizeImage . GDI 
, .
RLE, JPEG PNG
.
biXPelsPerMeter biYPelsPerMeter , ,

. , 
, 
.
biClrUsed . DIB
, 256, biClrUsed
, . 3.4. 
BMP, , 
. 
DIB, .
biClrImportant ,
. ,
.
, BITMAPINFOHEADER 
3 . Win32

180

3. GDI. , ,

API, Windows 3.1. , , 


Windows 95 Windows NT 4.0, 4, 
Windows 98 Windows 2000 5.
Windows 95 Windows NT 4.0 BITMAPV4HEADER,
Windows 98 Windows 2000 BITMAPV5HEADER.
BITMAPINFOHEADER. 4
RGBA1, , 
 ( ICM 1.02). 5
,
, ICM 2.0.
MSDN.

RGBQUAD.
:
typedef struct tagRGBQUAD
BYTE
rgbBlue;
BYTE
rgbGreen;
BYTE
rgbRed;
BYTE
rgbReserved;
} RGBQUAD;

,
. 
.
DIB,
256 . aBitmapBits
. DIB
True Color (Hi Color), , , .

, True Color, .
biClrUsed
. ,
.

aBitmapBits. biHeight
,
, 
.
. 
.
:
bytesPerLine = ((width * bitCount + 31) / 32) * 4;

width , bitCount .
1

RGBA Red, Green, Blue Alpha.

ICM Integrated Color Management API 


, 
.

181

DIB, biCompression BI_RGB,


,
. aBitmapBits 
,
. DIB 
. 
aBitmapBits ,

. 
3.5.

-
DIB, ,
.
(packed) DIB. DIB,
bmfHeader. , DIB 
bmiHeader, , ,
( ) . 
DIB GDI BITMAPINFO. 
, 
. ,
DIB .
, Win32 API, 
DIB. , DIB
Windows.

DIB
DIB
StretchDIBits SetDIBitsToDevice.
StretchDIBits :
int

StretchDIBits(
HDC hdc,
//
int XDest,
// x-
int YDest,
// y-
int nDestWidth,
//
int nDestHeight,
//
int XSrc,
// x-
int YSrc,
// y-
int nSrcWidth,
//
int nSrcHeight,
//
CONST VOID* lpBits,
//
CONST BITMAPINFO* lpBitsInfo, //
UINT iUsage,
//
DWORD dwRop
//

);

1, DIB
, . ,
1

x y .

182

3. GDI. , ,

, 
.
,
. :
 wBmp ;


hBmp ;

xs XSrc;

ys YSrc;

ws nSrcWidth;

hs nSrcHeight;

xd XDest;

yd YDest;

wd nDestWidth;

hd nDestHeight.
, 
.
. 3.6.


3.6.
[xs, ys, ws, hs]

0, 0, wBmp, hBmp
wBmp, 0, wBmp, hBmp
0, hBmp, wBmp, hBmp
wBmp, hBmp, wBmp, hBmp
0, 0, wBmp, 1

,
,
,
,

0, 0, 1, hBmp

, [xd, yd, wd, hd],


, 
, , .

, , 
. 3.6. ,
, .

, .
, . 
, 
.
.
(bitmap
stretching mode), .
SetStretchBltMode:
int

SetStretchBltMode(HDC

hdc,

int

iStretchMode);

183

iStretchMode , . 3.7.
3.7.
( )

STRETCH_ANDSCANS
(BLACKONWHITE)

0x1

STRETCH_ORSCANS
(WHITEONBLACK)

0x2

STRETCH_DELETESCANS
(COLORONCOLOR)

0x3

STRETCH_HALFTONE (HALFTONE)

0x4

StretchDIBits.
lpBits . ,
.
lpBitsInfo .
BITMAPINFO, Win32 GDI
:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD
bmiColors[1];
} BITMAPINFO;

,
. 
 .
iUsage 
DIB_RGB_COLORS, RGB ,
DIB_PAL_COLORS, .
, dwRop, .
, 
SRCCOPY,
.

SetDIBitsToDevice. DIB ,
. ,
StretchDIBits 
SetDIBitsToDevice. 
, , 
, .
MSDN.

DIB
,
 .
, BMP.
BMP, .
DIB C++,
KDib. .

184

3. GDI. , ,

, 
. , KDib, 
, .
BMP- ANSI-
, 3.5,
ANSI, , 
BMP. ANSI
True Color 24 /. 
.
,
, SYSTEM_FONT. ,
, 
, , 256 
1.
KDib, , . 
KDib.h, KDib.cpp.
3.5. CreateCharBmp
//////////////////////////////////////////////////////////////////////
// KDib.h
#include <windows.h>
#include <fstream>
#include <string>
using namespace std;
class KDib {
public:
KDib();
~KDib();
BOOL CreateDib24(int w, int h, const char* fileName);
void StoreDib24();
BOOL LoadFromFile(const char* fileName);
void SetPixel(int x, int y, COLORREF color);
int Draw(HDC hdc, int xDst, int yDst, int wDst, int hDst,
int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop);
int GetWidth() { return width; }
int GetHeight() { return height; }
const char* GetError() { return error.c_str(); }
private:
int width;
int height;
int bytesPerLine;
BITMAPFILEHEADER fileHead;
//
BITMAPINFOHEADER infoHead;
//
BITMAPINFOHEADER* pInfoHead;
BYTE* aBitmapBits;
//
int fileHeadSize;
int infoHeadSize;
1

, 
.

185

int imageSize;
string error;
ifstream inpFile;
ofstream outFile;
};
//////////////////////////////////////////////////////////////////////
// KDib.cpp
#include "KDib.h"
KDib::KDib() {
fileHeadSize = sizeof(BITMAPFILEHEADER);
fileHead.bfType = 0x4d42;
aBitmapBits = NULL;
}
//====================================================================
KDib::~KDib() {
if (pInfoHead) delete [] pInfoHead;
if (aBitmapBits) delete [] aBitmapBits;
if (outFile) outFile.close();
}
//====================================================================
BOOL KDib::CreateDib24(int w, int h, const char* fileName) {
width = w;
height = h;
bytesPerLine = ((width * 24 + 31) / 32) * 4;
imageSize = bytesPerLine * height;
infoHeadSize = sizeof(BITMAPINFOHEADER);
fileHead.bfSize = fileHeadSize + infoHeadSize + bytesPerLine * height;
fileHead.bfOffBits = fileHeadSize + infoHeadSize;
infoHead.biSize = infoHeadSize;
infoHead.biWidth = width;
infoHead.biHeight = height;
infoHead.biPlanes = 1;
infoHead.biBitCount = 24;
infoHead.biCompression = BI_RGB;
infoHead.biSizeImage = imageSize;
aBitmapBits = new BYTE[imageSize];
memset(aBitmapBits, 0, imageSize);
outFile.open(fileName, ios::out | ios::binary | ios::trunc);
if (!outFile) return FALSE;
else return TRUE;
}
//====================================================================
BOOL KDib::LoadFromFile(const char* fileName) {
inpFile.open(fileName, ios::in | ios::binary);
if (!inpFile) {
error = " .";
return FALSE;
}
inpFile.read((char*)&fileHead, fileHeadSize);
if (fileHead.bfType != 0x4d42) {
error = " BMP-";

186

3. GDI. , ,

3.5 ()
return FALSE;
}
infoHeadSize = fileHead.bfOffBits - fileHeadSize;
int fileSize = fileHead.bfSize;
imageSize = fileSize - (fileHeadSize + infoHeadSize);
pInfoHead = (BITMAPINFOHEADER*)(new BYTE [infoHeadSize]);
inpFile.read((char*)pInfoHead, infoHeadSize);
width =
pInfoHead->biWidth;
height = pInfoHead->biHeight;
aBitmapBits = new BYTE[imageSize];
inpFile.read((char*)aBitmapBits, imageSize);
return true;
}
//====================================================================
int KDib::Draw(HDC hdc, int xDst, int yDst, int wDst, int hDst,
int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop) {
return StretchDIBits(hdc, xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc,
aBitmapBits, (CONST BITMAPINFO*)pInfoHead, DIB_RGB_COLORS, rop);
}
//====================================================================
void KDib::SetPixel(int x, int y, COLORREF color) {
int row = y;
int col = 3 * x;
aBitmapBits[row*bytesPerLine + col]
= GetBValue(color);
aBitmapBits[row*bytesPerLine + col+1] = GetGValue(color);
aBitmapBits[row*bytesPerLine + col+2] = GetRValue(color);
}
//====================================================================
void KDib::StoreDib24() {
// BMP-
outFile.write((char*)&fileHead, fileHeadSize);
outFile.write((char*)&infoHead, infoHeadSize);
//
outFile.write((char*)aBitmapBits, imageSize);
}
//////////////////////////////////////////////////////////////////////
// CreateCharBmp.cpp
#include <windows.h>
#include "KWnd.h"
#include "KDib.h"
#define ANSI_CODE 65
#define FILE_NAME "symbol.bmp"
KDib bmp;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;

187

KWnd

mainWnd("CreateCharBmp",

hInstance,

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


TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

nCmdShow,

WndProc);

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SIZE sz;
static int width, height;
COLORREF color;
int x, y;
BOOL isFileCreated;
static char line[2];
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
line[0] = ANSI_CODE;
line[1] = 0;
GetTextExtentPoint32(hDC, line, 1, &sz);
width = sz.cx;
height = tm.tmHeight;
isFileCreated =
bmp.CreateDib24(width, height, FILE_NAME);
if (!isFileCreated)
MessageBox(hWnd, " " FILE_NAME " .", "Error", MB_OK);
ReleaseDC(hWnd, hDC);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
SetBkColor(hDC, RGB(0,0,0));
SetTextColor(hDC, RGB(255,255,255));
TextOut(hDC, 0, 0, line, 1);
// ( )
// DIB
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x) {
color = GetPixel(hDC, x, height-1-y);
bmp.SetPixel(x, y, color);
}
}
bmp.StoreDib24();
EndPaint(hWnd, &ps);

188

3. GDI. , ,

3.5 ()
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

, 
KDib. , ,
DIB.
, width, height, bytesPerLine, fileHead, infoHead aBitmapBits,
. BITMAPINFOHEADER,
pInfoHead? , LoadFromFile,
, , 
new.
, , 
/ . ,
, , 
.
, 
, KDib , :
 CreateDib24 24
.
.
.
, .


SetPixel 24 .
, 
aBitmapBits. 
y x.

StoreDib24 ,
BMP.

LoadFromFile BMP ,
.
, 
, infoHeadSize.
imageSize
. 
pInfoHead
aBitmapBits. 
.

Draw ,
StretchDIBits.

189

CreateCharBmp.cpp. 
, :


bmp KDib.

ANSI_CODE, ANSI. 65
A .

FILE_NAME, BMP, 
.
WndProc,
:
 WM_CREATE
tm GetTextMetrics.
, height.
C line, 
. 
ANSI_CODE, .


, ANSI_CODE.
GetTextExtentPoint32 
line. width. 
bmp.CreateDib24 DIB 
.

WM_PAINT
. TextOut,
.


GetPixel.
bmp.SetPixel.
bmp.StoreDib24.
, 1. 
symbol.bmp, ,
. 3.6. 8 MS PAINT.
.


. 3.6. symbol.bmp

KDib. , 
LoadFromFile Draw .
1

KWnd.h KWnd.cpp, 1.2.

190

3. GDI. , ,

BMP-
, 3.6,
BMP. .
. . 
, , 
. . , 
,
.
KDib,
. ,
. KDib.h KDib.cpp
.
3.6. BmpFileViewer
//////////////////////////////////////////////////////////////////////
// BmpFileViewer.cpp
#include <windows.h>
#include "KWnd.h"
#include "KDib.h"
#define

FILE_NAME

"YoungHacker.bmp"

KDib bmp;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("BmpFileViewer", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
int dX, dY;
int ws, hs, wd, hd;
static BOOL isFileLoaded;
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
isFileLoaded = bmp.LoadFromFile(FILE_NAME);

191

if (!isFileLoaded) {
MessageBox(hWnd, " " FILE_NAME " .", "Error",
MB_OK);
MessageBox(hWnd, bmp.GetError(), "Error", MB_OK);
break;
}
// bmp
GetClientRect(hWnd, &rect);
dX = bmp.GetWidth() - rect.right;
dY = bmp.GetHeight() - rect.bottom;
GetWindowRect(hWnd, &rect);
InflateRect(&rect, dX/2, dY/2);
MoveWindow(hWnd, rect.left, rect.top,
rect.right-rect.left, rect.bottom-rect.top, TRUE);
ReleaseDC(hWnd, hDC);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
wd = ws = bmp.GetWidth();
hd = hs = bmp.GetHeight();
bmp.Draw(hDC, 0, 0, wd, hd, 0, 0, ws, hs, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

, , , ,
BMP, .
YoungHacker.bmp. ?
www.piter.com 
. 
. , BMP,
.
.
, . 3.7.
bmp.Draw,
StretchDIBits. , 
( ) 
.

StretchDIBits. .
:
int xd0, yd0, xd1, yd1, xd2, yd2, xd3, yd3;

192

3. GDI. , ,

. 3.7. YoungHacker.bmp BmpFileViewer

. 3.8. BmpFileViewer

193

WM_PAINT :
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
ws = bmp.GetWidth();
hs = bmp.GetHeight();
wd = ws/2 - 4;
hd = hs/2 - 4;
xd0 = 2;
yd0 = 2;
xd1 = ws/2 + 2; yd1 = 2;
xd2 = 2;
yd2 = hs/2 + 2;
xd3 = ws/2 + 2; yd3 = hs/2 + 2;
SetStretchBltMode(hDC, STRETCH_HALFTONE);
bmp.Draw(hDC, xd0, yd0, wd, hd, ws, 0, -ws, hs, SRCCOPY);
bmp.Draw(hDC, xd1, yd1, wd, hd, 0, 0, ws, hs, SRCCOPY);
bmp.Draw(hDC, xd2, yd2, wd, hd, ws, hs, -ws, -hs, SRCCOPY);
bmp.Draw(hDC, xd3, yd3, wd, hd, 0, hs, ws, -hs, SRCCOPY);
EndPaint(hWnd, &ps);
return 0;

, . 3.8.

-
 (DDB) GDI, 
GDI . 
, . DDB
Windows
GDI.
GDI, HBITMAP. DDB 
GDI. , DDB ,

.

DDB-
Win32 GDI GDI:
HBITMAP
UINT
HBITMAP
HBITMAP

CreateBitmap(int nWidth, int nHeight, UINT cPlanes,


cBitsPerPel, CONST VOID* lpvBits);
CreateBitmapIndirect(CONST BITMAP* lpbm);
CreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight);

CreateBitmap DDB nWidth,


nHeight, cPlanes, cBitsPerPel,
lpvBits.
cPlanes cBitsPerPel . 
, GDI
cPlanes cBitsPerPel /.
CreateBitmapIndirect , 
BITMAP:
typedef struct tagBITMAP {
LONG
bmType;
// ( 0)
LONG
bmWidth;
//
LONG
bmHeight;
//

194

3. GDI. , ,
LONG

bmWidthBytes; //
//( )
WORD
bmPlanes;
//
WORD
bmBitsPixel;
//
LPVOID bmBits;
//
} BITMAP;

, ,
.
, , ,
. lpvBits
lpbm.bmBits NULL. ,
, , 
,
.
CreateCompatibleBitmap DDB
, 
hdc. , , 
.

DDB- DIB
, 
DDB.  
. 
GDI CreateDIBitmap,
DDB DIB, , , DIB DDB.
:
HBITMAP CreateDIBitmap(HDC hdc,
CONST BITMAPINFOHEADER* lpbmih,
DWORD fdwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi,
UINT fuUsage);

DDB, 
hdc, DIB DDB. lpbmih
DIB. fdwInit 
DDB. CBM_INIT,
DIB, 
. lpbInit , lpbmi 
DIB, BITMAPINFO.
, fuUsage, ,
(DIB_PAL_COLORS) RGB (DIB_RGB_COLORS).
, , ,
DIB , , , 3.6,
. StretchDIBits ( KDib
Draw). CreateDIBitmap
DIB, , DDB,
BitBlt (
DDB ). :
?
DDB
.

195

DDB-
Windows DIB (BMP)
1, LoadBitmap,
HBITMAP:
HBITMAP LoadBitmap(
HINSTANCE hInstance,
LPCTSTR lpBitmapName
);

//
//

5,
, szBmpName1, ,
IDB_1. lpBitmapName
szBmpName1, , 
LPCTSTR MAKEINTRESOURCE, 
MAKEINTRESOURCE(IDB_1).
Win32 DIB
. LoadBitmap , ,
DIB DDB
, .
LoadBitmap 5.4 
12.1.
LoadBitmap 
, 
Win32 API. hInstance NULL,
OBM_BTNCORNERS, OBM_BTSIZE
.

DDB- BMP-
 , 
BMP, 
LoadImage, , .
:
HANDLE LoadImage(
HINSTANCE hinst,
LPCTSTR lpszName,
UINT uType,
int cxDesired,
int cyDesired,
UINT fuLoad
);

//
//
//
//
//
//

lpszName,
fuLoad LR_LOADFROMFILE, uType
IMAGE_BITMAP. cxDesired cyDesired
.

DDB. , 
NULL.
LoadImage 3.7.
1

Windows 5.

196

3. GDI. , ,


DDB 
, .
GetObject,
:
int GetObject(
HGDIOBJ hgdiobj,
int cbBuffer,
LPVOID lpvObject
);

//
//
//

, hgdiobj 
, , , ,
HBITMAP.
lpvObject. . 3.7 , 
.
3.7. , lpvObject

HBITMAP

BITMAP

HBITMAP,
CreateDIBSection

DIBSECTION, cbBuffer
sizeof(DIBSECTION), BITMAP, cbBuffer
sizeof(BITMAP)

HPALETTE

WORD

HPEN

LOGPEN

HPEN,
ExtCreatePen

EXTLOGPEN

HBRUSH

LOGBRUSH

HFONT

LOGFONT

lpvObject NULL, 
, lpvObject
.
lpvObject NULL,
. 
.
GetObject HBITMAP, 
,
. bmBits BITMAP
.

DDB-
DDB Windows
, Win32 API DDB.
GDI DDB , 
(
) ().

, .

197

? 
,
. GDI 
( ). 2 
. ,
:
HDC CreateCompatibleDC (HDC hdc);

hdc ,
. CreateCompatibleDC 
, . hdc
, 
. NULL,
, . 
, .
,
. ,
, DDB SelectObject.
DDB hBitmap 
hDC
:
//
HDC hMemDC;
//
hMemDC = CreateCompatibleDC(hDC);
// DDB-
SelectObject(hMemDC, hBitmap);
// hMemDC hDC
BitBlt(hDC, 0, 0, bmpWidth, bmpHeight, hMemDC, 0, 0, SRCCOPY);
//
DeleteDC(hMemDC);

,  
. 
hDC hMemDC, DDB.


1 GDI BitBlt StretchBlt. 
.
BitBlt bit block transfer,
. BitBlt
, .
256 .
:
BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop);

BitBlt 
 hdcSrc  hdcDest.
nXSrc, nYSrc, nWidth, nHeight
1

198

3. GDI. , ,

.
nXDest, nYDest, nWidth, nHeight 
. 
RC_BITBLT.
, 
nWidth
nHeight.   
MM_TEXT,
,
.

. 
.
 
. BitBlt 
, .
dwRop , 
, 
. ,
SRCCOPY,
.
StretchBlt :
BOOL StretchBlt(HDC hdcDest, int nXDest, int nYDest, int nWidthDest,
int nHeightDest, HDC hdcSrc, int nXSrc, int nYSrc, int nWidthSrc,
int nHeightSrc, DWORD dwRop);

, BitBlt, 

. 
,
.
, StretchDIBits,
( ) 
, . 3.6.

DDB
, 3.7, DDB BMP
, . ,
, BmpFileViewer (. 3.6), 
.
3.7. BmpFileViewer2
//////////////////////////////////////////////////////////////////////
// BmpFileViewer2.cpp
#include <windows.h>
#include "KWnd.h"
#define

FILE_NAME

"YoungHacker.bmp"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

199

//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("BmpFileViewer2", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
static int bmpWidth, bmpHeight;
static HBITMAP hBitmap;
//
HINSTANCE hInst;
HDC hMemDC;
//
BITMAP bm;
int dX, dY;
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
hInst = (HINSTANCE)GetClassLong(hWnd, GCL_HMODULE);
hBitmap = (HBITMAP)LoadImage(hInst, FILE_NAME, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
if (hBitmap == NULL) {
MessageBox(hWnd, " " FILE_NAME " ", "Error", MB_OK);
break;
}
GetObject(hBitmap, sizeof(bm), &bm);
bmpWidth = bm.bmWidth;
bmpHeight = bm.bmHeight;
// hBitmap
GetClientRect(hWnd, &rect);
dX = bmpWidth - rect.right;
dY = bmpHeight - rect.bottom;
GetWindowRect(hWnd, &rect);
InflateRect(&rect, dX/2, dY/2);
MoveWindow(hWnd, rect.left, rect.top,
rect.right-rect.left, rect.bottom-rect.top, TRUE);
ReleaseDC(hWnd, hDC);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
//
hMemDC = CreateCompatibleDC(hDC);

200

3. GDI. , ,

3.7. ()
// hBitmap
SelectObject(hMemDC, hBitmap);
// hMemDC hDC
BitBlt(hDC, 0, 0, bmpWidth, bmpHeight, hMemDC, 0, 0, SRCCOPY);
DeleteDC(hMemDC);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

. , DDB
hBitmap WM_CREATE
LoadImage. hInst,
LoadImage,
GetClassLong(hWnd, GCL_HMODULE). 
GetObject.

WM_PAINT .
( ) hMemDC,
hBitmap.
BitBlt. .
, 
BmpFileViewer (. . 3.7).

DIB-

. DDB DIB . 3.8.
3.8. DDB DIB

DDB

DIB

GDI

48 M ( )

(
)

Win32 API , DDB


DIB.

201

DIB (DIB section) DIB, 


, 
GDI. DIB 
, , ,
Windows . , ,
DIB.
DIB,  , GDI. 
GDI DIB,
HBITMAP. DIB,
DeleteObject, .

DIB-
DIB CreateDIBSection:
HBITMAP CreateDIBSection(
HDC hdc,
//
CONST BITMAPINFO* pbmi, //
UINT iUsage,
//
VOID** ppvBits,
//
HANDLE hSection, // ,
DWORD dwOffset
//
);


BITMAPINFO, . 
, , . DIB
BI_RGB, .
, , , 
.
iUsage , bmiColors, 
BITMAPINFO. iUsage 
DIB_PAL_COLORS, bmiColors
. DIB_RGB_COLORS , 
RGB.
ppvBits , GDI 
DIB.
hSection NULL. GDI
, dwOffset 
. hSection NULL,
, ,
CreateFileMapping PAGE_READWRITE PAGE_WRITECOPY. 
, 
dwOffset.


,
DIB (. KDib 3.5).
DIB
KDibSection, 12, 
(. 12.4).

202

3. GDI. , ,

DIB-
DIB 
:
 DIB StretchDIBits SetDIBitsToDevice;
GDI, hBitmap, 
BitBlt StretchBlt.
DIB ArincReceiver (
12, 12.4).



, dwRop, BitBlt, PatBlt StretchBlt
, GDI, 
 
. 
. ,
.
Win32 API 256 ROP (rasteroperation codes).
32 DWORD.
256 ,
, 
.
Microsoft 
256. , ,
.
. 3.9, : P
(pattern), S (source), D (destination).
3.9.
Pattern:
Source:
Destination:

11110000
11001100
10101010

ROP-

0
0
0
0
0
0
0
1
1
1
1
1
1
1

D=0
D = ~(S | D)
D = ~S
D = S & ~D
D = ~D
D=P^D
D=S^D
D=S&D
D = ~S | D
D=P&S
D=S
D=S|D
D=P
D = P | ~S | D

0x00000042
0x001100A6
0x00330008
0x00440328
0x00550009
0x005A0049
0x00660046
0x008800C6
0x00BB0226
0x00C000CA
0x00CC0020
0x00EE0086
0x00F00021
0x00FB0A09

BLACKNESS
NOTSRCERASE
NOTSRCCOPY
SRCERASE
DSTINVERT
PATINVERT
SRCINVERT
SRCAND
MERGEPAINT
MERGECOPY
SRCCOPY
SRCPAINT
PATCOPY
PATPAINT

D=1

0x00FF0062

WHITENESS

0
0
0
1
1
1
1
0
0
1
1
1
1
1

0
0
1
0
0
0
1
0
1
0
0
1
1
1

0
1
1
0
1
1
0
0
1
0
0
0
1
1

0000
0001
0011
0100
0101
1010
0110
1000
1011
0000
1100
1110
0000
1011

11111111

203

MSDN
(Platform SDKWindows GDITernary Raster Operations).
, 
. , 
, ROP.
. 3.9 ,
. 
.


BLACKNESS WHITENESS , ,
. 
. (Black) (White)
, 0,
1. C 
:
Black
Black
Black
White
White
White

AND C
OR C
XOR C
AND C
OR C
XOR C

=
=
=
=
=
=

Black
C
C
C
White
NOT C


.

,
SRCCOPY NOTSRCCOPY.
SRCCOPY .
. 
.
NOTSRCCOPY , 
.

,
DSTINVERT .

,
. 3.9 PATINVERT PATCOPY. 16 
, ,
. GDI 
, :
BOOL PatBlt(HDC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight,
DWORD dwRop);

PatBlt 
. ROP 1, 
, , . 3.9.
1

. MSDN.

204

3. GDI. , ,

,
NOTSRCERASE, SRCERASE, SRCINVERT, SRCAND, MERGEPAINT
SRCPAINT. , SRCINVERT SRCAND 
Windows .
, , , 
Windows.
Shell32.dll1. , 
LoadLibrary, 
(hShell32),
. , , 
hShell32. LoadImage.
, LoadImage 12, 
, CDROM.
LoadImage
hIcon.
GetIconInfo(hIcon, &iconInfo);

, 
iconInfo ICONINFO. :
HBITMAP hbmMask;
HBITMAP hbmColor;

,
, ,
. . 3.9 
CDROM.

. 3.9. CD-ROM

48 48. ?
, 
, .
,
. 
.
, 3.8, ,
.
3.8. DrawIconWithRop
//////////////////////////////////////////////////////////////////////
// DrawIconWithRop.cpp
#include <windows.h>
1

5.

205

#include

"KWnd.h"

#define ICON_ID

12

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Draw icon with ROP", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
static HINSTANCE hShell32;
ICONINFO iconInfo;
BITMAP bmp;
HICON hIcon;
HDC hMemDC;
int x = 20, y = 20;
switch (uMsg)
{
case WM_CREATE:
hShell32 = LoadLibrary("Shell32.dll");
SetClassLong(hWnd, GCL_HBRBACKGROUND,
(LONG)CreateSolidBrush (RGB(180,140,200)));
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
hMemDC = CreateCompatibleDC(hDC);
hIcon = (HICON)LoadImage(hShell32, MAKEINTRESOURCE(ICON_ID),
IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
if (!hIcon) {
MessageBox(hWnd, " ", "Error", MB_OK);
break;
}
GetIconInfo(hIcon, &iconInfo);
GetObject(iconInfo.hbmMask, sizeof(bmp), &bmp);
//
SelectObject(hMemDC, iconInfo.hbmMask);
BitBlt(hDC, x, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
//

206

3. GDI. , ,

3.8 ()
SelectObject(hMemDC, iconInfo.hbmColor);
BitBlt(hDC, x+60, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0,
SRCCOPY);
//
SelectObject(hMemDC, iconInfo.hbmMask);
BitBlt(hDC, x+120, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0,
SRCAND);
SelectObject(hMemDC, iconInfo.hbmColor);
BitBlt(hDC, x+120, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0,
SRCINVERT);
// DrawIcon
DrawIcon(hDC, x+188, y, hIcon);
DeleteObject(hMemDC);
DestroyIcon(hIcon);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

BitBlt
SRCAND . 
, .
, BitBlt 
SRCINVERT.
. 3.10. 
: (), (), (),
, (), 
DrawIcon, 
32 32 .

. 3.10. DrawIconWithRop

GDI, 
. ,
. ,

207

,
, , , ,
.
,
GDI. 
, 
,
, .

, 
. , 
. 
, .

,
. 
.
16 WMF1 Windows 2.0.
 
, 
. Win32 32 EMF (Enhanced Metafile
Format). 
, 
. , 32 . Win32
API WMF EMF.
EMF,
.


GDI, , ,
DIB. 
HENHMETAFILE.
GDI
, .
CreateEnhMetaFile:
HDC CreateEnhMetaFile(HDC hdcRef, LPCTSTR lpFilename, CONST RECT* lpRect,
LPCTSTR lpDescription);

, hdcRef, ,
EMF.
NULL, GDI .
, lpFilename,
NULL. NULL, . 
, DeleteEnhMetaFile
.
1

WMF Windows Metafile Format.

208

3. GDI. , ,

, lpRect, 
0,01 . NULL, GDI
.
, lpDescription, 
, .
, . 
.
CreateEnhMetaFile
. GDI
.
, CloseEnhMetaFile, 

. 
.
,
CreateEnhMetaFile,
DeleteEnhMetaFile, .
,
3.9. CreateMetaFile
, ,
,
.
3.9. CreateMetaFile
//////////////////////////////////////////////////////////////////////
// CreateMetaFile.cpp
#include <windows.h>
#include "KWnd.h"
#define FILE_NAME "Pict1.emf"
void DrawSomething(HDC);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("CreateMetaFile", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;


static HDC hdcEMF;
HENHMETAFILE hemf;
switch (uMsg)
{
case WM_CREATE:
hdcEMF = CreateEnhMetaFile(NULL, FILE_NAME, NULL,
"CreateMetaFile\0Pict1\0");
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
DrawSomething(hDC);
DrawSomething(hdcEMF);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
hemf = CloseEnhMetaFile(hdcEMF);
DeleteEnhMetaFile(hemf);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////
void DrawSomething(HDC hdc) {
RECT r;
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
SetRect(&r, 20, 20, 220, 220);
hPen = CreatePen(PS_SOLID, 10, RGB(255, 160, 140));
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateSolidBrush(RGB(140, 160, 255));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
Rectangle(hdc, r.left, r.top, r.right, r.bottom);
hPen = CreatePen(PS_SOLID, 3, RGB(0, 255, 0));
SelectObject(hdc, hPen);
hBrush = CreateSolidBrush(RGB(100, 100, 100));
SelectObject(hdc, hBrush);
InflateRect(&r, -40, -40);
Ellipse(hdc, r.left, r.top, r.right, r.bottom);
SetTextColor(hdc, RGB(255, 255, 255));
SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, "YES !", -1, &r, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
DeleteObject(SelectObject(hdc, hOldPen));
DeleteObject(SelectObject(hdc, hOldBrush));
}
//////////////////////////////////////////////////////////////////////

209

210

3. GDI. , ,


WM_CREATE. hdcEMF static, 
, 
.
DrawSomething,
hdc, .
, 
200 200 , ,
.
WM_PAINT DrawSomething 
: , .
WM_DESTROY :
hemf = CloseEnhMetaFile(hdcEMF);
DeleteEnhMetaFile(hemf);

.
. 
, . 3.11.
True Color, , ,  , 
 , , 
,  ,  .

. 3.11. CreateMetaFile

, .
. 
Pict1.emf. .
,
EMF, , ACDSee.


PlayEnhMetaFile, 
:
BOOL PlayEnhMetaFile(HDC hdc, HENHMETAFILE hemf, CONST RECT* lpRect);

, hdc, . 
.

hdc.

211

, .
GetEnhMetaFileHeader:
HENHMETAFILE GetEnhMetaFile(LPCTSTR lpszMetaFile);

lpszMetaFile.
, lpszMetaFile
.
: 
PlayEnhMetaFile? 
GetEnhMetaFileHeader,
ENHMETAHEADER, rclBounds 
.
3.10 ,
Pict1.emf.
PlayMetaFile.
3.10. PlayMetaFile
//////////////////////////////////////////////////////////////////////
//
PlayMetaFile.cpp
#include <windows.h>
#include "KWnd.h"
#define FILE_NAME "Pict1.emf"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("PlayMetaFile", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
HENHMETAFILE hemf;
ENHMETAHEADER emh;
int x1, y1, x2, y2;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
hemf = GetEnhMetaFile(FILE_NAME);

212

3. GDI. , ,

3.10 ()
if (!hemf)
MessageBox(hWnd, " " FILE_NAME " .", "Error", MB_OK);
else {
GetEnhMetaFileHeader(hemf, sizeof(ENHMETAHEADER), &emh);
x1 = emh.rclBounds.left; y1 = emh.rclBounds.top;
x2 = emh.rclBounds.right; y2 = emh.rclBounds.bottom;
SetRect(&rect, x1, y1, x2, y2);
PlayEnhMetaFile(hDC, hemf, &rect);
DeleteEnhMetaFile(hemf);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////


,
SetRect(&rect, x1, y1, x2, y2);

:
SetRect(&rect,
SetRect(&rect,
SetRect(&rect,
SetRect(&rect,

x1,
x1,
x1,
x1,

y1,
y1,
y1,
y1,

2 * x2, y2);
x2, 2 * y2);
2 * x2, 2 * y2);
0.5* x2, 0.5 * y2);

, .

213

, Windows,
, 
. 
, , ,
. 

. , , 
, . Win32 API 
.

Windows , 
, . 
. 
1.
. 4.1 , 
.

. 4.1.
1

, 
.

214

4.

,
  .  (scan
code) , 
1. 
,
.  
(virtualkey code). ,
Windows 
. , 
, /
. .
Windows
, .
,
.


, Windows,
. 
,
. Windows , 
. (keyboard focus) ,
,
. , ,
.
.
, 
. ,
. , Windows 
.
,
. , 
, , ,
.  ,
. , ,
, , .
, . Windows
,
, ,
.
WM_SETFOCUS WM_KILLFOCUS, 
. 
, ,
.
1

 OEM (Original Equipment Manufacturer


Scan Code).

215

:
HWND SetFocus(HWND hWnd) hWnd,
, .

HWND GetFocus() ,
.


, 
,
.

, . , 
, 
. ANSI1.
. 
, .
, , 
,
.
:
  Caps Lock, Num Lock, Scroll Lock 
Insert. ,
. , 
.


Shift, Ctrl Alt.


. 
.

, , ,
, Pause, Delete.

, , , Tab, Backspace,
Esc Enter. , Tab, Backspace, Esc Enter 
.
, Windows,
(keystrokes) (characters). 

.



. 4.1.
.
SYS .
1

. 2, .

216

4.

4.1.

WM_KEYDOWN

WM_KEYUP

WM_SYSKEYDOWN

WM_SYSKEYUP

WM_SYSKEYDOWN WM_SYSKEYUP,
Alt, Windows,
. 
. ,
(Alt + Tab), (Alt
). Windows 
Alt, , , 
. 
,
(, ).
.
,
, Windows WM_KEYDOWN
WM_KEYUP, , , .
32 lParam,
, 6 (. 4.2).
4.2. lParam

15 . . . 0

. ,
, .
WM_KEYUP

23 . . . 16

C-

- OEM

24

1 IBM ( , Alt Ctrl


)

29

1, Alt ( WM_KEYDOWN WM_KEYUP 0 )

30

, , ,

31

, , ,

lParam
, wParam,
.
(virtual key code) 
. 
winuser.h. . 4.3
.

217

4.3.

IBM

03

VK_CANCEL

Ctrl + Break

08

VK_BACK

Backspace

09

VK_TAB

Tab

13

0D

VK_RETURN

Enter

16

10

VK_SHIFT

Shift

17

11

VK_CONTROL

Ctrl

18

12

VK_MENU

Alt

19

13

VK_PAUSE

Pause

20

14

VK_CAPITAL

Caps Lock

27

1B

VK_ESCAPE

Esc

32

20

VK_SPACE

33

21

VK_PRIOR

Page Up

34

22

VK_NEXT

Page Down

35

23

VK_END

End

36

24

VK_HOME

Home

37

25

VK_LEFT

38

26

VK_UP

39

27

VK_RIGHT

40

28

VK_DOWN

44

2C

VK_SNAPSHOT

Print Screen

45

2D

VK_INSERT

Insert

46

2E

VK_DELETE

4857

3039

6590

415A

112123

707B

Delete
09 (
)
AZ

VK_F1VK_F12

F1F12

144

90

VK_NUMLOCK

Num Lock

145

91

VK_SCROLL

Scroll Lock


, . ,
WM_KEYDOWN,
, Shift 
. 
. ,
, WM_CHAR.


,
. 
, , 

218

4.

. TranslateMessage,
, WinMain 

while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

, GetMessage 
msg, DispatchMessage 
.
TranslateMessage,

. WM_KEYDOWN,
 
, TranslateMessage .
WM_KEYDOWN 
WM_CHAR WM_DEADCHAR.
WM_DEADCHAR.

(dead keys), ,
, . 
, . ,
U (U)
, U. , 
WM_DEADCHAR, Windows
, WM_CHAR,
ANSI .
, 
WM_CHAR. lParam WM_CHAR,
, , lParam
. wParam ANSI.

. , Caps
Lock 1, A, 
:

WM_KEYDOWN

WM_CHAR

ANSI- a

WM_KEYUP

, Shift, A,
A Shift,
:
1

 Caps Lock
<Caps Lock>.

219

WM_KEYDOWN
WM_KEYDOWN
WM_CHAR
WM_KEYUP

VK_SHIFT
A
ANSI- A
A

WM_KEYUP

VK_SHIFT



. , 
, , 
. , 
,
.
Win32 API ,
:
 CreateCaret .


SetCaretPos .

ShowCaret .

HideCaret .

DestroyCaret .

WM_CREATE WM_DESTROY.

. ,
, . 
, , 
WM_SETFOCUS WM_KILLFOCUS.
.
CreateCaret WM_SETFOCUS
DestroyCaret WM_KILLFOCUS.
CreateCaret, 
:


BOOL CreateCaret(HWND hWnd, HBITMAP hBitmap, int nWidth, int nHeight);

,
.
.
, NULL.
hBitmap NULL, 
nWidth nHeight, .
hBitmap , ,
NULL,  
, . 
.

220

4.

hBitmap , 
. nWidth nHeight .
nWidth nHeight
. . nWidth 
,
, . nHeight 
, , 
1.
CreateCaret
. .
CreateCaret .
, ShowCaret.
DestroyCaret
HideCaret.


Typer, 4.1,
. 
.
, , 
Enter, 
, , 
, .
, ,
.
, ,
string C++
C. 
,
.
string,
:
#include <string>
using namespace std;

( string) 
:
static string text;

static 
text 2.
, string, 
, .
1


GetSystemMetrics (SM_CXBORDER) GetSystemMetrics (SM_CYBORDER) .

, static,
WndProc.

221

symb 
+= :
text += symb;

insert symb
index:
text.insert(index, symb);

n , index, erase:
text.erase(index, n);


size, , , :
nLines = text.size() / nCharPerLine;

, text
C c_str. TextOut,
C.
WM_KEYDOWN, WM_CHAR, WM_SETFOCUS,
WM_KILLFOCUS, Typer 
. 
.
4.1. Typer1
//////////////////////////////////////////////////////////////////////
// Typer.cpp
#include <windows.h>
#include <string>
using namespace std;
#include KWnd.h
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd(Typer, hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;

KWnd.h KWnd.cpp, 1.2 (


1).

222

4.

4.1 ()
TEXTMETRIC tm;
static string text; //
string symb;
static int cxChar, cyChar, cxClient, cyClient;
static int nCharPerLine, nClientLines;
static int xCaret = 0, yCaret = 0;
int curIndex;
int nLines; //
int nTailChar; //
int x, y, i;
switch (uMsg) {
case WM_CREATE:
hDC = GetDC(hWnd);
SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hDC, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight;
ReleaseDC(hWnd, hDC);
break;
case WM_SIZE:
//
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
// ( 'x') ( 'y')
nCharPerLine = max(1, cxClient / cxChar);
nClientLines = max(1, cyClient / cyChar);
if (hWnd == GetFocus())
SetCaretPos(xCaret * cxChar, yCaret * cyChar);
break;
case WM_SETFOCUS:
//
CreateCaret(hWnd, NULL, 0, cyChar);
SetCaretPos(xCaret * cxChar, yCaret * cyChar);
ShowCaret(hWnd);
break;
case WM_KILLFOCUS:
//
HideCaret(hWnd);
DestroyCaret();
break;
case WM_KEYDOWN:
nLines = text.size() / nCharPerLine;
nTailChar = text.size() % nCharPerLine;
switch (wParam) {
case VK_HOME:

xCaret = 0;
break;

223

case VK_END:

if (yCaret == nLines)
xCaret = nTailChar;
else
xCaret = nCharPerLine - 1;
break;
case VK_PRIOR: yCaret = 0;
break;
case VK_NEXT:
yCaret = nLines;
xCaret = nTailChar;
break;
case VK_LEFT:
xCaret = max(xCaret - 1, 0);
break;
case VK_RIGHT: xCaret = min(xCaret + 1, nCharPerLine - 1);
if ((yCaret == nLines) && (xCaret > nTailChar))
xCaret = nTailChar;
break;
case VK_UP:
yCaret = max(yCaret - 1, 0);
break;
case VK_DOWN:
yCaret = min(yCaret + 1, nLines);
if ((yCaret == nLines) && (xCaret > nTailChar))
xCaret = nTailChar;
break;
case VK_DELETE: curIndex = yCaret * nCharPerLine + xCaret;
if (curIndex < text.size()) {
text.erase(curIndex, 1);
InvalidateRect(hWnd, NULL, TRUE);
}
break;
}
SetCaretPos(xCaret * cxChar, yCaret * cyChar);
break;
case WM_CHAR:
switch (wParam) {
case '\b': // 'backspace'
if (xCaret > 0) {
xCaret--;
SendMessage(hWnd, WM_KEYDOWN, VK_DELETE, 1);
}
break;
case '\t': // 'tab'
do { SendMessage(hWnd, WM_CHAR, ' ', 1L); }
while (xCaret % 8 != 0);
break;
case '\r': case '\n': //
for (i = 0; i < nCharPerLine - xCaret; ++i)
text += ' ';
xCaret = 0;
if (++yCaret == nClientLines) {
MessageBox(hWnd, " ", "Error", MB_OK);
yCaret--;
}

224

4.

4.1 ()
break;
default: //
curIndex = yCaret * nCharPerLine + xCaret;
if (curIndex == text.size())
text += (char)wParam;
else {
symb = (char)wParam;
text.insert(curIndex, symb);
}
InvalidateRect(hWnd, NULL, TRUE);
if (++xCaret == nCharPerLine) {
xCaret = 0;
if (++yCaret == nClientLines) {
MessageBox(hWnd, " ", "Error", MB_OK);
yCaret--;
}
}
break;
}
SetCaretPos(xCaret * cxChar, yCaret * cyChar);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
if (text.size()) {
nLines = text.size() / nCharPerLine;
nTailChar = text.size() % nCharPerLine;
for (y = 0; y < nLines; ++y)
TextOut(hDC, 0, y*cyChar, text.c_str() + y*nCharPerLine,
nCharPerLine);
TextOut(hDC, 0, y*cyChar, text.c_str() + y*nCharPerLine,
nTailChar);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

, 
Typer. . 
WM_SETFOCUS :

225

CreateCaret(hWnd, NULL, 0, cyChar);


CreateCaret(hWnd, 1, 0, cyChar);


CreateCaret(hWnd, 1, 10, cyChar);

, .

. Win32
API , ,
. 
GetSystemMetrics:
fMouse = GetSystemMetrics (SM_MOUSEPRESENT);

, fMouse TRUE. 
:
cButtons = GetSystemMetrics (SM_CMOUSEBUTTONS);

, .
, ,
. 
,
, .
.
, , 
, .

Windows, Microsoft IntelliMouse. 
, 
, 
, .
.
, , ,
.
, ,
, 
.

GetSystemMetrics:
fMouseWheel = GetSystemMetrics(SM_MOUSEWHEELPRESENT);

TRUE, .
, 
Windows , ,
.
,
.

226

4.

,
, Windows 
, (mouse
cursor).
(hot spot) ,
. ,
. ,
(IDC_ARROW) . 
, (IDC_CROSS), 
.
, , ,
. ,
:
wc.hCursor = LoadCursor(NULL, IDC_ARROW);


:
.

.
, .
,
Windows, LBUTTON, MBUTTON RBUTTON.
. 
.



, , Windows 
, . 
Windows . 
, , ,
.
,
WM_MOUSEMOVE. 
,
:

( )

WM_LBUTTONDOWN

WM_LBUTTONUP

WM_LBUTTONDBLCLK

WM_MBUTTONDOWN

WM_MBUTTONUP

WM_MBUTTONDBLCLK

WM_RBUTTONDOWN

WM_RBUTTONUP

WM_RBUTTONDBLCLK

lParam
. x,
y.
. lParam 
LOWORD HIWORD.

227

wParam Shift
Ctrl. wParam 
:

MK_LBUTTON

MK_MBUTTON

MK_RBUTTON

MK_SHIFT

Shift

MK_CONTROL

Ctrl


, Windows ,
WM_LBUTTONDOWN.


,
. 

(Mouse), .
,
(DBLCLK) ,
CS_DBLCLKS. 
style WNDCLASS , . 
, KWnd,
:
style = GetClassLong(hWnd, GCL_STYLE);
SetClassLong(hWnd, GCL_STYLE, style | CS_DBLCLKS);

CS_DBLCLKS
, 
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDOWN WM_LBUTTONUP.
CS_DBLCLKS, 
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_ LBUTTONDBLCLK WM_LBUTTONUP. ,
WM_LBUTTONDOWN WM_LBUTTONDBLCLK.
WM_LBUTTONDBLCLK 4.4.


Windows ,
.
WM_MOUSEWHEEL.
,
:
#include <zmouse.h>

zmouse.h .

228

4.

wParam WM_MOUSEWHEEL 
, ,
Shift Ctrl.
wParam , 
, .
, WHEEL_DELTA.
zmouse.h 120.
WM_MOUSEWHEEL ,
4.5.
.


, , 
.
, ,
, , , .
, .
Scribble ( 4.2).
4.2. Scribble
//////////////////////////////////////////////////////////////////////
// Scribble.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Scribble", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HDC hDC;
static int x, y; //
static BOOL bTracking = FALSE;
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);

229

break;
case WM_LBUTTONDOWN:
bTracking = TRUE;
//
x = LOWORD(lParam);
y = HIWORD(lParam);
MoveToEx(hDC, x, y, NULL);
break;
case WM_LBUTTONUP:
bTracking = FALSE;
break;
case WM_MOUSEMOVE:
if (bTracking) {
//
x = LOWORD(lParam);
y = HIWORD(lParam);
LineTo(hDC, x, y);
}
break;
case WM_DESTROY:
ReleaseDC(hWnd, hDC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////


. , WM_LBUTTONDOWN,
bTracking TRUE
MoveToEx.
WM_MOUSEMOVE
. , bTracking 
FALSE .
, 
MoveToEx LineTo. hDC
static. .
GetDC WM_CREATE,
ReleaseDC WM_DESTROY. .

, , 
WM_PAINT. ,
.
hDC ,
,
LineTo, WndProc.

230

4.

. 4.2 Scribble.

. 4.2. Scribble

?.. , 
, ! ,
WM_PAINT, 
!
.
WM_PAINT? 
! , 
. ,
, 
. , 
.
vector 
STL. vector , , 
,
. string vector
.
vector,
:
#include <vector>
using namespace std;

vector ,
, :
vector<int> v1; // v1 - int

, , vector, 
, .
v1, , ,
. 
push_back:
v1.push_back(value);

int v1 
value.

231


size.
,
, , 
.

v1:
vector<int>::iterator it; // it vector<int>
for (it = v1.begin(); it != v1.end(); ++it) {
// *it it
}

begin() , v1,
end() , ,
v1.
, 
clear.
vector , 
.
, 
.
x y. Win32 API POINT,
. , ,
:
static vector<POINT> curve;

, . , ,
POINT , 
1 POINT(x, y), 
:
curve.push_back(POINT(x, y));

, Point, 
:
struct Point {
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
int x;
int y;
};

,
, :
static vector<Point> curve;

, ,
WM_LBUTTONUP. 
curve curves, 
curve:
static vector<vector<Point> > curves;
1

, ,
(public). ,
.

232

4.

 curves .
vector<Point>.
. , 
.
ScribbleAdvanced, Scribble,
4.3.
4.3. ScribbleAdvanced
//////////////////////////////////////////////////////////////////////
// ScribbleAdvanced.cpp
#include <windows.h>
#include <vector>
using namespace std;
#include "KWnd.h"
struct Point {
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
int x;
int y;
};
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("ScribbleAdvanced", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HDC hDC; //
HDC hdc; //
// WM_PAINT
PAINTSTRUCT ps;
static int x, y; //
static BOOL bTracking = FALSE;
static vector<Point> curve;
static vector<vector<Point> > curves;
vector<Point>::iterator it;
int i, j;
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);

233

break;
case WM_LBUTTONDOWN:
bTracking = TRUE;
//
x = LOWORD(lParam);
y = HIWORD(lParam);
MoveToEx(hDC, x, y, NULL);
curve.push_back(Point(x, y));
break;
case WM_LBUTTONUP:
if (bTracking) {
bTracking = FALSE;
curves.push_back(curve);
curve.clear();
}
break;
case WM_MOUSEMOVE:
if (bTracking) {
//
x = LOWORD(lParam);
y = HIWORD(lParam);
LineTo(hDC, x, y);
curve.push_back(Point(x, y));
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (i = 0; i < curves.size(); ++i) {
it = curves[i].begin();
MoveToEx(hdc, it->x, it->y, NULL);
for (it + 1; it != curves[i].end(); ++it)
LineTo(hdc, it->x, it->y);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
ReleaseDC(hWnd, hDC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

, , 
WM_PAINT. ,
hdc, 
hDC, .

234

4.

, curves 
, (
vector<Point>) it. 
: , , it
*it? , , , 
Point, x y.
LineTo :
LineTo(hdc, (*it).x, (*it).y);

. C++ 
, (*it).x 
it->x. LineTo :
LineTo(hdc, it->x, it->y);


, .


, , 
. , 
,
.
, , 
. , 
, , .
ElasticRect, 4.4, 
. ,
, .

, .

.

. WM_MOUSEMOVE,
, 

.
,
R2_XORPEN R2_NOTXORPEN.

, . 
: R2_XORPEN R2_NOTXORPEN?
, 
R2_NOTXORPEN. ,
R2_XORPEN. ? 
1 / (0 ,
1 ), . 4.4 4.5.

235

4.4. R2_XORPEN

R2_XORPEN

4.5. R2_NOTXORPEN

R2_NOTXORPEN

, 
, ,
. , 
, . ,

R2_XORPEN 
R2_NOTXORPEN.
RGB.
, . 4.4 4.5, 
, .

( PS_SOLID). 
(, PS_DOT), 
:
R2_XORPEN, R2_NOTXORPEN. 
.
, ( 4.4).
4.4. ElasticRect
//////////////////////////////////////////////////////////////////////
// ElasticRect.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Elastic Rectangle", hInstance, nCmdShow, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);

236

4.

4.4 ()
DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
UINT style;
static HDC hDC;
static
int x1, y1, x2, y2;
static BOOL bTracking = FALSE;
static HBRUSH hOldBrush;
static HPEN hDotPen, hOldPen;
switch (uMsg)
{
case WM_CREATE:
style = GetClassLong(hWnd, GCL_STYLE);
SetClassLong(hWnd, GCL_STYLE, style | CS_DBLCLKS);
hDotPen = CreatePen(PS_DOT, 1, RGB(0,0,0));
hDC = GetDC(hWnd);
hOldBrush = (HBRUSH)SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));
break;
case WM_LBUTTONDOWN:
bTracking = TRUE;
SetROP2(hDC, R2_NOTXORPEN);
x1 = x2 = LOWORD(lParam);
y1 = y2 = HIWORD(lParam);
hOldPen = (HPEN)SelectObject(hDC, hDotPen);
Rectangle(hDC, x1, y1, x2, y2);
break;
case WM_LBUTTONUP:
if (bTracking) {
bTracking = FALSE;
SetROP2(hDC, R2_COPYPEN);
//
x2 = LOWORD(lParam);
y2 = HIWORD(lParam);
SelectObject(hDC, hOldPen);
Rectangle(hDC, x1, y1, x2, y2);
}
break;
case WM_MOUSEMOVE:
if (bTracking) {
//
Rectangle(hDC, x1, y1, x2, y2);
//
x2 = LOWORD(lParam);
y2 = HIWORD(lParam);
Rectangle(hDC, x1, y1, x2, y2);
}

237

break;
case WM_LBUTTONDBLCLK:
bTracking = FALSE;
x1 = LOWORD(lParam);
y1 = HIWORD(lParam);
Rectangle(hDC, x1, y1, x1 + 100, y1 + 100);
break;
case WM_DESTROY:
SelectObject(hDC, hOldBrush);
ReleaseDC(hWnd, hDC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

WM_CREATE,
WM_LBUTTONDOWN WM_LBUTTONUP.
WM_CREATE
CS_DBLCLKS. 
. hDotPen 
PS_DOT hDC,
.
(HOLLOW_BRUSH), .
WM_LBUTTONDOWN 
R2_NOTXORPEN
hDotPen. WM_MOUSEMOVE 
.
WM_LBUTTONUP
R2_COPYPEN 
(hOldPen).
WM_PAINT,
, Scribble,
.
ScribbleAdvanced, 
.




TextViewer (. 2.2),
. 
, Windows
. Windows

238

4.

SB_. 
.
, ,
TextViewer, , 
.
, , ,
.
. WM_KEYDOWN,
,
WM_VSCROLL WM_HSCROLL.
.
, ,
, , 
, SB_. , ,
SB_.
Win32 API . 
SendMessage, 
:
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

, ,
. SendMessage, Windows 
hWnd, 
. ,
Windows SendMessage .
4.5 
1.
4.5. TextViewerAdv
//////////////////////////////////////////////////////////////////////
// TextViewerAdv.cpp
#include <windows.h>
#include <zmouse.h>
//
#include "KWnd.h"
#include "KDocument.h"
#define FILE_NAME "D:\\Program files\\Microsoft Visual
Studio\\VC98\\MFC\\SRC\\README.TXT"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
KDocument doc;
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;

KWnd.h, KWnd.cpp, KDocument.h, KDocument.cpp. 


2.2.

239

if (!doc.Open(FILE_NAME))
return 0;
KWnd mainWnd("Text Viewer Advanced", hInstance, nCmdShow, WndProc, NULL,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, CS_HREDRAW | CS_VREDRAW,
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
TEXTMETRIC tm;
int cxClient=0, cyClient=0;
static int xInc, yInc;
short status;
switch (uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
doc.Initialize(&tm);
ReleaseDC(hWnd, hDC);
break;
case WM_SIZE:
hDC = GetDC(hWnd);
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
if (cxClient > 0)
doc.ScrollSettings(hWnd, cxClient, cyClient);
ReleaseDC(hWnd, hDC);
break;
case WM_VSCROLL:
switch(LOWORD(wParam)) {
case SB_LINEUP:
yInc = -1; break;
case SB_LINEDOWN:
yInc = 1; break;
case SB_PAGEUP:
yInc = -(int)doc.vsi.nPage; break;
case SB_PAGEDOWN:
yInc = (int)doc.vsi.nPage; break;
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - doc.vsi.nPos;
case SB_TOP:
yInc = -doc.vsi.nPos; break;
case SB_BOTTOM:

break;

240

4.

4.5 ()
yInc = doc.vsi.nMax - doc.vsi.nPos;
default:
yInc = 0;
}
doc.UpdateVscroll(hWnd, yInc);
break;

break;

case WM_HSCROLL:
switch(LOWORD(wParam)) {
case SB_LINELEFT:
xInc = -1; break;
case SB_LINERIGHT:
xInc = 1; break;
case SB_PAGELEFT:
xInc = -0.8 * (int)doc.hsi.nPage; break;
case SB_PAGERIGHT:
xInc = 0.8 * (int)doc.hsi.nPage; break;
case SB_THUMBTRACK:
xInc = HIWORD(wParam) - doc.hsi.nPos; break;
case SB_TOP:
xInc = -doc.hsi.nPos; break;
case SB_BOTTOM:
xInc = doc.hsi.nMax - doc.hsi.nPos; break;
default:
xInc = 0;
}
doc.UpdateHscroll(hWnd, xInc);
break;
case WM_MOUSEWHEEL:
if (LOWORD(wParam) & MK_SHIFT) {
xInc = -3 * (short)HIWORD(wParam) / WHEEL_DELTA;
doc.UpdateHscroll(hWnd, xInc);
}
else {
yInc = -3 * (short)HIWORD(wParam) / WHEEL_DELTA;
doc.UpdateVscroll(hWnd, yInc);
}
break;
case WM_KEYDOWN:
switch (wParam) {
case VK_UP:
SendMessage(hWnd,
break;
case VK_DOWN: SendMessage(hWnd,
break;
case VK_LEFT: SendMessage(hWnd,
break;
case VK_RIGHT: SendMessage(hWnd,
break;
case VK_PRIOR: SendMessage(hWnd,
break;
case VK_NEXT: SendMessage(hWnd,
break;

WM_VSCROLL, SB_LINEUP, 0);


WM_VSCROLL, SB_LINEDOWN, 0);
WM_HSCROLL, SB_LINELEFT, 0);
WM_HSCROLL, SB_LINERIGHT, 0);
WM_VSCROLL, SB_PAGEUP, 0);
WM_VSCROLL, SB_PAGEDOWN, 0);

case VK_HOME:
status = GetKeyState(VK_CONTROL);

241

if (0x80 & status) SendMessage(hWnd, WM_VSCROLL, SB_TOP, 0);


else
SendMessage(hWnd, WM_HSCROLL, SB_TOP, 0);
break;
case VK_END:
status = GetKeyState(VK_CONTROL);
if (0x80 & status) SendMessage(hWnd, WM_VSCROLL, SB_BOTTOM, 0);
else
SendMessage(hWnd, WM_HSCROLL, SB_BOTTOM, 0);
break;
}
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
doc.PutText(hWnd, hDC);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, uMsg, wParam, lParam));
}
return 0;
}
//////////////////////////////////////////////////////////////////////

WM_MOUSEWHEEL 
WM_KEYDOWN.
short (short)
HIWORD(wParam) WM_MOUSEWHEEL. 
, .
WM_MOUSEWHEEL
Shift. , 
, .

TextViewer TextViewerAdv.

242

5. Windows-

Windows-

Windows. 
, , , , ,
, .
(
) . , 1.1 
,
.

(resource script), ASCII .rc. 
, 
,
,
.
,
. 
MS Visual Studio 6.0 
. 
FileSave.
Visual Studio
script1.rc.
, (,
MyApp.rc).
( rc.exe
). 
.res.

.obj .lib. Visual Studio 
Build .
Windows 
. 
.

243



. MS Visual Studio 6.0
:
 , , , 
;


, .

, .
, , , 
, 1.
. 6, 7 8 
, .


, Windows
, . ,
, 
. , Windows
Start (), ,
, , Windows
Explorer . ,
.
Windows
32 32 . Windows 95,
: 16 16 , 32 32
48 48 .
16, 
256 . 
, Start. ,
1

(MSDN) , .
, . 
, , 
. , .

244

5. Windows-

, . ,
Windows Explorer,
.
(48 48) ,
Windows.
, 
. 
:
.
Visual Studio, 
, .ico,
:
 32 32, 16 ( ).


32 32, 256 .

48 48, 256 .

32 32,  .

16 16, 16 .
, 
. Windows 
, . 
.

.
, 
. 
.

.
. ,
Win32 Application Russia.
Russia.cpp, ,
5.1.


5.1. Russia ( )
//////////////////////////////////////////////////////////////////////
// Russia.cpp
#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Russia today", hInstance, nCmdShow, WndProc, NULL, 0, 0,
400, 300);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);

245

DispatchMessage(&msg);
}
return msg.wParam;
}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

Russia KWnd.h KWnd.cpp, 


Hello2 ( 1.2), Russia. 
Visual Studio ,
. 5.1.

. 5.1. Visual Studio Russia

, Workspace :
ClassView FileView. FileView
, .

246

5. Windows-




:
1. . Visual Studio 
InsertResource. Insert
Resource (. 5.2).

. 5.2. Insert Resource

Icon New.
Script1 IDI_ICON1 
(. 5.3).

. 5.3. Visual Studio

247

.
Graphics , Colors
.  ,

Graphics Colors.
2. . Device 
Standard (3232).
New Device Image. 
, New Icon Image Target device (. 5.4).

. 5.4. New Icon Image

, 
OK, Device.
Russia.cpp .
Small(1616) 
OK. 
.
3. .
: Script1 IDI_ICON1 (Icon). 
.
Script1, .
, ,
(. . 5).
. 
IDI_ICON1.
,
IDI_ICON2, IDI_ICON3 . . 
. 
, .
, 
IDI_TRICOLOUR.

. Icon Properties
(. 5.5).
General ID
File name , 
.
IDI_TRICOLOUR tricol.ico.

248

5. Windows-

. 5.5. Icon Properties

, Palette. 
16 .
, Colors. 
256 , 256 , 
.
Icon Properties, .
Script1
IDI_TRICOLOUR.
4. .
(16 16). , . 5.3, ,
 (darkcyan) . 

1.
Graphics,
. Colors.
MS Paint, 
.
. 5.6.

. 5.6.

 .
,
. 1 2.
1

,  
.

Russia ,
(www.piter.com),  .

249

(3232), 
Device. 
.
Russia, 
(. 5.7).

. 5.7.

, 256 
, Palette Icon Properties
(. . 5.5).
5. .
Visual Studio FileSave.

, 
.
,
Save As ( ). File Name ( ) 
Script1.rc. Script1 , 
Russia, Save ().
Russia.rc IDI_TRICOLOUR.
.
Workspace Resource Files
Add Files to Folder. 
Insert Files .
Russia.rc, Visual
Studio , . 5.8.
, FileView.
Resource Files : Russia.rc
tricol.ico. , Workspace
ResourceView. , 
, Icon c
IDI_TRICOLOUR.

250

5. Windows-

. 5.8. Visual Studio

6. resource.h (
). , 
resource.h, 
. ,

. Workspace
Header Files 
Add Files to Folder. Insert
Files resource.h.

resource.h , ,
. (DLL), , .
11.


.
, ,
.


. 

, .

251

, ,
AnyIcon.ico. 
AnyIcon.ico .
:
 Visual Studio InsertResource. 
Insert Resource Icon
Import.


Import Resource ,
, AnyIcon.ico. 

.

. 3 
.


, . 5 6 .

. 
, , .




, 

.


Workspace ResourceView
.
, , 
, , , . 5.8. 
.
,
FileSave.


, 
. Visual Studio FileOpen.
Open (), 
. 5.9.
,
( Russia). ,
. Open
as Text. 
( Russia.rc). Visual
Studio .

252

5. Windows-

. 5.9. Open

Russia.rc,
:
IDI_TRICOLOUR

ICON

DISCARDABLE

"tricol.ico"

.
. 
, .
:
_

DISCARDABLE

_ Windows C
, . _
ASCII
, Windows . 
_ C,
( ) .
, C Windows,
Visual Studio
. ,
resource.h Russia, :
#define

IDI_TRICOLOUR

101


:
101

ICON

DISCARDABLE

"tricol.ico"

, , Russia.rc,
IDI_TRICOLOUR tricol.ico, 
: .
DISCARDABLE ()
Windows, 
, . Win32
.

253


, HICON, 
LoadIcon LoadImage.
LoadIcon 1.
. LoadIcon 
(.exe), 
hInstance:
HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);

, , 
. ,
, , _
. 

MAKEINTRESOURCE (make an integer into resource string),
winuser.h :
#define MAKEINTRESOURCE(i) (LPSTR)((DWORD)((WORD)(i)))

, 16
. Windows ,
LoadIcon , .
, Russia 
:
LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TRICOLOUR));

hInstance NULL, LoadIcon 


. 
. 1.5 (
1). ,
KWnd hIcon wc
LoadIcon(NULL, IDI_APPLICATION).
LoadIcon 
. NULL.
 LoadIcon ,
IDI_WINLOGO.
, LoadIcon 
. 
(16 16). .
LoadImage.
LoadImage :
, , . :
HANDLE LoadImage(HINSTANCE hinst, LPCTSTR lpszName, UINT uType,
int cxDesired, int cyDesired, UINT fuLoad);

. 
hinst NULL fuLoad LR_LOADFROMFILE,
lpszName
LoadIcon.

254

5. Windows-

hinst NULL, fuLoad 


LR_LOADFROMFILE, lpszName OEM1.
OEM winuser.h
: OBM_ , OIC_ OCR_ .
hinst NULL, fuLoad LR_LOADFROMFILE,
lpszName , 
.
, uType, 
IMAGE_BITMAP, IMAGE_CURSOR IMAGE_ICON.
, cxDesired, .
fuLoad LR_DEFAULTSIZE, 
SM_CXICON
SM_CXCURSOR. , LR_DEFAULTSIZE 
, .
, cyDesired, . 
fuLoad LR_DEFAULTSIZE, 
SM_CXICON SM_CXCURSOR.
, LR_DEFAULTSIZE ,
.
, fuLoad, . 
, . 5.1 (
. . MSDN).
5.1. LoadImage

LR_DEFAULTCOLOR

. ,

LR_CREATEDIBSECTION

uType IMAGE_BITMAP,
DIB-

LR_DEFAULTSIZE

LR_LOADFROMFILE

LR_MONOCHROME

Russia.

, hIcon
hIconSm .
KWnd,
KWnd (.
KWnd.cpp).
SetClassLong. 
WM_CREATE, ,
.
Russia.cpp 5.2.

OEM Original Equipment Manufacturers ( ).

255

5.2. Russia (1- )


//////////////////////////////////////////////////////////////////////
// Russia.cpp
#include <windows.h>
#include "KWnd.h"
#include "resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Russia today", hInstance, nCmdShow, WndProc, NULL, 0, 0,
400, 300);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HINSTANCE hInst;
HICON hIcon;
//
HICON hIconSm; //
switch (uMsg)
{
case WM_CREATE:
hInst = GetModuleHandle(NULL);
hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_TRICOLOUR));
hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_TRICOLOUR),
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
SetClassLong(hWnd, GCL_HICON, (LONG)hIcon);
SetClassLong(hWnd, GCL_HICONSM, (LONG)hIconSm);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

WM_CREATE LoadIcon
LoadImage 
. hInst, 
, GetModuleHandle.

256

5. Windows-

hIcon hIconSm 
SetClassLong, (hIcon, hIconSm)
mainWnd.wc .
:
#include "resource.h"

IDI_TRICOLOUR .

(. 5.10).

. 5.10. Russia (1- )

32 32 , 
() . .
(hotspot).
,
. 
, , 
.
, 
, , Russia.

, .
, 
IDC_CROSS.
, , 
, .
, 
, . ,
IDC_UP IDC_DOWN.

.
Insert Resource Icon Cursor.
.
, , 
. , IDC_UP
. 5.11.

257

. 5.11. IDC_UP

,
, Set Hotspot,
.
(0, 0).
.
, Set Hotspot,
,
. .
Hot spot: 15, 0.
IDC_DOWN.
(. 5.12).

. 5.12. IDC_DOWN

,
FileSave. Russia.rc , 
:
IDC_UP
IDC_DOWN

CURSOR
CURSOR

DISCARDABLE
DISCARDABLE

"up.cur"
"down.cur"

, .
( HCURSOR)
LoadCursor,
LoadIcon.

258

5. Windows-

: hCursor 
( IDC_CROSS), hCursorUp
(IDC_UP) hCursorDown (IDC_DOWN).
hCursor . 
,
:
SetClassLong(hWnd, GCL_HCURSOR, (LONG)hCursor);


SetCursor:
HCURSOR SetCursor(HCURSOR hCursor);

, 
. .

WM_MOUSEMOVE. lParam 
x y,
. 
.
Russia.cpp 5.3.
5.3. Russia (2- )
//////////////////////////////////////////////////////////////////////
// Russia.cpp
#include <windows.h>
#include <stdio.h>
#include "KWnd.h"
#include "resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("Russia today", hInstance, nCmdShow, WndProc, NULL, 0, 0,
400, 300);
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

}
//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HINSTANCE hInst;
HICON hIcon, hIconSm;
static HCURSOR hCursor, hCursorUp, hCursorDown;
static int xPos, yPos; //
static int wClient, hClient; //
HDC hDC;
PAINTSTRUCT ps;
char text[100];
RECT rect;

259

SetRect(&rect, 10, 0, 200, 30);


switch (uMsg)
{
case WM_CREATE:
hInst = GetModuleHandle(NULL);
hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_TRICOLOUR));
hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_TRICOLOUR),
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
SetClassLong(hWnd, GCL_HICON, (LONG)hIcon);
SetClassLong(hWnd, GCL_HICONSM, (LONG)hIconSm);
hCursor = LoadCursor(NULL, IDC_CROSS);
SetClassLong(hWnd, GCL_HCURSOR, (LONG)hCursor);
hCursorUp = LoadCursor(hInst, MAKEINTRESOURCE(IDC_UP));
hCursorDown = LoadCursor(hInst, MAKEINTRESOURCE(IDC_DOWN));
break;
case WM_SIZE:
wClient = LOWORD(lParam);
hClient = HIWORD(lParam);
break;
case WM_MOUSEMOVE:
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
if (yPos < 16)
SetCursor(hCursorUp);
if (yPos > hClient - 16)
SetCursor(hCursorDown);
InvalidateRect(hWnd, &rect, TRUE);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
sprintf(text, "xPos = %d, yPos = %d\0", xPos, yPos);
DrawText(hDC, text, -1, &rect, DT_LEFT);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////

wClient hClient 
WM_SIZE. hClient
WM_MOUSEMOVE,
, , .
,
, . 5.13.

260

5. Windows-

. 5.13. Russia c ,

, , 
InvalidateRect WM_MOUSEMOVE:
InvalidateRect(hWnd, &rect, TRUE);

, ,
, .
WM_PAINT. , 
DrawText .
, 
, , 
. Windows , 
BeginPaint, .
WM_PAINT InvalidateRect 
, TRUE.

InvalidateRect. , 
, . 
NULL, .
, 
.
.


3 Windows
. 
, DDB . , 
.
.
, . 
, Windows
, 
, , , 
.

261

.
, Windows 
. 
12.1 ( 12).

. Insert Resource 
Icon Bitmap.
. ,
.
( ), Bitmap
Properties (. 5.14) ,
, 16 256 .
,
,
, .
. 
.

. 5.14. Bitmap Properties


HBITMAP , LoadBitmap:
HBITMAP LoadBitmap(
HINSTANCE hInstance,
LPCTSTR lpBitmapName
);

//
//

, LoadIcon.
Win32 DIB
. LoadBitmap , ,
DIB, DDB,
, DDB.
BitBlt
StretchBlt .
3.
Russia.
.

MS Paint. 400 280 
, 
Russia today (. 5.15).

262

5. Windows-

. 5.15. RussiaToday.bmp MS Paint

RusFlag.bmp, 256
. Russia1.
,
RusFlag.bmp IDB_RUSFLAG.
Russia.rc ,
:
IDB_RUSFLAG

BITMAP

DISCARDABLE

"RusFlag.bmp"

.
.

static HBITMAP hBmpRusFlag;
HDC hMemDC;
static BITMAP bm;

//
//
//

WM_CREATE
hBmpRusFlag = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RUSFLAG));
GetObject(hBmpRusFlag, sizeof(bm), (LPSTR)&bm);

WM_PAINT BeginPaint
:
hMemDC = CreateCompatibleDC(hDC);
SelectObject(hMemDC, hBmpRusFlag);
BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
DeleteDC(hMemDC);

,
. 5.16.
1

, 
, (www.piter.com).

263

. 5.16. Russia.

,
.
. (&rect) InvalidateRect
NULL . ,
.

,
, (userdefined resource), 
, 
.
: , .
, proghelp.txt, 
. 
, :
HELPTEXT

TEXT

DISCARDABLE

proghelp.txt

(HELPTEXT) (TEXT) 
. , 

.
,
WM_CREATE, ,
proghelp.txt.
: 
. 
, , 
.
, Visual Studio 
, .

264

5. Windows-


:
_

DISCARDABLE

, .
, .


, , 
FindResource, LoadResource LockResource.
FindResource .
:
HRSRC FindResource(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType);

hModule 
, . hModule NULL, Windows
, .
lpName , , , .
#, 
. lpType .

, . 
,
LoadResource. FindResource NULL.
LoadResource , FindResource,
.
:
HGLOBAL LoadResource(HMODULE hModule, HRSRC hResInfo);

hResInfo 
, FindResource.
, LoadResource, , 
, MSDN
, LockResource:
LPVOID LockResource(HGLOBAL hResData);

.
hResData , . 
, LoadResource.
LockResource
, NULL.
,
.
proghelp.txt, 
,
:
HGLOBAL hResource = LoadResource(hInstance,
FindResource(hInstance, "HELPTEXT", "TEXT"));
char* pHelpText = (char*) LockResource(hResource);

265

, ,
.



,  . , 
, 

. 
, , 
.
Win32 API ,
WAVE (waveform audio file fomat). 
.wav. 8 16
. WAVE
, ,
. .wav, 
,
.
PlaySound, 
:
BOOL PlaySound(
LPCSTR pszSound,
HMODULE hmod,
DWORD fdwSound
);

// ,
//
//

, 
. PlaySound NULL,
.

. ,
NULL.
. . 5.2
.
5.2. fdwSound

SND_FILENAME

pszSound

SND_RESOURCE

pszSound

SND_SYNC

. PlaySound

SND_ASYNC

. PlaySound
.

PlaySound, pszSound NULL

266

5. Windows-

5.2. ()

SND_LOOP

,
PlaySound, pszSound NULL.
SND_ASYNC

SND_NODEFAULT

. ,
PlaySound ,

SND_PURGE

pszSound NULL,
. NULL,

SND_NOWAIT

PlaySound Windows. 
Visual Studio, 
winmm.lib1.
, 
PlaySound . ,
.wav exe
. , 
. 
. , 
,
!  ,
, , exe
.
PlaySound 
. ,
FindResource, LoadResource
LockResource.
PlaySound.
PlaySound
Russia. 
, . 
, RussiaToday, 
, ,
. , 
.
RussiaToday.rc

MY_SOUND

WAVE

DISCARDABLE

"RusHymn.wav"

RusHymn.wav
2.
1

Visual Studio 6.0 ProjectSettings Link 


Object/library modules.
2
WAVE 
RusHymn.wav .
: www.piter.com.

267

5.4.
5.4. RussiaToday
//////////////////////////////////////////////////////////////////////
// RussiaToday.cpp
#include <windows.h>
#include <stdio.h>
#include "KWnd.h"
#include "resource.h"
char szSoundName[] = "MY_SOUND";

//

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
nCmdShow)