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