Reactos
at master 351 lines 10 kB view raw
1 2// ------------------------------------------------------------------ 3// Windows 2000 Graphics API Black Book 4// Chapter 5 - Listing 5.1 (Output Primitives 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#include <cassert> 17 18// for the MakeFont() function... 19#include "mk_font.h" 20//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 21 22 23HINSTANCE hInst; 24const char* WndClassName = "GMainWnd"; 25LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, 26 LPARAM LParam); 27 28 29int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, 30 int nCmdShow) 31{ 32 hInst = hInstance; 33 34 WNDCLASS wc; 35 memset(&wc, 0, sizeof(WNDCLASS)); 36 37 wc.style = CS_VREDRAW | CS_HREDRAW; 38 wc.lpszClassName = WndClassName; 39 wc.lpfnWndProc = MainWndProc; 40 wc.hInstance = hInst; 41 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 42 wc.hbrBackground = reinterpret_cast<HBRUSH>( 43 COLOR_BTNFACE + 1 44 ); 45 46 if (RegisterClass(&wc)) 47 { 48 HWND hWnd = 49 CreateWindow( 50 WndClassName, TEXT("Output Primitives Demo"), 51 WS_OVERLAPPEDWINDOW | WS_CAPTION | 52 WS_VISIBLE | WS_CLIPCHILDREN, 53 CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 54 NULL, NULL, hInst, NULL 55 ); 56 57 if (hWnd) 58 { 59 ShowWindow(hWnd, nCmdShow); 60 UpdateWindow(hWnd); 61 62 MSG msg; 63 while (GetMessage(&msg, NULL, 0, 0)) 64 { 65 TranslateMessage(&msg); 66 DispatchMessage(&msg); 67 } 68 } 69 } 70 return 0; 71} 72//------------------------------------------------------------------ 73 74 75enum OutPrimitive { 76 opLine, opBezier, opRectangle, opRoundRect, 77 opEllipse, opArc, opPie, opChord, opCustom 78 }; 79 80void DrawPrimitive(IN HDC hDC, IN const RECT& RPrimitive, 81 IN OutPrimitive PrimitiveID) 82{ 83 RECT R = RPrimitive; 84 InflateRect(&R, -10, -10); 85 86 switch (PrimitiveID) 87 { 88 case opLine: 89 { 90 const POINT PLine[] = {{R.left, R.top}, {R.right, R.bottom}}; 91 Polyline(hDC, PLine, 2); 92 break; 93 } 94 case opBezier: 95 { 96 const POINT PControlPoints[] = { 97 {R.left, R.top}, 98 {(R.right - R.left) / 2, R.top}, 99 {(R.right - R.left) / 2, R.bottom}, 100 {R.right, R.bottom} 101 }; 102 PolyBezier(hDC, PControlPoints, 4); 103 break; 104 } 105 case opRectangle: 106 { 107 Rectangle(hDC, R.left, R.top, R.right, R.bottom); 108 break; 109 } 110 case opRoundRect: 111 { 112 RoundRect(hDC, R.left, R.top, R.right, R.bottom, 20, 20); 113 break; 114 } 115 case opEllipse: 116 { 117 Ellipse(hDC, R.left, R.top, R.right, R.bottom); 118 break; 119 } 120 case opArc: 121 { 122 const POINT PRads[] = { 123 {(R.right - R.left) / 3 + R.left, R.top}, 124 {(R.right - R.left) / 3 + R.left, R.bottom} 125 }; 126 Arc(hDC, R.left, R.top, R.right, R.bottom, 127 PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y); 128 break; 129 } 130 case opPie: 131 { 132 const POINT PRads[] = { 133 {(R.right - R.left) / 3 + R.left, R.top}, 134 {(R.right - R.left) / 3 + R.left, R.bottom} 135 }; 136 Pie(hDC, R.left, R.top, R.right, R.bottom, 137 PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y); 138 break; 139 } 140 case opChord: 141 { 142 const POINT PRads[] = { 143 {(R.right - R.left) / 3 + R.left, R.top}, 144 {(R.right - R.left) / 3 + R.left, R.bottom} 145 }; 146 Chord(hDC, R.left, R.top, R.right, R.bottom, 147 PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y); 148 break; 149 } 150 case opCustom: 151 { 152 const POINT PVertices[] = { 153 {R.left, (R.bottom - R.top) / 2 + R.top}, 154 {(R.right - R.left) / 2 + R.left, R.top}, 155 {R.right, (R.bottom - R.top) / 2 + R.top}, 156 {(R.right - R.left) / 2 + R.left, R.bottom} 157 }; 158 Polygon(hDC, PVertices, 4); 159 break; 160 } 161 } 162} 163//------------------------------------------------------------------ 164 165 166HWND hListBox = NULL; // handle to the list box 167HBRUSH hListBrush = NULL; // handle to the list box brush 168HPEN hListPen = NULL; // handle to the list box pen 169HFONT hListFont = NULL; // handle to the list box font 170 171LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, 172 LPARAM lParam) 173{ 174 switch (msg) 175 { 176 case WM_CREATE: 177 { 178 hListBox = 179 CreateWindowEx( 180 WS_EX_CLIENTEDGE, TEXT("LISTBOX"), TEXT(""), 181 WS_CHILD | WS_VISIBLE | WS_VSCROLL | 182 LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | 183 LBS_OWNERDRAWFIXED, 184 0, 0, 640, 480, 185 hWnd, NULL, hInst, NULL 186 ); 187 assert(hListBox != NULL); 188 189 SetWindowLongPtr( 190 hListBox, GWL_ID, reinterpret_cast<LONG_PTR>(hListBox) 191 ); 192 193 SNDMSG(hListBox, LB_ADDSTRING, 0, 194 reinterpret_cast<LPARAM>(TEXT("Line"))); 195 SNDMSG(hListBox, LB_ADDSTRING, 0, 196 reinterpret_cast<LPARAM>(TEXT("Bezier Curve"))); 197 SNDMSG(hListBox, LB_ADDSTRING, 0, 198 reinterpret_cast<LPARAM>(TEXT("Rectangle"))); 199 SNDMSG(hListBox, LB_ADDSTRING, 0, 200 reinterpret_cast<LPARAM>(TEXT("Rounded Rectangle"))); 201 SNDMSG(hListBox, LB_ADDSTRING, 0, 202 reinterpret_cast<LPARAM>(TEXT("Ellipse"))); 203 SNDMSG(hListBox, LB_ADDSTRING, 0, 204 reinterpret_cast<LPARAM>(TEXT("Arc"))); 205 SNDMSG(hListBox, LB_ADDSTRING, 0, 206 reinterpret_cast<LPARAM>(TEXT("Pie Slice"))); 207 SNDMSG(hListBox, LB_ADDSTRING, 0, 208 reinterpret_cast<LPARAM>(TEXT("Chord"))); 209 SNDMSG(hListBox, LB_ADDSTRING, 0, 210 reinterpret_cast<LPARAM>(TEXT("Custom"))); 211 212 hListBrush = CreateSolidBrush(PALETTERGB(64, 192, 64)); 213 hListPen = CreatePen(PS_SOLID, 3, PALETTERGB(0, 0, 0)); 214 HDC hScreenDC = GetDC(NULL); 215#if 0 216 try 217#endif 218 { 219 // MakeFont() from Chapter 4 220 hListFont = font::MakeFont( 221 hScreenDC, "Impact", 20, ANSI_CHARSET, 222 font::FS_BOLD | font::FS_UNDERLINE 223 ); 224 } 225#if 0 226 catch (...) 227#endif 228 { 229 ReleaseDC(NULL, hScreenDC); 230 } 231 ReleaseDC(NULL, hScreenDC); 232 233 break; 234 } 235 case WM_MEASUREITEM: 236 { 237 LPMEASUREITEMSTRUCT lpmis = 238 reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam); 239 assert(lpmis != NULL); 240 241 if (lpmis->CtlID == reinterpret_cast<UINT_PTR>(hListBox)) 242 { 243 lpmis->itemHeight = 150; 244 return TRUE; 245 } 246 break; 247 } 248 case WM_DRAWITEM: 249 { 250 LPDRAWITEMSTRUCT lpdis = 251 reinterpret_cast<LPDRAWITEMSTRUCT>(lParam); 252 assert(lpdis != NULL); 253 254 if (lpdis->CtlID == reinterpret_cast<UINT_PTR>(hListBox)) 255 { 256 SaveDC(lpdis->hDC); 257#if 0 258 try 259#endif 260 { 261 SelectObject(lpdis->hDC, hListBrush); 262 SelectObject(lpdis->hDC, hListPen); 263 SelectObject(lpdis->hDC, hListFont); 264 265 bool selected = (lpdis->itemState & ODS_SELECTED); 266 COLORREF clrText = GetSysColor( 267 selected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT 268 ); 269 HBRUSH hListBrush = GetSysColorBrush( 270 selected ? COLOR_HIGHLIGHT : COLOR_WINDOW 271 ); 272 273 // fill the background 274 FillRect(lpdis->hDC, &lpdis->rcItem, hListBrush); 275 276 // render the output primitive 277 RECT RPrimitive = lpdis->rcItem; 278 InflateRect(&RPrimitive, -5, -5); 279 RPrimitive.right = static_cast<int>( 280 0.6 * lpdis->rcItem.right + 0.5 281 ); 282 FillRect( 283 lpdis->hDC, &RPrimitive, 284 reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1) 285 ); 286 DrawPrimitive( 287 lpdis->hDC, RPrimitive, 288 static_cast<OutPrimitive>(lpdis->itemID) 289 ); 290 if (selected) InvertRect(lpdis->hDC, &RPrimitive); 291 DrawEdge(lpdis->hDC, &RPrimitive, EDGE_SUNKEN, BF_RECT); 292 293 // render the text 294 TCHAR text[13]; 295 if (SNDMSG(hListBox, LB_GETTEXT, lpdis->itemID, 296 reinterpret_cast<LPARAM>(&text)) != LB_ERR) 297 { 298 RECT RText = RPrimitive; 299 RText.left = RPrimitive.right; 300 RText.right = lpdis->rcItem.right; 301 302 SelectObject(lpdis->hDC, hListFont); 303 SetBkMode(lpdis->hDC, TRANSPARENT); 304 SetTextColor(lpdis->hDC, clrText); 305 306 DrawText(lpdis->hDC, text, -1, &RText, 307 DT_CENTER | DT_VCENTER | DT_SINGLELINE); 308 } 309 310 // indicate keyboard focus 311 if (lpdis->itemState & ODS_FOCUS) 312 { 313 RECT RFocus = lpdis->rcItem; 314 InflateRect(&RFocus, -1, -1); 315 DrawFocusRect(lpdis->hDC, &RFocus); 316 } 317 } 318#if 0 319 catch (...) 320#endif 321 { 322 RestoreDC(lpdis->hDC, -1); 323 } 324 RestoreDC(lpdis->hDC, -1); 325 return TRUE; 326 } 327 break; 328 } 329 case WM_SIZE: 330 { 331 MoveWindow( 332 hListBox, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE 333 ); 334 return 0; 335 } 336 case WM_DESTROY: 337 { 338 if (hListBrush) DeleteObject(hListBrush); 339 if (hListPen) DeleteObject(hListPen); 340 if (hListFont) DeleteObject(hListFont); 341 342 PostQuitMessage(0); 343 return 0; 344 } 345 } 346 return DefWindowProc(hWnd, msg, wParam, lParam); 347} 348//------------------------------------------------------------------------- 349 350 351