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