ReactOS  0.4.14-dev-98-gb0d4763
fontwnd.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS VGA Font Editor
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Implements the MDI child window for a font
5  * COPYRIGHT: Copyright 2008 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 static const WCHAR szFontWndClass[] = L"VGAFontEditFontWndClass";
11 
12 static BOOL
14 {
15  Info->Font = (PBITMAP_FONT) HeapAlloc( hProcessHeap, 0, sizeof(BITMAP_FONT) );
16 
17  if(Info->OpenInfo->bCreateNew)
18  {
19  ZeroMemory( Info->Font, sizeof(BITMAP_FONT) );
20  return TRUE;
21  }
22  else
23  {
24  // Load a font
25  BOOL bRet = FALSE;
26  DWORD dwTemp;
27  HANDLE hFile;
28 
29  hFile = CreateFileW(Info->OpenInfo->pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
30 
32  {
34  return FALSE;
35  }
36 
37  // Let's first check the file size to determine the file type
38  dwTemp = GetFileSize(hFile, NULL);
39 
40  switch(dwTemp)
41  {
42  case 2048:
43  // It should be a binary font file
44  Info->OpenInfo->bBinaryFileOpened = TRUE;
45 
46  if( ReadFile(hFile, Info->Font, sizeof(BITMAP_FONT), &dwTemp, NULL) )
47  bRet = TRUE;
48  else
50 
51  break;
52 
53  case 2052:
54  {
56 
57  // Probably it's a PSFv1 file, check the header to make sure
58  if( !ReadFile(hFile, &Header, sizeof(PSF1_HEADER) , &dwTemp, NULL) )
59  {
61  break;
62  }
63  else
64  {
65  if(Header.uMagic[0] == PSF1_MAGIC0 && Header.uMagic[1] == PSF1_MAGIC1)
66  {
67  // Yes, it is a PSFv1 file.
68  // Check the mode and character size. We only support 8x8 fonts with no special mode.
69  if(Header.uCharSize == 8 && Header.uMode == 0)
70  {
71  // Perfect! The file pointer is already set correctly, so we can just read the font bitmap now.
72  if( ReadFile(hFile, Info->Font, sizeof(BITMAP_FONT), &dwTemp, NULL) )
73  bRet = TRUE;
74  else
76  }
77  else
79 
80  break;
81  }
82 
83  // Fall through if the magic numbers aren't there
84  }
85  }
86 
87  default:
89  }
90 
92  return bRet;
93  }
94 }
95 
96 static LRESULT CALLBACK
98 {
100 
102 
103  if(Info || uMsg == WM_CREATE)
104  {
105  switch(uMsg)
106  {
107  case WM_CHILDACTIVATE:
108  Info->MainWndInfo->CurrentFontWnd = Info;
109  SetToolbarFileButtonState(Info->MainWndInfo, TRUE);
110  SetPasteButtonState(Info->MainWndInfo);
111  break;
112 
113  case WM_CREATE:
114  Info = (PFONT_WND_INFO)( ( (LPMDICREATESTRUCT) ( (LPCREATESTRUCT)lParam )->lpCreateParams )->lParam );
115  Info->hSelf = hwnd;
116 
118 
120 
121  return 0;
122 
123  case WM_USER_APPCLOSE:
124  case WM_CLOSE:
125  // The user has to close all open edit dialogs first
126  if(Info->FirstEditGlyphWnd)
127  {
128  PWSTR pszMessage;
129 
130  AllocAndLoadString(&pszMessage, IDS_CLOSEEDIT);
132  HeapFree(hProcessHeap, 0, pszMessage);
133 
134  return 0;
135  }
136 
137  // Prompt if the current file has been modified
138  if(Info->OpenInfo->bModified)
139  {
140  INT nMsgBoxResult;
141  PWSTR pszPrompt;
142  WCHAR szFile[MAX_PATH];
143 
144  GetWindowTextW(hwnd, szFile, MAX_PATH);
145  LoadAndFormatString(IDS_SAVEPROMPT, &pszPrompt, szFile);
146 
147  nMsgBoxResult = MessageBoxW(hwnd, pszPrompt, szAppName, MB_YESNOCANCEL | MB_ICONQUESTION);
148  LocalFree(pszPrompt);
149 
150  switch(nMsgBoxResult)
151  {
152  case IDYES:
153  DoFileSave(Info->MainWndInfo, FALSE);
154  break;
155 
156  case IDCANCEL:
157  // 0 = Stop the process of closing the windows (same value for both WM_CLOSE and WM_USER_APPCLOSE)
158  return 0;
159 
160  // IDNO is handled automatically
161  }
162  }
163 
164  // If there is another child, it will undo the following actions through its WM_CHILDACTIVATE handler.
165  // Otherwise CurrentFontWnd will stay NULL, so the main window knows that no more childs are opened.
166  Info->MainWndInfo->CurrentFontWnd = NULL;
167  SetToolbarFileButtonState(Info->MainWndInfo, FALSE);
168  SetPasteButtonState(Info->MainWndInfo);
169 
170  if(uMsg == WM_USER_APPCLOSE)
171  {
172  // First do the tasks we would do for a normal WM_CLOSE message, then return the value for WM_USER_APPCLOSE
173  // Anything other than 0 indicates that the application shall continue closing the windows
175  return 1;
176  }
177  break;
178 
179  case WM_DESTROY:
180  // Remove the window from the linked list
181  if(Info->PrevFontWnd)
182  Info->PrevFontWnd->NextFontWnd = Info->NextFontWnd;
183  else
184  Info->MainWndInfo->FirstFontWnd = Info->NextFontWnd;
185 
186  if(Info->NextFontWnd)
187  Info->NextFontWnd->PrevFontWnd = Info->PrevFontWnd;
188  else
189  Info->MainWndInfo->LastFontWnd = Info->PrevFontWnd;
190 
191  // Free memory
192  if(Info->Font)
193  HeapFree(hProcessHeap, 0, Info->Font);
194 
195  if(Info->OpenInfo->pszFileName)
196  HeapFree(hProcessHeap, 0, Info->OpenInfo->pszFileName);
197 
198  HeapFree(hProcessHeap, 0, Info->OpenInfo);
200 
202  return 0;
203 
204  case WM_SETFOCUS:
205  // Set the keyboard focus to the FontBoxes window every time the Font window gets the focus
206  SetFocus(Info->hFontBoxesWnd);
207  break;
208 
209  case WM_SIZE:
210  {
211  INT nHeight = HIWORD(lParam);
212  INT nWidth = LOWORD(lParam);
213  POINT pt;
214  RECT WndRect;
215 
216  // This ugly workaround is necessary for not setting either the Height or the Width of the window with SetWindowPos
217  GetWindowRect(Info->hFontBoxesWnd, &WndRect);
218  pt.x = WndRect.left;
219  pt.y = WndRect.top;
221 
222  if(nHeight < FONT_BOXES_WND_HEIGHT)
223  {
224  SCROLLINFO si;
225 
226  // Set the vertical scroll bar
227  si.cbSize = sizeof(si);
228  si.fMask = SIF_RANGE | SIF_PAGE;
229  si.nMin = 0;
231  si.nPage = nHeight;
232  SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
233  }
234  else
235  {
237 
238  // Store the new y coordinate in pt.y as well (needed for the SetWindowPos call for setting a new x coordinate)
239  pt.y = nHeight / 2 - FONT_BOXES_WND_HEIGHT / 2;
240  SetWindowPos(Info->hFontBoxesWnd,
241  NULL,
242  pt.x,
243  pt.y,
244  0,
245  0,
247  }
248 
249  if(nWidth < FONT_BOXES_WND_WIDTH)
250  {
251  SCROLLINFO si;
252 
253  // Set the horizontal scroll bar
254  si.cbSize = sizeof(si);
255  si.fMask = SIF_RANGE | SIF_PAGE;
256  si.nMin = 0;
258  si.nPage = nWidth;
259  SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
260  }
261  else
262  {
264 
265  SetWindowPos(Info->hFontBoxesWnd,
266  NULL,
267  nWidth / 2 - FONT_BOXES_WND_WIDTH / 2,
268  pt.y,
269  0,
270  0,
272  }
273 
274  // We have to call DefMDIChildProcW here as well, otherwise we won't get the Minimize/Maximize/Close buttons for a maximized MDI child.
275  break;
276  }
277 
278  case WM_HSCROLL:
279  case WM_VSCROLL:
280  {
281  INT nBar;
282  INT nOrgPos;
283  SCROLLINFO si;
284 
285  if(uMsg == WM_HSCROLL)
286  nBar = SB_HORZ;
287  else
288  nBar = SB_VERT;
289 
290  si.cbSize = sizeof(si);
291  si.fMask = SIF_ALL;
292  GetScrollInfo(hwnd, nBar, &si);
293 
294  nOrgPos = si.nPos;
295 
296  switch( LOWORD(wParam) )
297  {
298  // Constant is the same as SB_LEFT for WM_HSCROLL
299  case SB_TOP:
300  si.nPos = si.nMin;
301  break;
302 
303  // Constant is the same as SB_RIGHT for WM_HSCROLL
304  case SB_BOTTOM:
305  si.nPos = si.nMax;
306  break;
307 
308  // Constant is the same as SB_LINELEFT for WM_HSCROLL
309  case SB_LINEUP:
310  si.nPos -= 20;
311  break;
312 
313  // Constant is the same as SB_LINERIGHT for WM_HSCROLL
314  case SB_LINEDOWN:
315  si.nPos += 20;
316  break;
317 
318  // Constant is the same as SB_PAGELEFT for WM_HSCROLL
319  case SB_PAGEUP:
320  si.nPos -= si.nPage;
321  break;
322 
323  // Constant is the same as SB_PAGERIGHT for WM_HSCROLL
324  case SB_PAGEDOWN:
325  si.nPos += si.nPage;
326  break;
327 
328  case SB_THUMBTRACK:
329  si.nPos = si.nTrackPos;
330  break;
331  }
332 
333  si.fMask = SIF_POS;
334  SetScrollInfo(hwnd, nBar, &si, TRUE);
335  GetScrollInfo(hwnd, nBar, &si);
336 
337  if(si.nPos != nOrgPos)
338  {
339  // This ugly workaround is necessary for not setting the x coordinate
340  POINT pt;
341  RECT WndRect;
342 
343  GetWindowRect(Info->hFontBoxesWnd, &WndRect);
344  pt.x = WndRect.left;
345  pt.y = WndRect.top;
347 
348  if(uMsg == WM_HSCROLL)
349  SetWindowPos(Info->hFontBoxesWnd, NULL, -si.nPos, pt.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
350  else
351  SetWindowPos(Info->hFontBoxesWnd, NULL, pt.x, -si.nPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
352  }
353 
354  return 0;
355  }
356  }
357  }
358 
359  return DefMDIChildProcW(hwnd, uMsg, wParam, lParam);
360 }
361 
362 BOOL
364 {
365  HWND hFontWnd;
367 
369 
370  if(Info)
371  {
372  Info->MainWndInfo = MainWndInfo;
373  Info->OpenInfo = OpenInfo;
374 
375  if( InitFont(Info) )
376  {
377  PWSTR pszWindowTitle;
378 
379  if(OpenInfo->pszFileName)
380  pszWindowTitle = wcsrchr(OpenInfo->pszFileName, '\\') + 1;
381  else
382  LoadAndFormatString(IDS_DOCNAME, &pszWindowTitle, ++MainWndInfo->uDocumentCounter);
383 
384  hFontWnd = CreateMDIWindowW( szFontWndClass,
385  pszWindowTitle,
386  0,
391  MainWndInfo->hMdiClient,
392  hInstance,
393  (LPARAM)Info );
394 
395  if(!OpenInfo->pszFileName)
396  LocalFree(pszWindowTitle);
397 
398  if(hFontWnd)
399  {
400  // Add the new window to the linked list
401  Info->PrevFontWnd = Info->MainWndInfo->LastFontWnd;
402 
403  if(Info->MainWndInfo->LastFontWnd)
404  Info->MainWndInfo->LastFontWnd->NextFontWnd = Info;
405  else
406  Info->MainWndInfo->FirstFontWnd = Info;
407 
408  Info->MainWndInfo->LastFontWnd = Info;
409 
410  return TRUE;
411  }
412  }
413 
415  }
416 
417  return FALSE;
418 }
419 
420 BOOL
422 {
423  WNDCLASSW wc = {0,};
424 
426  wc.hInstance = hInstance;
427  wc.hCursor = LoadCursor( NULL, IDC_ARROW );
429  wc.hbrBackground = (HBRUSH)( COLOR_BTNFACE + 1 );
431 
432  return RegisterClassW(&wc) != 0;
433 }
434 
435 VOID
437 {
439 }
#define WM_USER_APPCLOSE
Definition: precomp.h:115
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define SB_PAGEDOWN
Definition: winuser.h:569
#define IN
Definition: typedefs.h:38
VOID SetPasteButtonState(IN PMAIN_WND_INFO Info)
Definition: mainwnd.c:389
#define SB_PAGEUP
Definition: winuser.h:568
#define TRUE
Definition: types.h:120
HWND WINAPI CreateMDIWindowW(_In_ LPCWSTR, _In_ LPCWSTR, _In_ DWORD, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HWND, _In_opt_ HINSTANCE, _In_ LPARAM)
#define CloseHandle
Definition: compat.h:398
#define IDS_READERROR
Definition: resource.h:10
#define SIF_RANGE
Definition: winuser.h:1221
#define IDYES
Definition: winuser.h:829
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define FONT_BOXES_WND_HEIGHT
Definition: precomp.h:107
VOID UnInitFontWndClass(VOID)
Definition: fontwnd.c:436
#define SB_VERT
Definition: winuser.h:553
#define pt(x, y)
Definition: drawing.c:79
uint16_t * PWSTR
Definition: typedefs.h:54
#define SB_HORZ
Definition: winuser.h:552
#define CALLBACK
Definition: compat.h:27
BOOL WINAPI ShowScrollBar(_In_ HWND, _In_ int, _In_ BOOL)
LONG top
Definition: windef.h:292
LRESULT WINAPI DefMDIChildProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IDS_SAVEPROMPT
Definition: resource.h:67
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
#define IDS_CLOSEEDIT
Definition: resource.h:69
HWND WINAPI SetFocus(_In_opt_ HWND)
UINT_PTR WPARAM
Definition: windef.h:207
BOOL CreateFontWindow(IN PMAIN_WND_INFO MainWndInfo, IN PFONT_OPEN_INFO OpenInfo)
Definition: fontwnd.c:363
#define GetWindowLongPtrW
Definition: winuser.h:4730
LONG left
Definition: windef.h:291
#define SWP_NOZORDER
Definition: winuser.h:1232
#define IDI_DOC
Definition: resource.h:15
static INT AllocAndLoadString(OUT LPTSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID)
Definition: misc.c:60
int32_t INT
Definition: typedefs.h:56
#define SIF_PAGE
Definition: winuser.h:1219
WPARAM wParam
Definition: combotst.c:138
struct TraceInfo Info
#define FILE_SHARE_READ
Definition: compat.h:125
#define MB_ICONEXCLAMATION
Definition: winuser.h:779
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
HINSTANCE hInstance
Definition: charmap.c:20
Definition: Header.h:8
#define WM_CHILDACTIVATE
Definition: winuser.h:1620
unsigned int BOOL
Definition: ntddk_ex.h:94
WNDPROC lpfnWndProc
Definition: winuser.h:3151
#define CW_USEDEFAULT
Definition: winuser.h:225
#define GWLP_USERDATA
Definition: treelist.c:63
smooth NULL
Definition: ftsmooth.c:416
#define MB_ICONQUESTION
Definition: winuser.h:783
#define MB_YESNOCANCEL
Definition: winuser.h:812
LPCWSTR lpszClassName
Definition: winuser.h:3159
LONG_PTR LPARAM
Definition: windef.h:208
struct _BITMAP_FONT * PBITMAP_FONT
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
DWORD LoadAndFormatString(IN HINSTANCE hInstance, IN UINT uID, OUT LPTSTR *lpTarget,...)
Definition: misc.c:86
#define OPEN_EXISTING
Definition: compat.h:426
#define PSF1_MAGIC0
Definition: psf.h:11
#define IDS_OPENERROR
Definition: resource.h:61
#define WM_DESTROY
Definition: winuser.h:1591
static const WCHAR szFontWndClass[]
Definition: fontwnd.c:10
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SB_THUMBTRACK
Definition: winuser.h:573
#define WM_SIZE
Definition: winuser.h:1593
#define PSF1_MAGIC1
Definition: psf.h:12
#define WM_CLOSE
Definition: winuser.h:1603
#define MAX_PATH
Definition: compat.h:26
VOID LocalizedError(IN UINT uID,...)
Definition: misc.c:103
unsigned long DWORD
Definition: ntddk_ex.h:95
HICON hIcon
Definition: winuser.h:3155
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
VOID CreateFontBoxesWindow(IN PFONT_WND_INFO FontWndInfo)
Definition: fontboxeswnd.c:231
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define IDS_DOCNAME
Definition: resource.h:66
static const WCHAR L[]
Definition: oid.c:1250
#define COLOR_BTNFACE
Definition: winuser.h:918
#define FONT_WND_MIN_HEIGHT
Definition: precomp.h:109
#define FONT_WND_MIN_WIDTH
Definition: precomp.h:108
#define IDS_UNSUPPORTEDFORMAT
Definition: resource.h:64
VOID DoFileSave(IN PMAIN_WND_INFO Info, IN BOOL bSaveAs)
Definition: mainwnd.c:289
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
#define LoadCursor
Definition: winuser.h:5713
#define SIF_POS
Definition: winuser.h:1220
TCHAR szAppName[128]
Definition: solitaire.cpp:16
#define SWP_NOSIZE
Definition: winuser.h:1230
HCURSOR hCursor
Definition: winuser.h:3156
#define SB_TOP
Definition: winuser.h:578
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1408
struct _FONT_WND_INFO * PFONT_WND_INFO
Definition: precomp.h:36
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
HBRUSH hbrBackground
Definition: winuser.h:3157
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define SB_LINEDOWN
Definition: winuser.h:565
#define WM_HSCROLL
Definition: winuser.h:1725
#define SB_LINEUP
Definition: winuser.h:564
#define SB_BOTTOM
Definition: winuser.h:577
#define MB_OK
Definition: winuser.h:784
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define CreateFileW
Definition: compat.h:400
#define IDS_UNSUPPORTEDPSF
Definition: resource.h:65
HINSTANCE hInstance
Definition: winuser.h:3154
#define IDC_ARROW
Definition: winuser.h:682
BOOL InitFontWndClass(VOID)
Definition: fontwnd.c:421
#define WM_CREATE
Definition: winuser.h:1590
#define FONT_BOXES_WND_WIDTH
Definition: precomp.h:106
static LRESULT CALLBACK FontWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: fontwnd.c:97
#define HIWORD(l)
Definition: typedefs.h:246
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
VOID SetToolbarFileButtonState(IN PMAIN_WND_INFO Info, BOOL bEnabled)
Definition: mainwnd.c:92
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
static BOOL InitFont(IN PFONT_WND_INFO Info)
Definition: fontwnd.c:13
#define SetWindowLongPtrW
Definition: winuser.h:5247
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define WM_SETFOCUS
Definition: winuser.h:1595
#define IDCANCEL
Definition: winuser.h:825
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
LONG_PTR LRESULT
Definition: windef.h:209
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define HeapFree(x, y, z)
Definition: compat.h:394
#define WM_VSCROLL
Definition: winuser.h:1726
#define SIF_ALL
Definition: winuser.h:1218
HANDLE hProcessHeap
Definition: kbswitch.c:25