Synchronize with trunk revision 59781.
[reactos.git] / base / applications / fontview / fontview.c
1 /*
2 * fontview
3 *
4 * fontview.c
5 *
6 * Copyright (C) 2007 Timo Kreuzer <timo <dot> kreuzer <at> reactos <dot> org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include "fontview.h"
24
25 HINSTANCE g_hInstance;
26 EXTLOGFONTW g_ExtLogFontW;
27 LPCWSTR g_fileName;
28
29 static const WCHAR g_szFontViewClassName[] = L"FontViewWClass";
30
31 /* Tye definition for the GetFontResourceInfo function */
32 typedef BOOL (WINAPI *PGFRI)(LPCWSTR, DWORD *, LPVOID, DWORD);
33
34 DWORD
35 FormatString(
36 DWORD dwFlags,
37 HINSTANCE hInstance,
38 DWORD dwStringId,
39 DWORD dwLanguageId,
40 LPWSTR lpBuffer,
41 DWORD nSize,
42 va_list* Arguments
43 )
44 {
45 DWORD dwRet;
46 int len;
47 WCHAR Buffer[1000];
48
49 len = LoadStringW(hInstance, dwStringId, (LPWSTR)Buffer, 1000);
50
51 if (len)
52 {
53 dwFlags |= FORMAT_MESSAGE_FROM_STRING;
54 dwFlags &= ~(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM);
55 dwRet = FormatMessageW(dwFlags, Buffer, 0, dwLanguageId, lpBuffer, nSize, Arguments);
56 return dwRet;
57 }
58 return 0;
59 }
60
61 static void
62 ErrorMsgBox(HWND hParent, DWORD dwCaptionID, DWORD dwMessageId, ...)
63 {
64 HLOCAL hMemCaption = NULL;
65 HLOCAL hMemText = NULL;
66 va_list args;
67
68 va_start(args, dwMessageId);
69 FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER,
70 NULL, dwMessageId, 0, (LPWSTR)&hMemText, 0, &args);
71 va_end(args);
72
73 FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER,
74 NULL, dwCaptionID, 0, (LPWSTR)&hMemCaption, 0, NULL);
75
76 MessageBoxW(hParent, hMemText, hMemCaption, MB_ICONERROR);
77
78 LocalFree(hMemCaption);
79 LocalFree(hMemText);
80 }
81
82 int WINAPI
83 WinMain (HINSTANCE hThisInstance,
84 HINSTANCE hPrevInstance,
85 LPSTR lpCmdLine,
86 int nCmdShow)
87 {
88 int argc;
89 WCHAR** argv;
90 DWORD dwSize;
91 HWND hMainWnd;
92 MSG msg;
93 WNDCLASSEXW wincl;
94 HINSTANCE hDLL;
95 PGFRI GetFontResourceInfoW;
96 LPCWSTR fileName;
97
98 switch (GetUserDefaultUILanguage())
99 {
100 case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
101 SetProcessDefaultLayout(LAYOUT_RTL);
102 break;
103
104 default:
105 break;
106 }
107
108 g_hInstance = hThisInstance;
109
110 /* Get unicode command line */
111 argv = CommandLineToArgvW(GetCommandLineW(), &argc);
112 if (argc < 2)
113 {
114 OPENFILENAMEW fontOpen;
115 WCHAR szFileName[MAX_PATH] = L"";
116 HLOCAL dialogTitle = NULL;
117
118 /* Gets the title for the dialog box ready */
119 FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER,
120 NULL, IDS_OPEN, 0, (LPWSTR)&dialogTitle, 0, NULL);
121
122 /* Clears out any values of fontOpen before we use it */
123 ZeroMemory(&fontOpen, sizeof(fontOpen));
124
125 /* Sets up the open dialog box */
126 fontOpen.lStructSize = sizeof(fontOpen);
127 fontOpen.hwndOwner = NULL;
128 fontOpen.lpstrFilter = L"TrueType Font (*.ttf)\0*.ttf\0"
129 L"All Files (*.*)\0*.*\0";
130 fontOpen.lpstrFile = szFileName;
131 fontOpen.lpstrTitle = dialogTitle;
132 fontOpen.nMaxFile = MAX_PATH;
133 fontOpen.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
134 fontOpen.lpstrDefExt = L"ttf";
135
136 /* Opens up the Open File dialog box in order to chose a font file. */
137 if(GetOpenFileNameW(&fontOpen))
138 {
139 fileName = fontOpen.lpstrFile;
140 g_fileName = fileName;
141 } else {
142 /* If the user decides to close out of the open dialog effectively
143 exiting the program altogether */
144 return 0;
145 }
146
147 LocalFree(dialogTitle);
148 }
149 else
150 {
151 /* Try to add the font resource from command line */
152 fileName = argv[1];
153 g_fileName = fileName;
154 }
155
156 if (!AddFontResourceW(fileName))
157 {
158 ErrorMsgBox(0, IDS_ERROR, IDS_ERROR_NOFONT, fileName);
159 return -1;
160 }
161
162 /* Load the GetFontResourceInfo function from gdi32.dll */
163 hDLL = LoadLibraryW(L"GDI32.DLL");
164 GetFontResourceInfoW = (PGFRI)GetProcAddress(hDLL, "GetFontResourceInfoW");
165
166 /* Get the font name */
167 dwSize = sizeof(g_ExtLogFontW.elfFullName);
168 if (!GetFontResourceInfoW(fileName, &dwSize, g_ExtLogFontW.elfFullName, 1))
169 {
170 ErrorMsgBox(0, IDS_ERROR, IDS_ERROR_NOFONT, fileName);
171 return -1;
172 }
173
174 dwSize = sizeof(LOGFONTW);
175 if (!GetFontResourceInfoW(fileName, &dwSize, &g_ExtLogFontW.elfLogFont, 2))
176 {
177 ErrorMsgBox(0, IDS_ERROR, IDS_ERROR_NOFONT, fileName);
178 return -1;
179 }
180
181 if (!Display_InitClass(hThisInstance))
182 {
183 ErrorMsgBox(0, IDS_ERROR, IDS_ERROR_NOCLASS);
184 return -1;
185 }
186
187 /* The main window class */
188 wincl.cbSize = sizeof (WNDCLASSEXW);
189 wincl.style = CS_DBLCLKS;
190 wincl.lpfnWndProc = MainWndProc;
191 wincl.cbClsExtra = 0;
192 wincl.cbWndExtra = 0;
193 wincl.hInstance = hThisInstance;
194 wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
195 wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
196 wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
197 wincl.lpszMenuName = NULL;
198 wincl.lpszClassName = g_szFontViewClassName;
199 wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
200
201 /* Register the window class, and if it fails quit the program */
202 if (!RegisterClassExW (&wincl))
203 {
204 ErrorMsgBox(0, IDS_ERROR, IDS_ERROR_NOCLASS);
205 return 0;
206 }
207
208 /* The class is registered, let's create the main window */
209 hMainWnd = CreateWindowExW(
210 0, /* Extended possibilites for variation */
211 g_szFontViewClassName, /* Classname */
212 g_ExtLogFontW.elfFullName,/* Title Text */
213 WS_OVERLAPPEDWINDOW, /* default window */
214 CW_USEDEFAULT, /* Windows decides the position */
215 CW_USEDEFAULT, /* where the window ends up on the screen */
216 544, /* The programs width */
217 375, /* and height in pixels */
218 HWND_DESKTOP, /* The window is a child-window to desktop */
219 NULL, /* No menu */
220 hThisInstance, /* Program Instance handler */
221 NULL /* No Window Creation data */
222 );
223 ShowWindow(hMainWnd, nCmdShow);
224
225 /* Main message loop */
226 while (GetMessage (&msg, NULL, 0, 0))
227 {
228 TranslateMessage(&msg);
229 DispatchMessage(&msg);
230 }
231
232 RemoveFontResourceW(argv[1]);
233
234 return (int)msg.wParam;
235 }
236
237 static LRESULT
238 MainWnd_OnCreate(HWND hwnd)
239 {
240 WCHAR szQuit[MAX_BUTTONNAME];
241 WCHAR szPrint[MAX_BUTTONNAME];
242 WCHAR szString[MAX_STRING];
243 HWND hDisplay, hButtonInstall, hButtonPrint;
244
245 /* create the display window */
246 hDisplay = CreateWindowExW(
247 0, /* Extended style */
248 g_szFontDisplayClassName, /* Classname */
249 L"", /* Title text */
250 WS_CHILD | WS_VSCROLL, /* Window style */
251 0, /* X-pos */
252 HEADER_SIZE, /* Y-Pos */
253 550, /* Width */
254 370-HEADER_SIZE, /* Height */
255 hwnd, /* Parent */
256 (HMENU)IDC_DISPLAY, /* Identifier */
257 g_hInstance, /* Program Instance handler */
258 NULL /* Window Creation data */
259 );
260
261 LoadStringW(g_hInstance, IDS_STRING, szString, MAX_STRING);
262 SendMessage(hDisplay, FVM_SETSTRING, 0, (LPARAM)szString);
263
264 /* Init the display window with the font name */
265 SendMessage(hDisplay, FVM_SETTYPEFACE, 0, (LPARAM)&g_ExtLogFontW);
266 ShowWindow(hDisplay, SW_SHOWNORMAL);
267
268 /* Create the quit button */
269 LoadStringW(g_hInstance, IDS_INSTALL, szQuit, MAX_BUTTONNAME);
270 hButtonInstall = CreateWindowExW(
271 0, /* Extended style */
272 L"button", /* Classname */
273 szQuit, /* Title text */
274 WS_CHILD | WS_VISIBLE, /* Window style */
275 BUTTON_POS_X, /* X-pos */
276 BUTTON_POS_Y, /* Y-Pos */
277 BUTTON_WIDTH, /* Width */
278 BUTTON_HEIGHT, /* Height */
279 hwnd, /* Parent */
280 (HMENU)IDC_INSTALL, /* Identifier */
281 g_hInstance, /* Program Instance handler */
282 NULL /* Window Creation data */
283 );
284 SendMessage(hButtonInstall, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
285
286 /* Create the print button */
287 LoadStringW(g_hInstance, IDS_PRINT, szPrint, MAX_BUTTONNAME);
288 hButtonPrint = CreateWindowExW(
289 0, /* Extended style */
290 L"button", /* Classname */
291 szPrint, /* Title text */
292 WS_CHILD | WS_VISIBLE, /* Window style */
293 450, /* X-pos */
294 BUTTON_POS_Y, /* Y-Pos */
295 BUTTON_WIDTH, /* Width */
296 BUTTON_HEIGHT, /* Height */
297 hwnd, /* Parent */
298 (HMENU)IDC_PRINT, /* Identifier */
299 g_hInstance, /* Program Instance handler */
300 NULL /* Window Creation data */
301 );
302 SendMessage(hButtonPrint, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
303
304 return 0;
305 }
306
307 static LRESULT
308 MainWnd_OnSize(HWND hwnd)
309 {
310 RECT rc;
311
312 GetClientRect(hwnd, &rc);
313 MoveWindow(GetDlgItem(hwnd, IDC_PRINT), rc.right - BUTTON_WIDTH - BUTTON_POS_X, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, TRUE);
314 MoveWindow(GetDlgItem(hwnd, IDC_DISPLAY), 0, HEADER_SIZE, rc.right, rc.bottom - HEADER_SIZE, TRUE);
315
316 return 0;
317 }
318
319 static LRESULT
320 MainWnd_OnPaint(HWND hwnd)
321 {
322 HDC hDC;
323 PAINTSTRUCT ps;
324 RECT rc;
325
326 hDC = BeginPaint(hwnd, &ps);
327 GetClientRect(hwnd, &rc);
328 rc.top = HEADER_SIZE - 2;
329 rc.bottom = HEADER_SIZE;
330 FillRect(hDC, &rc, GetStockObject(GRAY_BRUSH));
331 EndPaint(hwnd, &ps);
332 return 0;
333 }
334
335 static LRESULT
336 MainWnd_OnInstall(HWND hwnd)
337 {
338 DWORD fontExists;
339
340 /* First, we have to find out if the font still exists. */
341 fontExists = GetFileAttributes((LPCSTR)g_fileName);
342 if (fontExists != 0xFFFFFFFF) /* If the file does not exist */
343 {
344 ErrorMsgBox(0, IDS_ERROR, IDS_ERROR_NOFONT, g_fileName);
345 return -1;
346 }
347
348 //CopyFile(g_fileName, NULL, TRUE);
349
350 MessageBox(hwnd, TEXT("This function is unimplemented"), TEXT("Unimplemented"), MB_OK);
351
352 return 0;
353 }
354
355 LRESULT CALLBACK
356 MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
357 {
358 switch (message)
359 {
360 case WM_CREATE:
361 return MainWnd_OnCreate(hwnd);
362
363 case WM_PAINT:
364 return MainWnd_OnPaint(hwnd);
365
366 case WM_SIZE:
367 return MainWnd_OnSize(hwnd);
368
369 case WM_COMMAND:
370 switch(LOWORD(wParam))
371 {
372 case IDC_INSTALL:
373 return MainWnd_OnInstall(hwnd);
374 break;
375
376 case IDC_PRINT:
377 return Display_OnPrint(hwnd);
378 break;
379 }
380 break;
381
382 case WM_DESTROY:
383 PostQuitMessage (0); /* send a WM_QUIT to the message queue */
384 break;
385
386 default: /* for messages that we don't deal with */
387 return DefWindowProcW(hwnd, message, wParam, lParam);
388 }
389
390 return 0;
391 }
392
393 /* EOF */