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
WinMain(HINSTANCE hInstance,HINSTANCE,LPTSTR,int nCmdShow)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
MyEnumFontFamExProc(ENUMLOGFONTEX * lpelfe,NEWTEXTMETRICEX * lpntme,int FontType,LPARAM lParam)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
AddScreenFonts()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
MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)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