1 2 // ------------------------------------------------------------------ 3 // Windows 2000 Graphics API Black Book 4 // Chapter 8 - Listing 8.1 (Scaled Text 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 <commctrl.h> 17 #include <cassert> 18 19 // for the MakeFont() function... 20 #include "mk_font.h" 21 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 22 23 24 HINSTANCE hInst; 25 const char* WndClassName = "GMainWnd"; 26 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, 27 LPARAM LParam); 28 29 30 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, 31 int nCmdShow) 32 { 33 hInst = hInstance; 34 35 WNDCLASS wc; 36 memset(&wc, 0, sizeof(WNDCLASS)); 37 38 wc.style = CS_HREDRAW | CS_VREDRAW; 39 wc.lpszClassName = WndClassName; 40 wc.lpfnWndProc = MainWndProc; 41 wc.hInstance = hInst; 42 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 43 wc.hbrBackground = reinterpret_cast<HBRUSH>( 44 COLOR_BTNFACE + 1 45 ); 46 47 if (RegisterClass(&wc)) 48 { 49 HWND hWnd = 50 CreateWindow( 51 WndClassName, TEXT("Scaled Text Demo"), 52 WS_OVERLAPPEDWINDOW | WS_CAPTION | 53 WS_VISIBLE | WS_CLIPCHILDREN, 54 CW_USEDEFAULT, CW_USEDEFAULT, 800, 300, 55 NULL, NULL, hInst, NULL 56 ); 57 58 if (hWnd) 59 { 60 ShowWindow(hWnd, nCmdShow); 61 UpdateWindow(hWnd); 62 63 MSG msg; 64 while (GetMessage(&msg, NULL, 0, 0)) 65 { 66 TranslateMessage(&msg); 67 DispatchMessage(&msg); 68 } 69 } 70 } 71 return 0; 72 } 73 //------------------------------------------------------------------------- 74 75 76 HWND hTrackBar = NULL; 77 HFONT hTTFont = NULL; 78 double scale = 0.0; 79 LPCSTR pText = TEXT("The Scaled Text!"); 80 81 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, 82 LPARAM lParam) 83 { 84 switch (msg) 85 { 86 case WM_CREATE: 87 { 88 INITCOMMONCONTROLSEX icx; 89 icx.dwSize = sizeof(INITCOMMONCONTROLSEX); 90 icx.dwICC = ICC_BAR_CLASSES; 91 92 InitCommonControlsEx(&icx); 93 94 hTrackBar = 95 CreateWindow( 96 TRACKBAR_CLASS, "", 97 TBS_HORZ | TBS_BOTH | TBS_AUTOTICKS | 98 TBS_FIXEDLENGTH | TBS_ENABLESELRANGE | 99 WS_CHILD | WS_VISIBLE, 100 10, 260, 375, 40, 101 hWnd, NULL, hInst, NULL 102 ); 103 104 assert(hTrackBar != NULL); 105 SNDMSG(hTrackBar, TBM_SETTHUMBLENGTH, 20, 0); 106 SNDMSG(hTrackBar, TBM_SETRANGEMAX, TRUE, 100); 107 108 // create the TrueType (scalable) font 109 HDC hDC = GetDC(hWnd); 110 try 111 { 112 // see Chapter 4 for the definition of MakeFont 113 hTTFont = font::MakeFont(hDC, "Impact", 72); 114 if (!hTTFont) throw; 115 } 116 catch (...) 117 { 118 ReleaseDC(hWnd, hDC); 119 } 120 ReleaseDC(hWnd, hDC); 121 break; 122 } 123 case WM_HSCROLL: 124 { 125 if (reinterpret_cast<HWND>(lParam) == hTrackBar) 126 { 127 // 128 // adjust the scaling factor according to 129 // the position of the trackbar's slider 130 // 131 scale = static_cast<double>( 132 (SNDMSG(hTrackBar, TBM_GETPOS, 0, 0) + 1) / 50.0 133 ); 134 InvalidateRect(hWnd, NULL, true); 135 } 136 break; 137 } 138 case WM_ERASEBKGND: 139 { 140 LRESULT res = DefWindowProc(hWnd, msg, wParam, lParam); 141 142 HDC hDC = reinterpret_cast<HDC>(wParam); 143 HFONT hOldFont = static_cast<HFONT>( 144 SelectObject(hDC, hTTFont) 145 ); 146 try 147 { 148 SetBkMode(hDC, TRANSPARENT); 149 150 // open a path bracket 151 if (!BeginPath(hDC)) throw; 152 153 // record the text to the path 154 TextOut(hDC, 10, 10, pText, lstrlen(pText)); 155 156 // close the path bracket and 157 // select the path into hDC 158 EndPath(hDC); 159 160 // determine the number of endpoints in the path 161 const int num_points = GetPath(hDC, NULL, NULL, 0); 162 if (num_points > 0) 163 { 164 // make room for the POINTs and vertex types 165 POINT* pPEnds = new POINT[num_points]; 166 unsigned char* pTypes = new unsigned char[num_points]; 167 try 168 { 169 // get the path's description 170 int num_got = GetPath(hDC, pPEnds, pTypes, num_points); 171 if (num_got > 0) 172 { 173 // start a new path bracket 174 if (!BeginPath(hDC)) throw; 175 176 // scale each point in the description 177 int iPoint; 178 for (iPoint = 0; iPoint < num_got; ++iPoint) 179 { 180 pPEnds[iPoint].x = static_cast<LONG>( 181 scale * pPEnds[iPoint].x + 0.5 182 ); 183 pPEnds[iPoint].y = static_cast<LONG>( 184 scale * pPEnds[iPoint].y + 0.5 185 ); 186 } 187 188 for (iPoint = 0; iPoint < num_points; ++iPoint) 189 { 190 // handle the MoveToEx case 191 if (pTypes[iPoint] == PT_MOVETO) 192 { 193 MoveToEx( 194 hDC, pPEnds[iPoint].x, pPEnds[iPoint].y, NULL 195 ); 196 } 197 // handle the LineTo case 198 else if ( 199 pTypes[iPoint] == PT_LINETO || 200 pTypes[iPoint] == (PT_LINETO | PT_CLOSEFIGURE) 201 ) 202 { 203 LineTo(hDC, pPEnds[iPoint].x, pPEnds[iPoint].y); 204 } 205 // handle the PolyBezierTo case 206 else if ( 207 pTypes[iPoint] == PT_BEZIERTO || 208 pTypes[iPoint] == (PT_BEZIERTO | PT_CLOSEFIGURE) 209 ) 210 { 211 PolyBezierTo(hDC, pPEnds + iPoint, 3); 212 iPoint += 2; 213 } 214 } 215 216 // close the new path bracket 217 EndPath(hDC); 218 219 // stroke and fill the new path 220 StrokeAndFillPath(hDC); 221 } 222 } 223 catch (...) 224 { 225 // clean up 226 delete [] pTypes; 227 delete [] pPEnds; 228 throw; 229 } 230 // clean up 231 delete [] pTypes; 232 delete [] pPEnds; 233 } 234 // ... 235 } 236 catch (...) 237 { 238 SelectObject(hDC, hOldFont); 239 } 240 SelectObject(hDC, hOldFont); 241 return res; 242 } 243 case WM_SIZE: 244 { 245 MoveWindow( 246 hTrackBar, 247 0, HIWORD(lParam) - 40, LOWORD(lParam), 40, 248 false 249 ); 250 break; 251 } 252 case WM_DESTROY: 253 { 254 // clean up 255 DeleteObject(hTTFont); 256 PostQuitMessage(0); 257 break; 258 } 259 } 260 return DefWindowProc(hWnd, msg, wParam, lParam); 261 } 262 //------------------------------------------------------------------------- 263 264 265 266 267