2 // ------------------------------------------------------------------
3 // Windows 2000 Graphics API Black Book
4 // Chapter 2 - Listing 2.1 (PatBlt Tracking Rect Demo)
6 // Created by Damon Chandler <dmc27@ee.cornell.edu>
7 // Updates can be downloaded at: <www.coriolis.com>
9 // Please do not hesistate to e-mail me at dmc27@ee.cornell.edu
10 // if you have any questions about this code.
11 // ------------------------------------------------------------------
14 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
16 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
20 const char* WndClassName = "GMainWnd";
21 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
25 int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE, LPTSTR,
31 memset(&wc, 0, sizeof(WNDCLASS));
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)
42 if (RegisterClass(&wc))
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);
54 ShowWindow(HWnd, nCmdShow);
58 while (GetMessage(&msg, NULL, 0, 0))
60 TranslateMessage(&msg);
61 DispatchMessage(&msg);
67 //------------------------------------------------------------------
72 HBITMAP HOldBmp = NULL;
73 const char* filename = "PENGUIN.BMP";
74 RECT RImage = {225, 110, 225, 110};
77 bool is_tracking = false;
79 POINT PMouse = {0, 0};
80 RECT RTrack = {0, 0, 0, 0};
81 const int line_width = 5;
84 // utility function to map to/from window coordinates
85 void MapRect(IN HWND HWndFrom, IN HWND HWndTo, IN OUT RECT& RMap)
89 reinterpret_cast<LPPOINT>(&RMap), 2
92 //------------------------------------------------------------------
95 // utility function that uses the PatBlt function to
96 // render a tracking rectangle
97 void RenderTrackingRect(IN HDC HDestDC, IN const RECT& RRender)
99 const int width = RRender.right - RRender.left;
100 const int height = RRender.bottom - RRender.top;
101 const DWORD dwROP3 = DSTINVERT; // experiment with others
105 RRender.left, RRender.top,
110 RRender.left, RRender.bottom - line_width,
115 RRender.left, RRender.top + line_width,
116 line_width, height - (2 * line_width),
120 RRender.right - line_width, RRender.top + line_width,
121 line_width, height - (2 * line_width),
125 //------------------------------------------------------------------
128 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
135 // create a memory DC
136 HMemDC = CreateCompatibleDC(NULL);
139 // load the penguin bitmap
140 HBITMAP HBmp = static_cast<HBITMAP>(
141 LoadImage(HInst, filename, IMAGE_BITMAP, 0, 0,
142 LR_LOADFROMFILE | LR_DEFAULTSIZE)
146 // get the bitmap's dimensions
148 if (GetObject(HBmp, sizeof(BITMAP), &bmp))
150 RImage.right += bmp.bmWidth;
151 RImage.bottom += bmp.bmHeight;
153 // realize the bitmap
154 HOldBmp = static_cast<HBITMAP>(
155 SelectObject(HMemDC, HBmp)
158 else DeleteObject(HBmp);
165 PMouse.x = LOWORD(LParam);
166 PMouse.y = HIWORD(LParam);
169 if (PtInRect(&RImage, PMouse) &&
170 GetClientRect(HWnd, &RClient))
172 MapRect(HWnd, HWND_DESKTOP, RClient);
173 ClipCursor(&RClient);
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);
182 CopyRect(&RTrack, &RImage);
183 MapRect(HWnd, HWND_DESKTOP, RTrack);
185 // render the first tracking rect
186 RenderTrackingRect(HScreenDC, RTrack);
193 if (HScreenDC && is_tracking)
195 POINT PCurrent = {LOWORD(LParam), HIWORD(LParam)};
196 const int dX = PCurrent.x - PMouse.x;
197 const int dY = PCurrent.y - PMouse.y;
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);
206 // update the mouse position
207 memcpy(&PMouse, &PCurrent, sizeof(POINT));
217 SelectClipRgn(HScreenDC, NULL);
218 ReleaseDC(NULL, HScreenDC);
220 InvalidateRect(HWnd, &RImage, true);
221 CopyRect(&RImage, &RTrack);
222 MapRect(HWND_DESKTOP, HWnd, RImage);
223 InvalidateRect(HWnd, &RImage, true);
232 HDC Hdc = BeginPaint(HWnd, &ps);
236 // TODO: Add palette support...
239 // render the penguin
240 BitBlt(Hdc, RImage.left, RImage.top,
241 RImage.right - RImage.left,
242 RImage.bottom - RImage.top,
258 DeleteObject(SelectObject(HMemDC, HOldBmp));
268 return DefWindowProc(HWnd, Msg, WParam, LParam);
270 //------------------------------------------------------------------