[BRANCHES]
[reactos.git] / rostests / dibtests / patblt / patblt.cpp
1
2 // ------------------------------------------------------------------
3 // Windows 2000 Graphics API Black Book
4 // Chapter 2 - Listing 2.1 (PatBlt Tracking Rect Demo)
5 //
6 // Created by Damon Chandler <dmc27@ee.cornell.edu>
7 // Updates can be downloaded at: <www.coriolis.com>
8 //
9 // Please do not hesistate to e-mail me at dmc27@ee.cornell.edu
10 // if you have any questions about this code.
11 // ------------------------------------------------------------------
12
13
14 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
15 #include <windows.h>
16 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
17
18
19 HINSTANCE HInst;
20 const char* WndClassName = "GMainWnd";
21 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
22 LPARAM LParam);
23
24
25 int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE, LPTSTR,
26 int nCmdShow)
27 {
28 HInst = HInstance;
29
30 WNDCLASS wc;
31 memset(&wc, 0, sizeof(WNDCLASS));
32
33 wc.style = CS_VREDRAW | CS_HREDRAW;
34 wc.lpszClassName = WndClassName;
35 wc.lpfnWndProc = MainWndProc;
36 wc.hInstance = HInstance;
37 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
38 wc.hbrBackground = static_cast<HBRUSH>(
39 GetStockObject(BLACK_BRUSH)
40 );
41
42 if (RegisterClass(&wc))
43 {
44 HWND HWnd =
45 CreateWindow(WndClassName,
46 TEXT("PatBlt Tracking Rect Demo"),
47 WS_OVERLAPPEDWINDOW | WS_CAPTION |
48 WS_VISIBLE | WS_CLIPCHILDREN,
49 CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
50 NULL, NULL, HInst, NULL);
51
52 if (HWnd)
53 {
54 ShowWindow(HWnd, nCmdShow);
55 UpdateWindow(HWnd);
56
57 MSG msg;
58 while (GetMessage(&msg, NULL, 0, 0))
59 {
60 TranslateMessage(&msg);
61 DispatchMessage(&msg);
62 }
63 }
64 }
65 return 0;
66 }
67 //------------------------------------------------------------------
68
69
70 // image related
71 HDC HMemDC = NULL;
72 HBITMAP HOldBmp = NULL;
73 const char* filename = "PENGUIN.BMP";
74 RECT RImage = {225, 110, 225, 110};
75
76 // tracking related
77 bool is_tracking = false;
78 HDC HScreenDC = NULL;
79 POINT PMouse = {0, 0};
80 RECT RTrack = {0, 0, 0, 0};
81 const int line_width = 5;
82
83
84 // utility function to map to/from window coordinates
85 void MapRect(IN HWND HWndFrom, IN HWND HWndTo, IN OUT RECT& RMap)
86 {
87 MapWindowPoints(
88 HWndFrom, HWndTo,
89 reinterpret_cast<LPPOINT>(&RMap), 2
90 );
91 }
92 //------------------------------------------------------------------
93
94
95 // utility function that uses the PatBlt function to
96 // render a tracking rectangle
97 void RenderTrackingRect(IN HDC HDestDC, IN const RECT& RRender)
98 {
99 const int width = RRender.right - RRender.left;
100 const int height = RRender.bottom - RRender.top;
101 const DWORD dwROP3 = DSTINVERT; // experiment with others
102
103 // render top bar
104 PatBlt(HDestDC,
105 RRender.left, RRender.top,
106 width, line_width,
107 dwROP3);
108 // render bottom bar
109 PatBlt(HDestDC,
110 RRender.left, RRender.bottom - line_width,
111 width, line_width,
112 dwROP3);
113 // render left bar
114 PatBlt(HDestDC,
115 RRender.left, RRender.top + line_width,
116 line_width, height - (2 * line_width),
117 dwROP3);
118 // render right bar
119 PatBlt(HDestDC,
120 RRender.right - line_width, RRender.top + line_width,
121 line_width, height - (2 * line_width),
122 dwROP3);
123
124 }
125 //------------------------------------------------------------------
126
127
128 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
129 LPARAM LParam)
130 {
131 switch (Msg)
132 {
133 case WM_CREATE:
134 {
135 // create a memory DC
136 HMemDC = CreateCompatibleDC(NULL);
137 if (HMemDC)
138 {
139 // load the penguin bitmap
140 HBITMAP HBmp = static_cast<HBITMAP>(
141 LoadImage(HInst, filename, IMAGE_BITMAP, 0, 0,
142 LR_LOADFROMFILE | LR_DEFAULTSIZE)
143 );
144 if (HBmp)
145 {
146 // get the bitmap's dimensions
147 BITMAP bmp;
148 if (GetObject(HBmp, sizeof(BITMAP), &bmp))
149 {
150 RImage.right += bmp.bmWidth;
151 RImage.bottom += bmp.bmHeight;
152
153 // realize the bitmap
154 HOldBmp = static_cast<HBITMAP>(
155 SelectObject(HMemDC, HBmp)
156 );
157 }
158 else DeleteObject(HBmp);
159 }
160 }
161 break;
162 }
163 case WM_LBUTTONDOWN:
164 {
165 PMouse.x = LOWORD(LParam);
166 PMouse.y = HIWORD(LParam);
167
168 RECT RClient;
169 if (PtInRect(&RImage, PMouse) &&
170 GetClientRect(HWnd, &RClient))
171 {
172 MapRect(HWnd, HWND_DESKTOP, RClient);
173 ClipCursor(&RClient);
174
175 // grab a handle to the screen DC and clip
176 // all output to the client area of our window
177 HScreenDC = GetDC(NULL);
178 HRGN HClipRgn = CreateRectRgnIndirect(&RClient);
179 SelectClipRgn(HScreenDC, HClipRgn);
180 DeleteObject(HClipRgn);
181
182 CopyRect(&RTrack, &RImage);
183 MapRect(HWnd, HWND_DESKTOP, RTrack);
184
185 // render the first tracking rect
186 RenderTrackingRect(HScreenDC, RTrack);
187 is_tracking = true;
188 }
189 break;
190 }
191 case WM_MOUSEMOVE:
192 {
193 if (HScreenDC && is_tracking)
194 {
195 POINT PCurrent = {LOWORD(LParam), HIWORD(LParam)};
196 const int dX = PCurrent.x - PMouse.x;
197 const int dY = PCurrent.y - PMouse.y;
198
199 // erase the previous rectangle
200 RenderTrackingRect(HScreenDC, RTrack);
201 // update the postion
202 OffsetRect(&RTrack, dX, dY);
203 // render the new tracking rectangle
204 RenderTrackingRect(HScreenDC, RTrack);
205
206 // update the mouse position
207 memcpy(&PMouse, &PCurrent, sizeof(POINT));
208 }
209 break;
210 }
211 case WM_LBUTTONUP:
212 {
213 // clean up
214 if (is_tracking)
215 {
216 is_tracking = false;
217 SelectClipRgn(HScreenDC, NULL);
218 ReleaseDC(NULL, HScreenDC);
219
220 InvalidateRect(HWnd, &RImage, true);
221 CopyRect(&RImage, &RTrack);
222 MapRect(HWND_DESKTOP, HWnd, RImage);
223 InvalidateRect(HWnd, &RImage, true);
224
225 ClipCursor(NULL);
226 }
227 break;
228 }
229 case WM_PAINT:
230 {
231 PAINTSTRUCT ps;
232 HDC Hdc = BeginPaint(HWnd, &ps);
233 try
234 {
235 //
236 // TODO: Add palette support...
237 //
238
239 // render the penguin
240 BitBlt(Hdc, RImage.left, RImage.top,
241 RImage.right - RImage.left,
242 RImage.bottom - RImage.top,
243 HMemDC, 0, 0,
244 SRCCOPY);
245 }
246 catch (...)
247 {
248 EndPaint(HWnd, &ps);
249 }
250 EndPaint(HWnd, &ps);
251 break;
252 }
253 case WM_DESTROY:
254 {
255 // clean up
256 if (HOldBmp)
257 {
258 DeleteObject(SelectObject(HMemDC, HOldBmp));
259 }
260 if (HMemDC)
261 {
262 DeleteDC(HMemDC);
263 }
264 PostQuitMessage(0);
265 return 0;
266 }
267 }
268 return DefWindowProc(HWnd, Msg, WParam, LParam);
269 }
270 //------------------------------------------------------------------