6 * Copyright (C) 2007 Timo Kreuzer <timo <dot> kreuzer <at> reactos <dot> org>
7 * Copyright (C) 2016-2017 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 HINSTANCE g_hInstance
;
37 LOGFONTW g_LogFonts
[64];
39 WCHAR g_FontTitle
[1024] = L
"";
40 BOOL g_FontPrint
= FALSE
;
42 static const WCHAR g_szFontViewClassName
[] = L
"FontViewWClass";
44 /* GetFontResourceInfoW is undocumented */
45 BOOL WINAPI
GetFontResourceInfoW(LPCWSTR lpFileName
, DWORD
*pdwBufSize
, void* lpBuffer
, DWORD dwType
);
62 len
= LoadStringW(hInstance
, dwStringId
, (LPWSTR
)Buffer
, 1000);
66 dwFlags
|= FORMAT_MESSAGE_FROM_STRING
;
67 dwFlags
&= ~(FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_FROM_SYSTEM
);
68 dwRet
= FormatMessageW(dwFlags
, Buffer
, 0, dwLanguageId
, lpBuffer
, nSize
, Arguments
);
75 ErrorMsgBox(HWND hParent
, DWORD dwMessageId
, ...)
77 HLOCAL hMemCaption
= NULL
;
78 HLOCAL hMemText
= NULL
;
81 va_start(args
, dwMessageId
);
82 FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER
,
83 NULL
, dwMessageId
, 0, (LPWSTR
)&hMemText
, 0, &args
);
86 FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER
,
87 NULL
, IDS_ERROR
, 0, (LPWSTR
)&hMemCaption
, 0, NULL
);
89 MessageBoxW(hParent
, hMemText
, hMemCaption
, MB_ICONERROR
);
91 LocalFree(hMemCaption
);
96 wWinMain(HINSTANCE hThisInstance
,
97 HINSTANCE hPrevInstance
,
104 WCHAR szFileName
[MAX_PATH
] = L
"";
111 switch (GetUserDefaultUILanguage())
113 case MAKELANGID(LANG_HEBREW
, SUBLANG_DEFAULT
):
114 SetProcessDefaultLayout(LAYOUT_RTL
);
121 g_hInstance
= hThisInstance
;
123 /* Get unicode command line */
124 argv
= CommandLineToArgvW(GetCommandLineW(), &argc
);
127 OPENFILENAMEW fontOpen
;
128 WCHAR filter
[MAX_PATH
*2], dialogTitle
[MAX_PATH
];
130 LoadStringW(NULL
, IDS_OPEN
, dialogTitle
, ARRAYSIZE(dialogTitle
));
131 LoadStringW(NULL
, IDS_FILTER_LIST
, filter
, ARRAYSIZE(filter
));
133 /* Clears out any values of fontOpen before we use it */
134 ZeroMemory(&fontOpen
, sizeof(fontOpen
));
136 /* Sets up the open dialog box */
137 fontOpen
.lStructSize
= sizeof(fontOpen
);
138 fontOpen
.hwndOwner
= NULL
;
139 fontOpen
.lpstrFilter
= filter
;
140 fontOpen
.lpstrFile
= szFileName
;
141 fontOpen
.lpstrTitle
= dialogTitle
;
142 fontOpen
.nMaxFile
= MAX_PATH
;
143 fontOpen
.Flags
= OFN_EXPLORER
| OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
;
144 fontOpen
.lpstrDefExt
= L
"ttf";
146 /* Opens up the Open File dialog box in order to chose a font file. */
147 if(GetOpenFileNameW(&fontOpen
))
149 fileName
= fontOpen
.lpstrFile
;
150 g_fileName
= fileName
;
152 /* If the user decides to close out of the open dialog effectively
153 exiting the program altogether */
159 /* Try to add the font resource from command line */
160 // fileName = argv[1];
167 /* Windows fontview supports the /p option, which displays print dialog */
169 if (wcscmp(argv
[1], L
"/p") == 0)
178 g_fileName
= fileName
;
181 if (!AddFontResourceW(fileName
))
183 ErrorMsgBox(0, IDS_ERROR_NOFONT
, fileName
);
187 /* Get the font name */
188 dwSize
= sizeof(g_LogFonts
);
189 ZeroMemory(g_LogFonts
, sizeof(g_LogFonts
));
190 if (!GetFontResourceInfoW(fileName
, &dwSize
, g_LogFonts
, 2))
192 ErrorMsgBox(0, IDS_ERROR_NOFONT
, fileName
);
196 for (i
= 0; i
< ARRAYSIZE(g_LogFonts
); ++i
)
198 if (g_LogFonts
[i
].lfFaceName
[0] == 0)
205 ErrorMsgBox(0, IDS_ERROR_NOFONT
, fileName
);
210 dwSize
= sizeof(g_FontTitle
);
211 ZeroMemory(g_FontTitle
, sizeof(g_FontTitle
));
212 GetFontResourceInfoW(fileName
, &dwSize
, g_FontTitle
, 1);
214 if (!Display_InitClass(hThisInstance
))
216 ErrorMsgBox(0, IDS_ERROR_NOCLASS
);
220 /* The main window class */
221 wincl
.cbSize
= sizeof (WNDCLASSEXW
);
222 wincl
.style
= CS_DBLCLKS
;
223 wincl
.lpfnWndProc
= MainWndProc
;
224 wincl
.cbClsExtra
= 0;
225 wincl
.cbWndExtra
= 0;
226 wincl
.hInstance
= hThisInstance
;
227 wincl
.hIcon
= LoadIcon (GetModuleHandle(NULL
), MAKEINTRESOURCE(IDI_TT
));
228 wincl
.hCursor
= LoadCursor (NULL
, IDC_ARROW
);
229 wincl
.hbrBackground
= (HBRUSH
)COLOR_BACKGROUND
;
230 wincl
.lpszMenuName
= NULL
;
231 wincl
.lpszClassName
= g_szFontViewClassName
;
232 wincl
.hIconSm
= LoadIcon (GetModuleHandle(NULL
), MAKEINTRESOURCE(IDI_TT
));
234 /* Register the window class, and if it fails quit the program */
235 if (!RegisterClassExW (&wincl
))
237 ErrorMsgBox(0, IDS_ERROR_NOCLASS
);
241 /* The class is registered, let's create the main window */
242 hMainWnd
= CreateWindowExW(
243 0, /* Extended possibilities for variation */
244 g_szFontViewClassName
, /* Classname */
245 g_FontTitle
, /* Title Text */
246 WS_OVERLAPPEDWINDOW
, /* default window */
247 CW_USEDEFAULT
, /* Windows decides the position */
248 CW_USEDEFAULT
, /* where the window ends up on the screen */
249 544, /* The programs width */
250 375, /* and height in pixels */
251 HWND_DESKTOP
, /* The window is a child-window to desktop */
253 hThisInstance
, /* Program Instance handler */
254 NULL
/* No Window Creation data */
256 ShowWindow(hMainWnd
, nCmdShow
);
258 /* Main message loop */
259 while (GetMessage (&msg
, NULL
, 0, 0))
261 if (IsDialogMessage(hMainWnd
, &msg
))
263 TranslateMessage(&msg
);
264 DispatchMessage(&msg
);
267 RemoveFontResourceW(argv
[1]);
269 return (int)msg
.wParam
;
273 MainWnd_OnCreate(HWND hwnd
)
275 WCHAR szQuit
[MAX_BUTTONNAME
];
276 WCHAR szPrint
[MAX_BUTTONNAME
];
277 WCHAR szString
[MAX_STRING
];
278 WCHAR szPrevious
[MAX_STRING
];
279 WCHAR szNext
[MAX_STRING
];
280 HWND hDisplay
, hButtonInstall
, hButtonPrint
, hButtonPrev
, hButtonNext
;
282 /* create the display window */
283 hDisplay
= CreateWindowExW(
284 0, /* Extended style */
285 g_szFontDisplayClassName
, /* Classname */
286 L
"", /* Title text */
287 WS_CHILD
| WS_VSCROLL
, /* Window style */
289 HEADER_SIZE
, /* Y-Pos */
291 370-HEADER_SIZE
, /* Height */
293 (HMENU
)IDC_DISPLAY
, /* Identifier */
294 g_hInstance
, /* Program Instance handler */
295 NULL
/* Window Creation data */
298 LoadStringW(g_hInstance
, IDS_STRING
, szString
, MAX_STRING
);
299 SendMessage(hDisplay
, FVM_SETSTRING
, 0, (LPARAM
)szString
);
301 /* Create the install button */
302 LoadStringW(g_hInstance
, IDS_INSTALL
, szQuit
, MAX_BUTTONNAME
);
303 hButtonInstall
= CreateWindowExW(
304 0, /* Extended style */
305 L
"button", /* Classname */
306 szQuit
, /* Title text */
307 WS_CHILD
| WS_VISIBLE
, /* Window style */
308 BUTTON_POS_X
, /* X-pos */
309 BUTTON_POS_Y
, /* Y-Pos */
310 BUTTON_WIDTH
, /* Width */
311 BUTTON_HEIGHT
, /* Height */
313 (HMENU
)IDC_INSTALL
, /* Identifier */
314 g_hInstance
, /* Program Instance handler */
315 NULL
/* Window Creation data */
317 SendMessage(hButtonInstall
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), (LPARAM
)TRUE
);
319 /* Create the print button */
320 LoadStringW(g_hInstance
, IDS_PRINT
, szPrint
, MAX_BUTTONNAME
);
321 hButtonPrint
= CreateWindowExW(
322 0, /* Extended style */
323 L
"button", /* Classname */
324 szPrint
, /* Title text */
325 WS_CHILD
| WS_VISIBLE
, /* Window style */
327 BUTTON_POS_Y
, /* Y-Pos */
328 BUTTON_WIDTH
, /* Width */
329 BUTTON_HEIGHT
, /* Height */
331 (HMENU
)IDC_PRINT
, /* Identifier */
332 g_hInstance
, /* Program Instance handler */
333 NULL
/* Window Creation data */
335 SendMessage(hButtonPrint
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), (LPARAM
)TRUE
);
337 /* Create the previous button */
338 LoadStringW(g_hInstance
, IDS_PREVIOUS
, szPrevious
, MAX_BUTTONNAME
);
339 hButtonPrev
= CreateWindowExW(
340 0, /* Extended style */
341 L
"button", /* Classname */
342 szPrevious
, /* Title text */
343 WS_CHILD
| WS_VISIBLE
, /* Window style */
345 BUTTON_POS_Y
, /* Y-Pos */
346 BUTTON_WIDTH
, /* Width */
347 BUTTON_HEIGHT
, /* Height */
349 (HMENU
)IDC_PREV
, /* Identifier */
350 g_hInstance
, /* Program Instance handler */
351 NULL
/* Window Creation data */
353 SendMessage(hButtonPrev
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), (LPARAM
)TRUE
);
355 /* Create the next button */
356 LoadStringW(g_hInstance
, IDS_NEXT
, szNext
, MAX_BUTTONNAME
);
357 hButtonNext
= CreateWindowExW(
358 0, /* Extended style */
359 L
"button", /* Classname */
360 szNext
, /* Title text */
361 WS_CHILD
| WS_VISIBLE
, /* Window style */
363 BUTTON_POS_Y
, /* Y-Pos */
364 BUTTON_WIDTH
, /* Width */
365 BUTTON_HEIGHT
, /* Height */
367 (HMENU
)IDC_NEXT
, /* Identifier */
368 g_hInstance
, /* Program Instance handler */
369 NULL
/* Window Creation data */
371 SendMessage(hButtonNext
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), (LPARAM
)TRUE
);
373 EnableWindow(hButtonPrev
, FALSE
);
375 EnableWindow(hButtonNext
, FALSE
);
377 /* Init the display window with the font name */
379 SendMessage(hDisplay
, FVM_SETTYPEFACE
, 0, (LPARAM
)&g_LogFonts
[g_FontIndex
]);
380 ShowWindow(hDisplay
, SW_SHOWNORMAL
);
383 PostMessage(hwnd
, WM_COMMAND
, IDC_PRINT
, 0);
389 MainWnd_OnSize(HWND hwnd
)
392 HWND hInstall
, hPrint
, hPrev
, hNext
, hDisplay
;
395 GetClientRect(hwnd
, &rc
);
397 hDWP
= BeginDeferWindowPos(5);
399 hInstall
= GetDlgItem(hwnd
, IDC_INSTALL
);
401 hDWP
= DeferWindowPos(hDWP
, hInstall
, NULL
, BUTTON_POS_X
, BUTTON_POS_Y
, BUTTON_WIDTH
, BUTTON_HEIGHT
, SWP_NOZORDER
);
403 hPrint
= GetDlgItem(hwnd
, IDC_PRINT
);
405 hDWP
= DeferWindowPos(hDWP
, hPrint
, NULL
, BUTTON_POS_X
+ BUTTON_WIDTH
+ BUTTON_PADDING
, BUTTON_POS_Y
, BUTTON_WIDTH
, BUTTON_HEIGHT
, SWP_NOZORDER
);
407 hPrev
= GetDlgItem(hwnd
, IDC_PREV
);
409 hDWP
= DeferWindowPos(hDWP
, hPrev
, NULL
, rc
.right
- (BUTTON_WIDTH
* 2 + BUTTON_PADDING
+ BUTTON_POS_X
), BUTTON_POS_Y
, BUTTON_WIDTH
, BUTTON_HEIGHT
, SWP_NOZORDER
);
411 hNext
= GetDlgItem(hwnd
, IDC_NEXT
);
413 hDWP
= DeferWindowPos(hDWP
, hNext
, NULL
, rc
.right
- (BUTTON_WIDTH
+ BUTTON_POS_X
), BUTTON_POS_Y
, BUTTON_WIDTH
, BUTTON_HEIGHT
, SWP_NOZORDER
);
415 hDisplay
= GetDlgItem(hwnd
, IDC_DISPLAY
);
417 hDWP
= DeferWindowPos(hDWP
, hDisplay
, NULL
, 0, HEADER_SIZE
, rc
.right
, rc
.bottom
- HEADER_SIZE
, SWP_NOZORDER
);
419 EndDeferWindowPos(hDWP
);
421 InvalidateRect(hwnd
, NULL
, TRUE
);
427 MainWnd_OnPaint(HWND hwnd
)
433 hDC
= BeginPaint(hwnd
, &ps
);
434 GetClientRect(hwnd
, &rc
);
435 rc
.top
= HEADER_SIZE
- 2;
436 rc
.bottom
= HEADER_SIZE
;
437 FillRect(hDC
, &rc
, GetStockObject(GRAY_BRUSH
));
443 MainWnd_OnInstall(HWND hwnd
)
445 WCHAR szFullName
[64];
447 WCHAR szSrcPath
[MAX_PATH
];
448 WCHAR szDestPath
[MAX_PATH
];
453 SendDlgItemMessage(hwnd
, IDC_DISPLAY
, FVM_GETFULLNAME
, 64, (LPARAM
)szFullName
);
454 // MessageBoxW(hwnd, szFullName, L"Debug", MB_OK);
456 /* First, we have to find out if the font still exists */
457 if (GetFileAttributes(g_fileName
) == INVALID_FILE_ATTRIBUTES
)
459 /* Fail, if the source file does not exist */
460 ErrorMsgBox(0, IDS_ERROR_NOFONT
, g_fileName
);
464 /* Build the full destination file name */
465 GetFullPathNameW(g_fileName
, MAX_PATH
, szSrcPath
, &pszFileName
);
467 GetWindowsDirectoryW(szDestPath
, MAX_PATH
);
468 wcscat(szDestPath
, L
"\\Fonts\\");
469 wcscat(szDestPath
, pszFileName
);
472 // MessageBoxW(hwnd, szDestPath, L"szDestPath", MB_OK);
473 // MessageBoxW(hwnd, pszFileName, L"pszFileExt", MB_OK);
475 /* Check if the file already exists */
476 if (GetFileAttributesW(szDestPath
) != INVALID_FILE_ATTRIBUTES
)
478 MessageBoxW(hwnd
, L
"This font is already installed!", L
"Already Installed", MB_OK
);
482 /* Copy the font file */
483 if (!CopyFileW(g_fileName
, szDestPath
, TRUE
))
485 MessageBoxW(hwnd
,L
"Failed to copy the font file!", L
"File Error", MB_OK
);
489 /* Open the fonts key */
490 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
491 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
495 if (res
!= ERROR_SUCCESS
)
497 MessageBoxW(hwnd
, L
"Failed top open the fonts key!", L
"Debug1", MB_OK
);
501 /* Register the font */
502 res
= RegSetValueExW(hKey
,
507 (wcslen(pszFileName
) + 1) * sizeof(WCHAR
));
508 if (res
!= ERROR_SUCCESS
)
510 MessageBoxW(hwnd
, L
"Failed to register the new font!", L
"Debug2", MB_OK
);
515 /* Close the fonts key */
518 /* if all of this goes correctly, message the user about success */
519 MessageBoxW(hwnd
, L
"Font Installation Completed.", L
"Success", MB_OK
);
525 MainWnd_OnPrev(HWND hwnd
)
531 EnableWindow(GetDlgItem(hwnd
, IDC_NEXT
), TRUE
);
532 if (g_FontIndex
== 0)
533 EnableWindow(GetDlgItem(hwnd
, IDC_PREV
), FALSE
);
535 hDisplay
= GetDlgItem(hwnd
, IDC_DISPLAY
);
536 SendMessage(hDisplay
, FVM_SETTYPEFACE
, 0, (LPARAM
)&g_LogFonts
[g_FontIndex
]);
537 InvalidateRect(hDisplay
, NULL
, TRUE
);
543 MainWnd_OnNext(HWND hwnd
)
546 if (g_FontIndex
+ 1 < g_NumFonts
)
549 EnableWindow(GetDlgItem(hwnd
, IDC_PREV
), TRUE
);
550 if (g_FontIndex
== g_NumFonts
- 1)
551 EnableWindow(GetDlgItem(hwnd
, IDC_NEXT
), FALSE
);
553 hDisplay
= GetDlgItem(hwnd
, IDC_DISPLAY
);
554 SendMessage(hDisplay
, FVM_SETTYPEFACE
, 0, (LPARAM
)&g_LogFonts
[g_FontIndex
]);
555 InvalidateRect(hDisplay
, NULL
, TRUE
);
561 MainWndProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
566 return MainWnd_OnCreate(hwnd
);
569 return MainWnd_OnPaint(hwnd
);
572 return MainWnd_OnSize(hwnd
);
575 switch(LOWORD(wParam
))
578 return MainWnd_OnInstall(hwnd
);
581 return Display_OnPrint(hwnd
);
584 return MainWnd_OnPrev(hwnd
);
587 return MainWnd_OnNext(hwnd
);
592 PostQuitMessage (0); /* send a WM_QUIT to the message queue */
595 default: /* for messages that we don't deal with */
596 return DefWindowProcW(hwnd
, message
, wParam
, lParam
);