1 /*
2  * PROJECT:    PAINT for ReactOS
3  * LICENSE:    LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE:    Window procedures of the dialog windows plus launching functions
5  * COPYRIGHT:  Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
6  */
7 
8 #include "precomp.h"
9 #include "dialogs.h"
10 
11 #include <winnls.h>
12 
13 CMirrorRotateDialog mirrorRotateDialog;
14 CAttributesDialog attributesDialog;
15 CStretchSkewDialog stretchSkewDialog;
16 CFontsDialog fontsDialog;
17 
18 /* FUNCTIONS ********************************************************/
19 
ShowError(INT stringID,...)20 void ShowError(INT stringID, ...)
21 {
22     va_list va;
23     va_start(va, stringID);
24 
25     CStringW strFormat, strText;
26     strFormat.LoadString(stringID);
27     strText.FormatV(strFormat, va);
28 
29     CStringW strProgramName;
30     strProgramName.LoadString(IDS_PROGRAMNAME);
31 
32     mainWindow.MessageBox(strText, strProgramName, MB_ICONERROR);
33     va_end(va);
34 }
35 
OnInitDialog(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)36 LRESULT CMirrorRotateDialog::OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
37 {
38     CheckDlgButton(IDD_MIRRORROTATERB1, BST_CHECKED);
39     CheckDlgButton(IDD_MIRRORROTATERB4, BST_CHECKED);
40     return TRUE;
41 }
42 
OnClose(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)43 LRESULT CMirrorRotateDialog::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
44 {
45     EndDialog(0);
46     return 0;
47 }
48 
OnOk(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)49 LRESULT CMirrorRotateDialog::OnOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
50 {
51     if (IsDlgButtonChecked(IDD_MIRRORROTATERB1))
52         EndDialog(1);
53     else if (IsDlgButtonChecked(IDD_MIRRORROTATERB2))
54         EndDialog(2);
55     else if (IsDlgButtonChecked(IDD_MIRRORROTATERB4))
56         EndDialog(3);
57     else if (IsDlgButtonChecked(IDD_MIRRORROTATERB5))
58         EndDialog(4);
59     else if (IsDlgButtonChecked(IDD_MIRRORROTATERB6))
60         EndDialog(5);
61     return 0;
62 }
63 
OnCancel(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)64 LRESULT CMirrorRotateDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
65 {
66     EndDialog(0);
67     return 0;
68 }
69 
OnRadioButton3(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)70 LRESULT CMirrorRotateDialog::OnRadioButton3(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
71 {
72     if (IsDlgButtonChecked(IDD_MIRRORROTATERB3) != BST_CHECKED)
73         return 0;
74 
75     ::EnableWindow(GetDlgItem(IDD_MIRRORROTATERB4), TRUE);
76     ::EnableWindow(GetDlgItem(IDD_MIRRORROTATERB5), TRUE);
77     ::EnableWindow(GetDlgItem(IDD_MIRRORROTATERB6), TRUE);
78     return 0;
79 }
80 
OnRadioButton12(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)81 LRESULT CMirrorRotateDialog::OnRadioButton12(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
82 {
83     if (IsDlgButtonChecked(IDD_MIRRORROTATERB1) != BST_CHECKED &&
84         IsDlgButtonChecked(IDD_MIRRORROTATERB2) != BST_CHECKED)
85     {
86         return 0;
87     }
88 
89     ::EnableWindow(GetDlgItem(IDD_MIRRORROTATERB4), FALSE);
90     ::EnableWindow(GetDlgItem(IDD_MIRRORROTATERB5), FALSE);
91     ::EnableWindow(GetDlgItem(IDD_MIRRORROTATERB6), FALSE);
92     return 0;
93 }
94 
OnInitDialog(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)95 LRESULT CAttributesDialog::OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
96 {
97     newWidth = imageModel.GetWidth();
98     newHeight = imageModel.GetHeight();
99 
100     CheckDlgButton(IDD_ATTRIBUTESRB3, BST_CHECKED);
101     SetDlgItemInt(IDD_ATTRIBUTESEDIT1, newWidth, FALSE);
102     SetDlgItemInt(IDD_ATTRIBUTESEDIT2, newHeight, FALSE);
103 
104     if (imageModel.IsBlackAndWhite())
105         CheckRadioButton(IDD_ATTRIBUTESRB4, IDD_ATTRIBUTESRB5, IDD_ATTRIBUTESRB4);
106     else
107         CheckRadioButton(IDD_ATTRIBUTESRB4, IDD_ATTRIBUTESRB5, IDD_ATTRIBUTESRB5);
108 
109     if (g_isAFile)
110     {
111         WCHAR date[100], temp[100];
112         GetDateFormatW(LOCALE_USER_DEFAULT, 0, &g_fileTime, NULL, date, _countof(date));
113         GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &g_fileTime, NULL, temp, _countof(temp));
114         StringCchCatW(date, _countof(date), L" ");
115         StringCchCatW(date, _countof(date), temp);
116         CStringW strSize;
117         strSize.Format(IDS_FILESIZE, g_fileSize);
118         SetDlgItemText(IDD_ATTRIBUTESTEXT6, date);
119         SetDlgItemText(IDD_ATTRIBUTESTEXT7, strSize);
120     }
121 
122     CStringW strUnit;
123     GetDlgItemText(IDD_ATTRIBUTESTEXT8, strUnit);
124 
125     CStringW strRes;
126     if (strUnit == L"dpi")
127         strRes.Format(IDS_PRINTRES, ROUND(g_xDpi), ROUND(g_yDpi));
128     else
129         strRes.Format(IDS_PRINTRES, ROUND(PpcmFromDpi(g_xDpi)), ROUND(PpcmFromDpi(g_yDpi)));
130 
131     SetDlgItemText(IDD_ATTRIBUTESTEXT8, strRes);
132     return TRUE;
133 }
134 
OnClose(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)135 LRESULT CAttributesDialog::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
136 {
137     EndDialog(0);
138     return 0;
139 }
140 
OnOk(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)141 LRESULT CAttributesDialog::OnOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
142 {
143     m_bBlackAndWhite = (IsDlgButtonChecked(IDD_ATTRIBUTESRB4) == BST_CHECKED);
144     EndDialog(1);
145     return 0;
146 }
147 
OnCancel(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)148 LRESULT CAttributesDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
149 {
150     EndDialog(0);
151     return 0;
152 }
153 
OnDefault(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)154 LRESULT CAttributesDialog::OnDefault(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
155 {
156     newWidth = imageModel.GetWidth();
157     newHeight = imageModel.GetHeight();
158     CheckDlgButton(IDD_ATTRIBUTESRB3, BST_CHECKED);
159     CheckDlgButton(IDD_ATTRIBUTESRB5, BST_CHECKED);
160     SetDlgItemInt(IDD_ATTRIBUTESEDIT1, newWidth, FALSE);
161     SetDlgItemInt(IDD_ATTRIBUTESEDIT2, newHeight, FALSE);
162     return 0;
163 }
164 
OnRadioButton1(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)165 LRESULT CAttributesDialog::OnRadioButton1(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
166 {
167     if (IsDlgButtonChecked(IDD_ATTRIBUTESRB1) != BST_CHECKED)
168         return 0;
169 
170     CStringW strNum;
171     strNum.Format(L"%.3lf", newWidth / g_xDpi);
172     SetDlgItemText(IDD_ATTRIBUTESEDIT1, strNum);
173     strNum.Format(L"%.3lf", newHeight / g_yDpi);
174     SetDlgItemText(IDD_ATTRIBUTESEDIT2, strNum);
175     return 0;
176 }
177 
OnRadioButton2(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)178 LRESULT CAttributesDialog::OnRadioButton2(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
179 {
180     if (IsDlgButtonChecked(IDD_ATTRIBUTESRB2) != BST_CHECKED)
181         return 0;
182 
183     CStringW strNum;
184     strNum.Format(L"%.3lf", newWidth / PpcmFromDpi(g_xDpi));
185     SetDlgItemText(IDD_ATTRIBUTESEDIT1, strNum);
186     strNum.Format(L"%.3lf", newHeight / PpcmFromDpi(g_yDpi));
187     SetDlgItemText(IDD_ATTRIBUTESEDIT2, strNum);
188     return 0;
189 }
190 
OnRadioButton3(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)191 LRESULT CAttributesDialog::OnRadioButton3(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
192 {
193     if (IsDlgButtonChecked(IDD_ATTRIBUTESRB3) != BST_CHECKED)
194         return 0;
195 
196     SetDlgItemInt(IDD_ATTRIBUTESEDIT1, newWidth, FALSE);
197     SetDlgItemInt(IDD_ATTRIBUTESEDIT2, newHeight, FALSE);
198     return 0;
199 }
200 
OnEdit1(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)201 LRESULT CAttributesDialog::OnEdit1(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
202 {
203     if (Edit_GetModify(hWndCtl))
204     {
205         WCHAR tempS[100];
206         if (IsDlgButtonChecked(IDD_ATTRIBUTESRB1))
207         {
208             GetDlgItemText(IDD_ATTRIBUTESEDIT1, tempS, _countof(tempS));
209             newWidth = max(1, (int)(wcstod(tempS, NULL) * g_xDpi));
210         }
211         else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB2))
212         {
213             GetDlgItemText(IDD_ATTRIBUTESEDIT1, tempS, _countof(tempS));
214             newWidth = max(1, (int)(wcstod(tempS, NULL) * PpcmFromDpi(g_xDpi)));
215         }
216         else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB3))
217         {
218             GetDlgItemText(IDD_ATTRIBUTESEDIT1, tempS, _countof(tempS));
219             newWidth = max(1, _wtoi(tempS));
220         }
221         Edit_SetModify(hWndCtl, FALSE);
222     }
223     return 0;
224 }
225 
OnEdit2(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)226 LRESULT CAttributesDialog::OnEdit2(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
227 {
228     if (Edit_GetModify(hWndCtl))
229     {
230         WCHAR tempS[100];
231         if (IsDlgButtonChecked(IDD_ATTRIBUTESRB1))
232         {
233             GetDlgItemText(IDD_ATTRIBUTESEDIT2, tempS, _countof(tempS));
234             newHeight = max(1, (int)(wcstod(tempS, NULL) * g_yDpi));
235         }
236         else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB2))
237         {
238             GetDlgItemText(IDD_ATTRIBUTESEDIT2, tempS, _countof(tempS));
239             newHeight = max(1, (int)(wcstod(tempS, NULL) * PpcmFromDpi(g_yDpi)));
240         }
241         else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB3))
242         {
243             GetDlgItemText(IDD_ATTRIBUTESEDIT2, tempS, _countof(tempS));
244             newHeight = max(1, _wtoi(tempS));
245         }
246         Edit_SetModify(hWndCtl, FALSE);
247     }
248     return 0;
249 }
250 
251 
252 
OnInitDialog(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)253 LRESULT CStretchSkewDialog::OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
254 {
255     SetDlgItemInt(IDD_STRETCHSKEWEDITHSTRETCH, 100, FALSE);
256     SetDlgItemInt(IDD_STRETCHSKEWEDITVSTRETCH, 100, FALSE);
257     SetDlgItemInt(IDD_STRETCHSKEWEDITHSKEW, 0, FALSE);
258     SetDlgItemInt(IDD_STRETCHSKEWEDITVSKEW, 0, FALSE);
259     return TRUE;
260 }
261 
OnClose(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)262 LRESULT CStretchSkewDialog::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
263 {
264     EndDialog(0);
265     return 0;
266 }
267 
OnOk(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)268 LRESULT CStretchSkewDialog::OnOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
269 {
270     CStringW strrcIntNumbers, strrcPercentage, strrcAngle;
271     BOOL tr1, tr2, tr3, tr4;
272 
273     strrcIntNumbers.LoadString(g_hinstExe, IDS_INTNUMBERS);
274     strrcPercentage.LoadString(g_hinstExe, IDS_PERCENTAGE);
275     strrcAngle.LoadString(g_hinstExe, IDS_ANGLE);
276 
277     percentage.x = GetDlgItemInt(IDD_STRETCHSKEWEDITHSTRETCH, &tr1, FALSE);
278     percentage.y = GetDlgItemInt(IDD_STRETCHSKEWEDITVSTRETCH, &tr2, FALSE);
279     angle.x = GetDlgItemInt(IDD_STRETCHSKEWEDITHSKEW, &tr3, TRUE);
280     angle.y = GetDlgItemInt(IDD_STRETCHSKEWEDITVSKEW, &tr4, TRUE);
281 
282     if (!(tr1 && tr2 && tr3 && tr4))
283         MessageBox(strrcIntNumbers, NULL, MB_ICONEXCLAMATION);
284     else if (percentage.x < 1 || percentage.x > 500 || percentage.y < 1 || percentage.y > 500)
285         MessageBox(strrcPercentage, NULL, MB_ICONEXCLAMATION);
286     else if (angle.x < -89 || angle.x > 89 || angle.y < -89 || angle.y > 89)
287         MessageBox(strrcAngle, NULL, MB_ICONEXCLAMATION);
288     else
289         EndDialog(1);
290     return 0;
291 }
292 
OnCancel(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)293 LRESULT CStretchSkewDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
294 {
295     EndDialog(0);
296     return 0;
297 }
298 
299 static INT CALLBACK
EnumFontFamProc(ENUMLOGFONTW * lpelf,NEWTEXTMETRICW * lpntm,INT FontType,LPARAM lParam)300 EnumFontFamProc(ENUMLOGFONTW *lpelf, NEWTEXTMETRICW *lpntm, INT FontType, LPARAM lParam)
301 {
302     CSimpleArray<CStringW>& arrFontNames = *reinterpret_cast<CSimpleArray<CStringW>*>(lParam);
303     LPWSTR name = lpelf->elfLogFont.lfFaceName;
304     if (name[0] == L'@') // Vertical fonts
305         return TRUE;
306 
307     for (INT i = 0; i < arrFontNames.GetSize(); ++i)
308     {
309         if (arrFontNames[i] == name) // Already exists
310             return TRUE;
311     }
312 
313     arrFontNames.Add(name);
314     return TRUE;
315 }
316 
317 // TODO: AutoComplete font names
318 // TODO: Vertical text
CFontsDialog()319 CFontsDialog::CFontsDialog()
320 {
321 }
322 
InitFontNames()323 void CFontsDialog::InitFontNames()
324 {
325     // List the fonts
326     CSimpleArray<CStringW> arrFontNames;
327     HDC hDC = CreateCompatibleDC(NULL);
328     if (hDC)
329     {
330         EnumFontFamiliesW(hDC, NULL, (FONTENUMPROCW)EnumFontFamProc,
331                           reinterpret_cast<LPARAM>(&arrFontNames));
332         ::DeleteDC(hDC);
333     }
334 
335     // Actually add them to the combobox
336     HWND hwndNames = GetDlgItem(IDD_FONTSNAMES);
337     ::SendMessageW(hwndNames, CB_RESETCONTENT, 0, 0);
338     for (INT i = 0; i < arrFontNames.GetSize(); ++i)
339     {
340         ComboBox_AddString(hwndNames, arrFontNames[i]);
341     }
342 
343     ::SetWindowTextW(hwndNames, registrySettings.strFontName);
344 }
345 
InitFontSizes()346 void CFontsDialog::InitFontSizes()
347 {
348     static const INT s_sizes[] =
349     {
350         8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72
351     };
352 
353     HWND hwndSizes = GetDlgItem(IDD_FONTSSIZES);
354     ComboBox_ResetContent(hwndSizes);
355 
356     WCHAR szText[16];
357     for (UINT i = 0; i < _countof(s_sizes); ++i)
358     {
359         StringCchPrintfW(szText, _countof(szText), L"%d", s_sizes[i]);
360         INT iItem = ComboBox_AddString(hwndSizes, szText);
361         if (s_sizes[i] == (INT)registrySettings.PointSize)
362             ComboBox_SetCurSel(hwndSizes, iItem);
363     }
364 
365     if (ComboBox_GetCurSel(hwndSizes) == CB_ERR)
366     {
367         StringCchPrintfW(szText, _countof(szText), L"%d", (INT)registrySettings.PointSize);
368         ::SetWindowTextW(hwndSizes, szText);
369     }
370 }
371 
InitToolbar()372 void CFontsDialog::InitToolbar()
373 {
374     HWND hwndToolbar = GetDlgItem(IDD_FONTSTOOLBAR);
375     ::SendMessageW(hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
376     ::SendMessageW(hwndToolbar, TB_SETBITMAPSIZE, 0, MAKELPARAM(16, 16));
377     ::SendMessageW(hwndToolbar, TB_SETBUTTONWIDTH, 0, MAKELPARAM(20, 20));
378 
379     TBADDBITMAP AddBitmap;
380     AddBitmap.hInst = g_hinstExe;
381     AddBitmap.nID = IDB_FONTSTOOLBAR;
382     ::SendMessageW(hwndToolbar, TB_ADDBITMAP, 4, (LPARAM)&AddBitmap);
383 
384     HIMAGELIST himl = ImageList_LoadImage(g_hinstExe, MAKEINTRESOURCEW(IDB_FONTSTOOLBAR),
385                                           16, 8, RGB(255, 0, 255), IMAGE_BITMAP,
386                                           LR_CREATEDIBSECTION);
387     ::SendMessageW(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl);
388 
389     TBBUTTON buttons[] =
390     {
391         { 0, IDM_BOLD, TBSTATE_ENABLED, TBSTYLE_CHECK },
392         { 1, IDM_ITALIC, TBSTATE_ENABLED, TBSTYLE_CHECK },
393         { 2, IDM_UNDERLINE, TBSTATE_ENABLED, TBSTYLE_CHECK },
394         { 3, IDM_VERTICAL, 0, TBSTYLE_CHECK }, // TODO:
395     };
396     ::SendMessageW(hwndToolbar, TB_ADDBUTTONS, _countof(buttons), (LPARAM)&buttons);
397 
398     ::SendMessageW(hwndToolbar, TB_CHECKBUTTON, IDM_BOLD, registrySettings.Bold);
399     ::SendMessageW(hwndToolbar, TB_CHECKBUTTON, IDM_ITALIC, registrySettings.Italic);
400     ::SendMessageW(hwndToolbar, TB_CHECKBUTTON, IDM_UNDERLINE, registrySettings.Underline);
401 }
402 
OnInitDialog(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)403 LRESULT CFontsDialog::OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
404 {
405     // TODO: Tooltips
406     InitFontNames();
407     InitFontSizes();
408     InitToolbar();
409 
410     if (registrySettings.FontsPositionX != 0 || registrySettings.FontsPositionY != 0)
411     {
412         SetWindowPos(NULL,
413                      registrySettings.FontsPositionX, registrySettings.FontsPositionY,
414                      0, 0,
415                      SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
416         SendMessage(DM_REPOSITION, 0, 0);
417     }
418 
419     if (!registrySettings.ShowTextTool)
420         ShowWindow(SW_HIDE);
421 
422     return TRUE;
423 }
424 
OnClose(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)425 LRESULT CFontsDialog::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
426 {
427     ShowWindow(SW_HIDE); // Just hide. Recycle for optimization
428     return 0;
429 }
430 
OnFontName(UINT codeNotify)431 void CFontsDialog::OnFontName(UINT codeNotify)
432 {
433     HWND hwndNames = GetDlgItem(IDD_FONTSNAMES);
434     INT iItem = CB_ERR;
435     UINT cch;
436     WCHAR szText[LF_FACESIZE];
437 
438     switch (codeNotify)
439     {
440         case CBN_SELCHANGE:
441             iItem = ComboBox_GetCurSel(hwndNames);
442             cch = ComboBox_GetLBTextLen(hwndNames, iItem);
443             if (iItem != CB_ERR && 0 < cch && cch < _countof(szText))
444                 ComboBox_GetLBText(hwndNames, iItem, szText);
445             break;
446 
447         case CBN_EDITCHANGE:
448             GetDlgItemText(IDD_FONTSNAMES, szText, _countof(szText));
449             iItem = ComboBox_FindStringExact(hwndNames, -1, szText);
450             break;
451     }
452 
453     if (iItem != CB_ERR && registrySettings.strFontName.CompareNoCase(szText) != 0)
454     {
455         registrySettings.strFontName = szText;
456         toolsModel.NotifyToolChanged();
457     }
458 }
459 
OnFontSize(UINT codeNotify)460 void CFontsDialog::OnFontSize(UINT codeNotify)
461 {
462     HWND hwndSizes = GetDlgItem(IDD_FONTSSIZES);
463     WCHAR szText[8];
464     INT iItem, PointSize = 0;
465     UINT cch;
466 
467     switch (codeNotify)
468     {
469         case CBN_SELCHANGE:
470             iItem = ComboBox_GetCurSel(hwndSizes);
471             cch = ComboBox_GetLBTextLen(hwndSizes, iItem);
472             if (iItem != CB_ERR && 0 < cch && cch < _countof(szText))
473             {
474                 ComboBox_GetLBText(hwndSizes, iItem, szText);
475                 PointSize = _wtoi(szText);
476             }
477             break;
478 
479         case CBN_EDITCHANGE:
480             ::GetWindowTextW(hwndSizes, szText, _countof(szText));
481             PointSize = _wtoi(szText);
482             break;
483     }
484 
485     if (PointSize > 0)
486     {
487         registrySettings.PointSize = PointSize;
488         toolsModel.NotifyToolChanged();
489     }
490 }
491 
OnCommand(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)492 LRESULT CFontsDialog::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
493 {
494     UINT id = LOWORD(wParam);
495     UINT codeNotify = HIWORD(wParam);
496     HWND hwndToolbar = GetDlgItem(IDD_FONTSTOOLBAR);
497     BOOL bChecked = (BOOL)::SendMessageW(hwndToolbar, TB_ISBUTTONCHECKED, id, 0);
498 
499     switch (id)
500     {
501         case IDCANCEL:
502             ShowWindow(SW_HIDE);
503             registrySettings.ShowTextTool = FALSE;
504             break;
505 
506         case IDD_FONTSNAMES:
507             OnFontName(codeNotify);
508             break;
509 
510         case IDD_FONTSSIZES:
511             OnFontSize(codeNotify);
512             break;
513 
514         case IDM_BOLD:
515             registrySettings.Bold = bChecked;
516             toolsModel.NotifyToolChanged();
517             break;
518 
519         case IDM_ITALIC:
520             registrySettings.Italic = bChecked;
521             toolsModel.NotifyToolChanged();
522             break;
523 
524         case IDM_UNDERLINE:
525             registrySettings.Underline = bChecked;
526             toolsModel.NotifyToolChanged();
527             break;
528 
529         case IDM_VERTICAL:
530             // TODO:
531             break;
532     }
533     return 0;
534 }
535 
OnNotify(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)536 LRESULT CFontsDialog::OnNotify(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
537 {
538     NMHDR *pnmhdr = reinterpret_cast<NMHDR *>(lParam);
539     if (pnmhdr->code == TTN_NEEDTEXT)
540     {
541         LPTOOLTIPTEXTW pToolTip = reinterpret_cast<LPTOOLTIPTEXTW>(lParam);
542         pToolTip->hinst = g_hinstExe;
543         switch (pnmhdr->idFrom)
544         {
545             case IDM_BOLD:      pToolTip->lpszText = MAKEINTRESOURCEW(IDS_BOLD); break;
546             case IDM_ITALIC:    pToolTip->lpszText = MAKEINTRESOURCEW(IDS_ITALIC); break;
547             case IDM_UNDERLINE: pToolTip->lpszText = MAKEINTRESOURCEW(IDS_UNDERLINE); break;
548             case IDM_VERTICAL:  pToolTip->lpszText = MAKEINTRESOURCEW(IDS_VERTICAL); break;
549 
550             default:
551                 break;
552         }
553     }
554     return 0;
555 }
556 
OnMove(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)557 LRESULT CFontsDialog::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
558 {
559     RECT rc;
560     GetWindowRect(&rc);
561     registrySettings.FontsPositionX = rc.left;
562     registrySettings.FontsPositionY = rc.top;
563     return 0;
564 }
565 
OnToolsModelToolChanged(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)566 LRESULT CFontsDialog::OnToolsModelToolChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
567 {
568     if (wParam != TOOL_TEXT)
569         ShowWindow(SW_HIDE);
570 
571     return 0;
572 }
573 
OnMeasureItem(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)574 LRESULT CFontsDialog::OnMeasureItem(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
575 {
576     if (wParam == IDD_FONTSNAMES)
577     {
578         LPMEASUREITEMSTRUCT pMeasureItem = reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam);
579         RECT rc;
580         ::GetClientRect(GetDlgItem(IDD_FONTSNAMES), &rc);
581         pMeasureItem->itemWidth = rc.right - rc.left;
582         pMeasureItem->itemHeight = GetSystemMetrics(SM_CYVSCROLL);
583         return TRUE;
584     }
585     return 0;
586 }
587 
OnDrawItem(UINT nMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)588 LRESULT CFontsDialog::OnDrawItem(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
589 {
590     // TODO: Owner-draw the font types
591     if (wParam == IDD_FONTSNAMES)
592     {
593         LPDRAWITEMSTRUCT pDrawItem = reinterpret_cast<LPDRAWITEMSTRUCT>(lParam);
594         if (pDrawItem->itemID == (UINT)-1)
595             return TRUE;
596 
597         ::SetBkMode(pDrawItem->hDC, TRANSPARENT);
598 
599         HWND hwndItem = pDrawItem->hwndItem;
600         RECT rcItem = pDrawItem->rcItem;
601         if (pDrawItem->itemState & ODS_SELECTED)
602         {
603             ::FillRect(pDrawItem->hDC, &rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
604             ::SetTextColor(pDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
605         }
606         else
607         {
608             ::FillRect(pDrawItem->hDC, &rcItem, GetSysColorBrush(COLOR_WINDOW));
609             ::SetTextColor(pDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
610         }
611 
612         WCHAR szText[LF_FACESIZE];
613         if ((UINT)ComboBox_GetLBTextLen(hwndItem, pDrawItem->itemID) < _countof(szText))
614         {
615             szText[0] = 0;
616             ComboBox_GetLBText(hwndItem, pDrawItem->itemID, szText);
617 
618             rcItem.left += 24;
619             ::DrawTextW(pDrawItem->hDC, szText, -1, &rcItem, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
620         }
621 
622         if (pDrawItem->itemState & ODS_FOCUS)
623             ::DrawFocusRect(pDrawItem->hDC, &pDrawItem->rcItem);
624 
625         return TRUE;
626     }
627     return 0;
628 }
629