1 2 // ------------------------------------------------------------------ 3 // Windows 2000 Graphics API Black Book 4 // Chapter 4 - Listing 4.2 (Font Enumeration 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 19 #ifndef SNDMSG 20 #define SNDMSG ::SendMessage 21 #endif /* ifndef SNDMSG */ 22 23 24 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 25 26 27 HWND hListBox = NULL; 28 const int ID_LISTBOX = 101; 29 30 HINSTANCE hInst; 31 const char* WndClassName = "GMainWnd"; 32 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, 33 LPARAM lParam); 34 35 36 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, 37 int nCmdShow) 38 { 39 hInst = hInstance; 40 41 WNDCLASS wc; 42 memset(&wc, 0, sizeof(WNDCLASS)); 43 44 wc.style = CS_VREDRAW | CS_HREDRAW; 45 wc.lpszClassName = WndClassName; 46 wc.lpfnWndProc = MainWndProc; 47 wc.hInstance = hInstance; 48 wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW); 49 wc.hbrBackground = reinterpret_cast<HBRUSH>( 50 COLOR_BTNFACE + 1 51 ); 52 53 if (RegisterClass(&wc)) 54 { 55 HWND hWnd = 56 CreateWindow( 57 WndClassName, TEXT("Font Enumeration Demo"), 58 WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | 59 WS_VISIBLE | WS_CLIPCHILDREN, 60 CW_USEDEFAULT, CW_USEDEFAULT, 295, 285, 61 NULL, NULL, hInst, NULL 62 ); 63 64 if (hWnd) 65 { 66 ShowWindow(hWnd, nCmdShow); 67 UpdateWindow(hWnd); 68 69 MSG msg; 70 while (GetMessage(&msg, NULL, 0, 0)) 71 { 72 TranslateMessage(&msg); 73 DispatchMessage(&msg); 74 } 75 } 76 } 77 return 0; 78 } 79 //------------------------------------------------------------------------- 80 81 82 int CALLBACK MyEnumFontFamExProc(ENUMLOGFONTEX *lpelfe, 83 NEWTEXTMETRICEX* lpntme, int FontType, LPARAM lParam) 84 { 85 if (FontType == TRUETYPE_FONTTYPE) 86 { 87 // if the typeface name is not already in the list 88 LPARAM name = reinterpret_cast<LPARAM>(lpelfe->elfFullName); 89 if (SNDMSG(hListBox, LB_FINDSTRINGEXACT, (ULONG)-1, name) == LB_ERR) 90 { 91 // add each font to the list box 92 int index = SNDMSG(hListBox, LB_ADDSTRING, 0, name); 93 94 // fix the size of the font 95 lpelfe->elfLogFont.lfHeight = -20; 96 lpelfe->elfLogFont.lfWidth = 0; 97 98 // create a new font and store its handle 99 // as the data of the newly added item 100 HFONT hFont = CreateFontIndirect(&lpelfe->elfLogFont); 101 SNDMSG(hListBox, LB_SETITEMDATA, index, 102 reinterpret_cast<LPARAM>(hFont)); 103 } 104 } 105 return TRUE; 106 } 107 //------------------------------------------------------------------------- 108 109 110 void AddScreenFonts() 111 { 112 // grab a handle to the screen's DC 113 HDC hScreenDC = GetDC(NULL); 114 try 115 { 116 // 117 // NOTE: Windows 95, 98 and Me requires that the lpLogfont 118 // (second) parameter of the EnumFontFamiliesEx function is 119 // non-NULL. This parameter can be NULL on Windows NT/2000. 120 // 121 LOGFONT lf = {0}; 122 lf.lfCharSet = DEFAULT_CHARSET; 123 124 // enumerate the current screen fonts 125 EnumFontFamiliesEx( 126 hScreenDC, &lf, 127 (FONTENUMPROC)MyEnumFontFamExProc, 128 0, 0 129 ); 130 } 131 catch (...) 132 { 133 // release the screen's DC 134 ReleaseDC(NULL, hScreenDC); 135 } 136 // release the screen's DC 137 ReleaseDC(NULL, hScreenDC); 138 } 139 //------------------------------------------------------------------------- 140 141 142 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, 143 LPARAM lParam) 144 { 145 switch (msg) 146 { 147 case WM_CREATE: 148 { 149 hListBox = 150 CreateWindowEx( 151 WS_EX_CLIENTEDGE, TEXT("LISTBOX"), TEXT(""), 152 WS_CHILD | WS_VISIBLE | LBS_STANDARD | 153 LBS_HASSTRINGS | LBS_OWNERDRAWFIXED, 154 20, 10, 250, 250, 155 hWnd, reinterpret_cast<HMENU>(ID_LISTBOX), 156 hInst, NULL 157 ); 158 if (hListBox) 159 { 160 AddScreenFonts(); 161 } 162 } 163 case WM_MEASUREITEM: 164 { 165 // grab a pointer to the MEASUREITEMSTRUCT structure 166 LPMEASUREITEMSTRUCT lpmis = 167 reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam); 168 169 // test the identifier of the control that 170 // the message is meant for 171 if ((int)lpmis->CtlID == ID_LISTBOX) 172 { 173 // adjust the height 174 lpmis->itemHeight = 25; 175 176 return TRUE; 177 } 178 break; 179 } 180 case WM_DRAWITEM: 181 { 182 // grab a pointer to the DRAWITEMSTRUCT structure 183 LPDRAWITEMSTRUCT lpdis = 184 reinterpret_cast<LPDRAWITEMSTRUCT>(lParam); 185 186 // test the identifier of the control that 187 // the message is meant for 188 if ((int)lpdis->CtlID == ID_LISTBOX) 189 { 190 COLORREF OldColor = GetTextColor(lpdis->hDC); 191 int stock = WHITE_BRUSH; 192 193 // if the item is currently selected 194 if (lpdis->itemState & ODS_SELECTED) 195 { 196 // set the text color to white and 197 // the background color to black 198 COLORREF clrWhite = PALETTERGB(255, 255, 255); 199 OldColor = SetTextColor(lpdis->hDC, clrWhite); 200 stock = BLACK_BRUSH; 201 } 202 FillRect( 203 lpdis->hDC, &lpdis->rcItem, 204 static_cast<HBRUSH>(GetStockObject(stock)) 205 ); 206 207 if ((int)lpdis->itemID != -1) 208 { 209 // extract the item's text 210 char text[MAX_PATH]; 211 SNDMSG(hListBox, LB_GETTEXT, lpdis->itemID, 212 reinterpret_cast<LPARAM>(text)); 213 214 // extract the corresponding font handle 215 DWORD value = 216 SNDMSG(hListBox, LB_GETITEMDATA, lpdis->itemID, 0); 217 HFONT hFont = reinterpret_cast<HFONT>(value); 218 219 // select the corresponding font 220 // into the device context 221 HFONT HOldFont = static_cast<HFONT>( 222 SelectObject(lpdis->hDC, hFont) 223 ); 224 225 // render the text transparently 226 SetBkMode(lpdis->hDC, TRANSPARENT); 227 228 // render the text 229 RECT RText = lpdis->rcItem; 230 InflateRect(&RText, -2, -2); 231 DrawText(lpdis->hDC, text, strlen(text), &RText, 232 DT_LEFT | DT_VCENTER | DT_SINGLELINE); 233 234 // restore the previous font 235 SelectObject(lpdis->hDC, HOldFont); 236 } 237 238 // render the focus rectangle 239 if (lpdis->itemState & ODS_FOCUS) 240 { 241 DrawFocusRect(lpdis->hDC, &lpdis->rcItem); 242 } 243 244 // restore the previous color/mode 245 SetTextColor(lpdis->hDC, OldColor); 246 SetBkMode(lpdis->hDC, OPAQUE); 247 248 return TRUE; 249 } 250 break; 251 } 252 case WM_DESTROY: 253 { 254 // delete each created font object 255 int count = SNDMSG(hListBox, LB_GETCOUNT, 0, 0); 256 for (int index = 0; index < count; ++index) 257 { 258 DWORD value = SNDMSG(hListBox, LB_GETITEMDATA, index, 0); 259 DeleteObject(reinterpret_cast<HFONT>(value)); 260 } 261 262 PostQuitMessage(0); 263 break; 264 } 265 } 266 return DefWindowProc(hWnd, msg, wParam, lParam); 267 } 268 //------------------------------------------------------------------------- 269 270 271 272