Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1153 lines
36 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. fontdlg.dlg
  5. Abstract:
  6. This module contains the code for console font dialog
  7. Author:
  8. Therese Stowell (thereses) Feb-3-1992 (swiped from Win3.1)
  9. Revision History:
  10. --*/
  11. #include "shellprv.h"
  12. #pragma hdrstop
  13. #include "lnkcon.h"
  14. HBITMAP g_hbmTT = NULL; // handle of TT logo bitmap
  15. BITMAP g_bmTT; // attributes of TT source bitmap
  16. int g_dyFacelistItem = 0;
  17. /* ----- Prototypes ----- */
  18. int FontListCreate(
  19. CONSOLEPROP_DATA * pcpd,
  20. HWND hDlg,
  21. LPTSTR ptszTTFace,
  22. UINT cchTTFace,
  23. BOOL bNewFaceList
  24. );
  25. BOOL ConsolePreviewUpdate(
  26. CONSOLEPROP_DATA * pcpd,
  27. HWND hDlg,
  28. BOOL bLB
  29. );
  30. int SelectCurrentSize(
  31. CONSOLEPROP_DATA * pcpd,
  32. HWND hDlg,
  33. BOOL bLB,
  34. int FontIndex);
  35. BOOL ConsolePreviewInit(
  36. CONSOLEPROP_DATA * pcpd,
  37. HWND hDlg,
  38. BOOL* pfRaster);
  39. VOID ConsoleDrawItemFontList(
  40. CONSOLEPROP_DATA * pcpd,
  41. const LPDRAWITEMSTRUCT lpdis);
  42. /* ----- Globals ----- */
  43. const TCHAR g_szPreviewText[] = \
  44. TEXT("C:\\WINDOWS> dir \n") \
  45. TEXT("SYSTEM <DIR> 10-01-99 5:00a\n") \
  46. TEXT("SYSTEM32 <DIR> 10-01-99 5:00a\n") \
  47. TEXT("README TXT 26926 10-01-99 5:00a\n") \
  48. TEXT("WINDOWS BMP 46080 10-01-99 5:00a\n") \
  49. TEXT("NOTEPAD EXE 337232 10-01-99 5:00a\n") \
  50. TEXT("CLOCK AVI 39594 10-01-99 5:00p\n") \
  51. TEXT("WIN INI 7005 10-01-99 5:00a\n");
  52. // Context-sensitive help ids
  53. const static DWORD rgdwHelpFont[] = {
  54. IDC_CNSL_PREVIEWLABEL, IDH_DOS_FONT_WINDOW_PREVIEW,
  55. IDC_CNSL_PREVIEWWINDOW, IDH_DOS_FONT_WINDOW_PREVIEW,
  56. IDC_CNSL_STATIC, IDH_CONSOLE_FONT_FONT,
  57. IDC_CNSL_FACENAME, IDH_CONSOLE_FONT_FONT,
  58. IDC_CNSL_FONTSIZE, IDH_DOS_FONT_SIZE,
  59. IDC_CNSL_PIXELSLIST, IDH_DOS_FONT_SIZE,
  60. IDC_CNSL_POINTSLIST, IDH_DOS_FONT_SIZE,
  61. IDC_CNSL_BOLDFONT, IDH_CONSOLE_FONT_BOLD_FONTS,
  62. IDC_CNSL_GROUP, IDH_DOS_FONT_FONT_PREVIEW,
  63. IDC_CNSL_STATIC2, IDH_DOS_FONT_FONT_PREVIEW,
  64. IDC_CNSL_STATIC3, IDH_DOS_FONT_FONT_PREVIEW,
  65. IDC_CNSL_STATIC4, IDH_DOS_FONT_FONT_PREVIEW,
  66. IDC_CNSL_FONTWIDTH, IDH_DOS_FONT_FONT_PREVIEW,
  67. IDC_CNSL_FONTHEIGHT, IDH_DOS_FONT_FONT_PREVIEW,
  68. IDC_CNSL_FONTWINDOW, IDH_DOS_FONT_FONT_PREVIEW,
  69. 0, 0
  70. };
  71. // selelct font based on the current code page
  72. BOOL
  73. SelectCurrentFont(
  74. CONSOLEPROP_DATA * pcpd,
  75. HWND hDlg,
  76. int FontIndex
  77. );
  78. // Globals strings loaded from resource
  79. TCHAR tszSelectedFont[CCH_SELECTEDFONT+1];
  80. TCHAR tszRasterFonts[CCH_RASTERFONTS+1];
  81. BOOL
  82. CALLBACK
  83. _FontDlgProc(
  84. HWND hDlg,
  85. UINT wMsg,
  86. WPARAM wParam,
  87. LPARAM lParam
  88. )
  89. /*++
  90. Dialog proc for the font selection dialog box.
  91. Returns the near offset into the far table of LOGFONT structures.
  92. --*/
  93. {
  94. HWND hWndFocus;
  95. HWND hWndList;
  96. int FontIndex;
  97. BOOL bLB;
  98. TEXTMETRIC tm;
  99. HDC hDC;
  100. LINKDATA * pld = (LINKDATA *)GetWindowLongPtr(hDlg, DWLP_USER);
  101. HRESULT hr;
  102. switch (wMsg) {
  103. case WM_INITDIALOG:
  104. pld = (LINKDATA *)((PROPSHEETPAGE *)lParam)->lParam;
  105. SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pld);
  106. pld->cpd.bFontInit = FALSE;
  107. SendDlgItemMessage(hDlg, IDC_CNSL_PREVIEWWINDOW, CM_PREVIEW_INIT, 0, (LPARAM)&pld->cpd );
  108. SendDlgItemMessage(hDlg, IDC_CNSL_PREVIEWWINDOW, CM_PREVIEW_UPDATE, 0, 0 );
  109. /*
  110. * Load the font description strings
  111. */
  112. LoadString(HINST_THISDLL, IDS_CNSL_RASTERFONT,
  113. tszRasterFonts, NELEM(tszRasterFonts));
  114. ASSERT(lstrlen(tszRasterFonts) < CCH_RASTERFONTS);
  115. LoadString(g_hinst, IDS_CNSL_SELECTEDFONT,
  116. tszSelectedFont, NELEM(tszSelectedFont));
  117. ASSERT(lstrlen(tszSelectedFont) < CCH_SELECTEDFONT);
  118. /* Save current font size as dialog window's user data */
  119. if (IsFarEastCP(pld->cpd.uOEMCP))
  120. {
  121. // Assigning different value when we run on FarEast codepage
  122. pld->cpd.FontLong =
  123. MAKELONG(pld->cpd.FontInfo[pld->cpd.CurrentFontIndex].tmCharSet,
  124. pld->cpd.FontInfo[pld->cpd.CurrentFontIndex].Size.Y);
  125. }
  126. else
  127. {
  128. pld->cpd.FontLong =
  129. MAKELONG(pld->cpd.FontInfo[pld->cpd.CurrentFontIndex].Size.X,
  130. pld->cpd.FontInfo[pld->cpd.CurrentFontIndex].Size.Y);
  131. }
  132. /* Create the list of suitable fonts */
  133. pld->cpd.gbEnumerateFaces = TRUE;
  134. bLB = !TM_IS_TT_FONT(pld->cpd.lpConsole->uFontFamily);
  135. pld->cpd.gbBold = IS_BOLD(pld->cpd.lpConsole->uFontWeight);
  136. CheckDlgButton(hDlg, IDC_CNSL_BOLDFONT, pld->cpd.gbBold);
  137. FontListCreate(&pld->cpd, hDlg, bLB ? NULL : pld->cpd.lpFaceName, ARRAYSIZE(pld->cpd.lpFaceName), TRUE);
  138. /* Initialize the preview window - selects current face & size too */
  139. if (ConsolePreviewInit(&pld->cpd, hDlg, &bLB))
  140. {
  141. ConsolePreviewUpdate(&pld->cpd, hDlg, bLB);
  142. /* Make sure the list box has the focus */
  143. hWndList = GetDlgItem(hDlg, bLB ? IDC_CNSL_PIXELSLIST : IDC_CNSL_POINTSLIST);
  144. SetFocus(hWndList);
  145. pld->cpd.bFontInit = TRUE;
  146. }
  147. else
  148. {
  149. EndDialog(hDlg, IDCANCEL);
  150. }
  151. break;
  152. case WM_FONTCHANGE:
  153. pld->cpd.gbEnumerateFaces = TRUE;
  154. bLB = !TM_IS_TT_FONT(pld->cpd.lpConsole->uFontFamily);
  155. FontListCreate(&pld->cpd, hDlg, NULL, 0, TRUE);
  156. FontIndex = FindCreateFont(&pld->cpd,
  157. pld->cpd.lpConsole->uFontFamily,
  158. pld->cpd.lpFaceName,
  159. pld->cpd.lpConsole->dwFontSize,
  160. pld->cpd.lpConsole->uFontWeight);
  161. SelectCurrentSize(&pld->cpd, hDlg, bLB, FontIndex);
  162. return TRUE;
  163. case WM_PAINT:
  164. // fChangeCodePage can be TRUE only on FE codepage
  165. if (pld->cpd.fChangeCodePage)
  166. {
  167. pld->cpd.fChangeCodePage = FALSE;
  168. /* Create the list of suitable fonts */
  169. bLB = !TM_IS_TT_FONT(pld->cpd.lpConsole->uFontFamily);
  170. FontIndex = FontListCreate(&pld->cpd, hDlg, !bLB ? NULL : pld->cpd.lpFaceName, ARRAYSIZE(pld->cpd.lpFaceName), TRUE);
  171. FontIndex = FontListCreate(&pld->cpd, hDlg, bLB ? NULL : pld->cpd.lpFaceName, ARRAYSIZE(pld->cpd.lpFaceName), TRUE);
  172. pld->cpd.CurrentFontIndex = FontIndex;
  173. FontIndex = SelectCurrentSize(&pld->cpd, hDlg, bLB, FontIndex);
  174. SelectCurrentFont(&pld->cpd, hDlg, FontIndex);
  175. ConsolePreviewUpdate(&pld->cpd, hDlg, bLB);
  176. }
  177. break;
  178. case WM_HELP: /* F1 or title-bar help button */
  179. WinHelp( (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  180. NULL,
  181. HELP_WM_HELP,
  182. (ULONG_PTR) (LPVOID) &rgdwHelpFont[0]
  183. );
  184. break;
  185. case WM_CONTEXTMENU: /* right mouse click */
  186. WinHelp( (HWND) wParam,
  187. NULL,
  188. HELP_CONTEXTMENU,
  189. (ULONG_PTR) (LPTSTR) &rgdwHelpFont[0]
  190. );
  191. break;
  192. case WM_COMMAND:
  193. switch (LOWORD(wParam))
  194. {
  195. case IDC_CNSL_BOLDFONT:
  196. pld->cpd.gbBold = IsDlgButtonChecked(hDlg, IDC_CNSL_BOLDFONT);
  197. pld->cpd.bConDirty = TRUE;
  198. goto RedoFontListAndPreview;
  199. case IDC_CNSL_FACENAME:
  200. switch (HIWORD(wParam))
  201. {
  202. case LBN_SELCHANGE:
  203. RedoFontListAndPreview:
  204. if (pld->cpd.bFontInit)
  205. PropSheet_Changed( GetParent( hDlg ), hDlg );
  206. {
  207. TCHAR atchNewFace[LF_FACESIZE];
  208. LRESULT l;
  209. l = SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETCURSEL, 0, 0L);
  210. bLB = (BOOL) SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETITEMDATA, l, 0L);
  211. if (!bLB) {
  212. UINT cch = (UINT)SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETTEXTLEN, l, 0);
  213. if (cch < ARRAYSIZE(atchNewFace))
  214. {
  215. SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETTEXT, l, (LPARAM)atchNewFace);
  216. }
  217. else
  218. {
  219. atchNewFace[0] = TEXT('\0');
  220. }
  221. }
  222. FontIndex = FontListCreate(&pld->cpd, hDlg, bLB ? NULL : atchNewFace, ARRAYSIZE(atchNewFace), FALSE);
  223. FontIndex = SelectCurrentSize(&pld->cpd, hDlg, bLB, FontIndex);
  224. ConsolePreviewUpdate(&pld->cpd, hDlg, bLB);
  225. pld->cpd.bConDirty = TRUE;
  226. return TRUE;
  227. }
  228. }
  229. break;
  230. case IDC_CNSL_POINTSLIST:
  231. switch (HIWORD(wParam)) {
  232. case CBN_SELCHANGE:
  233. if (pld->cpd.bFontInit)
  234. PropSheet_Changed( GetParent( hDlg ), hDlg );
  235. ConsolePreviewUpdate(&pld->cpd, hDlg, FALSE);
  236. pld->cpd.bConDirty = TRUE;
  237. return TRUE;
  238. case CBN_KILLFOCUS:
  239. if (!pld->cpd.gbPointSizeError) {
  240. hWndFocus = GetFocus();
  241. if (hWndFocus != NULL && IsChild(hDlg, hWndFocus) &&
  242. hWndFocus != GetDlgItem(hDlg, IDCANCEL)) {
  243. ConsolePreviewUpdate(&pld->cpd, hDlg, FALSE);
  244. }
  245. }
  246. return TRUE;
  247. default:
  248. break;
  249. }
  250. break;
  251. case IDC_CNSL_PIXELSLIST:
  252. switch (HIWORD(wParam)) {
  253. case LBN_SELCHANGE:
  254. if (pld->cpd.bFontInit)
  255. PropSheet_Changed( GetParent( hDlg ), hDlg );
  256. ConsolePreviewUpdate(&pld->cpd, hDlg, TRUE);
  257. pld->cpd.bConDirty = TRUE;
  258. return TRUE;
  259. default:
  260. break;
  261. }
  262. break;
  263. default:
  264. break;
  265. }
  266. break;
  267. case WM_NOTIFY:
  268. switch (((LPNMHDR)lParam)->code)
  269. {
  270. case PSN_APPLY:
  271. // Write out the state values and exit.
  272. if (FAILED(SaveLink(pld)))
  273. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  274. break;
  275. case PSN_KILLACTIVE:
  276. //
  277. // If the TT combo box is visible, update selection
  278. //
  279. hWndList = GetDlgItem(hDlg, IDC_CNSL_POINTSLIST);
  280. if (hWndList != NULL && IsWindowVisible(hWndList)) {
  281. if (!ConsolePreviewUpdate(&pld->cpd, hDlg, FALSE)) {
  282. SetDlgMsgResult(hDlg, PSN_KILLACTIVE, TRUE);
  283. return TRUE;
  284. }
  285. SetDlgMsgResult(hDlg, PSN_KILLACTIVE, FALSE);
  286. }
  287. FontIndex = pld->cpd.CurrentFontIndex;
  288. if (pld->cpd.FontInfo[FontIndex].SizeWant.Y == 0) {
  289. // Raster Font, so save actual size
  290. pld->cpd.lpConsole->dwFontSize = pld->cpd.FontInfo[FontIndex].Size;
  291. } else {
  292. // TT Font, so save desired size
  293. pld->cpd.lpConsole->dwFontSize = pld->cpd.FontInfo[FontIndex].SizeWant;
  294. }
  295. pld->cpd.lpConsole->uFontWeight = pld->cpd.FontInfo[FontIndex].Weight;
  296. pld->cpd.lpConsole->uFontFamily = pld->cpd.FontInfo[FontIndex].Family;
  297. hr = StringCchCopy(pld->cpd.lpFaceName, ARRAYSIZE(pld->cpd.lpFaceName), pld->cpd.FontInfo[FontIndex].FaceName);
  298. if (FAILED(hr))
  299. {
  300. pld->cpd.lpFaceName[0] = TEXT('\0');
  301. }
  302. return TRUE;
  303. }
  304. break;
  305. /*
  306. * For WM_MEASUREITEM and WM_DRAWITEM, since there is only one
  307. * owner-draw item (combobox) in the entire dialog box, we don't have
  308. * to do a GetDlgItem to figure out who he is.
  309. */
  310. case WM_MEASUREITEM:
  311. /*
  312. * Load the TrueType logo bitmap
  313. */
  314. if (g_hbmTT == NULL)
  315. {
  316. g_hbmTT = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_TRUETYPE));
  317. if (g_hbmTT)
  318. {
  319. if (!GetObject(g_hbmTT, sizeof(BITMAP), &g_bmTT))
  320. {
  321. DeleteObject(g_hbmTT);
  322. g_hbmTT = NULL;
  323. }
  324. }
  325. }
  326. /*
  327. * Compute the height of face name listbox entries
  328. */
  329. if (g_dyFacelistItem == 0) {
  330. HFONT hFont;
  331. hDC = GetDC(hDlg);
  332. if (hDC)
  333. {
  334. hFont = GetWindowFont(hDlg);
  335. if (hFont) {
  336. hFont = SelectObject(hDC, hFont);
  337. }
  338. GetTextMetrics(hDC, &tm);
  339. if (hFont) {
  340. SelectObject(hDC, hFont);
  341. }
  342. ReleaseDC(hDlg, hDC);
  343. g_dyFacelistItem = max(tm.tmHeight, g_bmTT.bmHeight);
  344. }
  345. else
  346. {
  347. // We just failed GetDC: Low memory - we might look corrupted here, but its
  348. // better than using a null DC or bad textmetrics structure. Prefix 98166
  349. g_dyFacelistItem = g_bmTT.bmHeight;
  350. }
  351. }
  352. ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = g_dyFacelistItem;
  353. return TRUE;
  354. case WM_DRAWITEM:
  355. ConsoleDrawItemFontList(&pld->cpd, (LPDRAWITEMSTRUCT)lParam);
  356. return TRUE;
  357. case WM_DESTROY:
  358. /*
  359. * Delete the TrueType logo bitmap
  360. */
  361. if (g_hbmTT != NULL) {
  362. DeleteObject(g_hbmTT);
  363. g_hbmTT = NULL;
  364. }
  365. return TRUE;
  366. default:
  367. break;
  368. }
  369. return FALSE;
  370. }
  371. int
  372. FontListCreate(
  373. CONSOLEPROP_DATA * pcpd,
  374. HWND hDlg,
  375. LPTSTR ptszTTFace,
  376. UINT cchTTFace,
  377. BOOL bNewFaceList
  378. )
  379. /*++
  380. Initializes the font list by enumerating all fonts and picking the
  381. proper ones for our list.
  382. Returns
  383. FontIndex of selected font (LB_ERR if none)
  384. --*/
  385. {
  386. TCHAR tszText[80];
  387. LONG lListIndex;
  388. ULONG i;
  389. HWND hWndShow; // List or Combo box
  390. HWND hWndHide; // Combo or List box
  391. HWND hWndFaceCombo;
  392. BOOL bLB;
  393. int LastShowX = 0;
  394. int LastShowY = 0;
  395. int nSameSize = 0;
  396. UINT CodePage = pcpd->lpFEConsole->uCodePage;
  397. BOOL fDbcsCharSet = IS_ANY_DBCS_CHARSET( CodePageToCharSet( CodePage ) );
  398. BOOL fFESystem = IsFarEastCP(pcpd->uOEMCP);
  399. BOOL fFindTTFont = FALSE;
  400. LPTSTR ptszAltTTFace = NULL;
  401. DWORD dwExStyle = 0L;
  402. bLB = ((ptszTTFace == NULL) || (ptszTTFace[0] == TEXT('\0')));
  403. if (! bLB) {
  404. if (IsAvailableTTFont(pcpd, ptszTTFace)) {
  405. ptszAltTTFace = GetAltFaceName(pcpd, ptszTTFace);
  406. }
  407. else {
  408. ptszAltTTFace = ptszTTFace;
  409. }
  410. }
  411. /*
  412. * This only enumerates face names if necessary, and
  413. * it only enumerates font sizes if necessary
  414. */
  415. if (STATUS_SUCCESS != EnumerateFonts(pcpd, bLB ? EF_OEMFONT : EF_TTFONT))
  416. {
  417. return LB_ERR;
  418. }
  419. /* init the TTFaceNames */
  420. if (bNewFaceList) {
  421. FACENODE *panFace;
  422. hWndFaceCombo = GetDlgItem(hDlg, IDC_CNSL_FACENAME);
  423. SendMessage(hWndFaceCombo, LB_RESETCONTENT, 0, 0);
  424. lListIndex = (LONG) SendMessage(hWndFaceCombo, LB_ADDSTRING, 0, (LPARAM)tszRasterFonts);
  425. SendMessage(hWndFaceCombo, LB_SETITEMDATA, lListIndex, TRUE);
  426. for (panFace = pcpd->gpFaceNames; panFace; panFace = panFace->pNext) {
  427. if ((panFace->dwFlag & (EF_TTFONT|EF_NEW)) != (EF_TTFONT|EF_NEW)) {
  428. continue;
  429. }
  430. if (!fDbcsCharSet && (panFace->dwFlag & EF_DBCSFONT)) {
  431. continue;
  432. }
  433. if ( ( fDbcsCharSet && IsAvailableTTFontCP(pcpd, panFace->atch, CodePage)) ||
  434. ( !fDbcsCharSet && IsAvailableTTFontCP(pcpd, panFace->atch, 0)))
  435. {
  436. if ( !bLB &&
  437. (lstrcmp(ptszTTFace, panFace->atch) == 0 ||
  438. lstrcmp(ptszAltTTFace, panFace->atch) == 0)
  439. )
  440. fFindTTFont = TRUE;
  441. lListIndex = (LONG) SendMessage(hWndFaceCombo, LB_ADDSTRING, 0,
  442. (LPARAM)panFace->atch);
  443. SendMessage(hWndFaceCombo, LB_SETITEMDATA, lListIndex, FALSE);
  444. }
  445. }
  446. if (! bLB && ! fFindTTFont)
  447. {
  448. for (panFace = pcpd->gpFaceNames; panFace; panFace = panFace->pNext) {
  449. if ((panFace->dwFlag & (EF_TTFONT|EF_NEW)) != (EF_TTFONT|EF_NEW)) {
  450. continue;
  451. }
  452. if ( !fDbcsCharSet && (panFace->dwFlag & EF_DBCSFONT)) {
  453. continue;
  454. }
  455. if ( ( fDbcsCharSet && IsAvailableTTFontCP(pcpd, panFace->atch, CodePage)) ||
  456. (! fDbcsCharSet && IsAvailableTTFontCP(pcpd, panFace->atch, 0))
  457. )
  458. {
  459. if (lstrcmp(ptszTTFace, panFace->atch) != 0)
  460. {
  461. HRESULT hr = StringCchCopy(ptszTTFace, cchTTFace, panFace->atch);
  462. if (FAILED(hr))
  463. {
  464. ptszTTFace[0] = TEXT('\0');
  465. }
  466. break;
  467. }
  468. }
  469. }
  470. }
  471. } // bNewFaceList == TRUE
  472. hWndShow = GetDlgItem(hDlg, IDC_CNSL_BOLDFONT);
  473. // Disable bold font if that will be GDI simulated
  474. if ( fDbcsCharSet && IsDisableBoldTTFont(pcpd, ptszTTFace) )
  475. {
  476. EnableWindow(hWndShow, FALSE);
  477. pcpd->gbBold = FALSE;
  478. CheckDlgButton(hDlg, IDC_CNSL_BOLDFONT, FALSE);
  479. }
  480. else
  481. {
  482. CheckDlgButton(hDlg, IDC_CNSL_BOLDFONT, (bLB || !pcpd->gbBold) ? FALSE : TRUE);
  483. EnableWindow(hWndShow, bLB ? FALSE : TRUE);
  484. }
  485. hWndHide = GetDlgItem(hDlg, bLB ? IDC_CNSL_POINTSLIST : IDC_CNSL_PIXELSLIST);
  486. ShowWindow(hWndHide, SW_HIDE);
  487. EnableWindow(hWndHide, FALSE);
  488. hWndShow = GetDlgItem(hDlg, bLB ? IDC_CNSL_PIXELSLIST : IDC_CNSL_POINTSLIST);
  489. // hStockFont = GetStockObject(SYSTEM_FIXED_FONT);
  490. // SendMessage(hWndShow, WM_SETFONT, (DWORD)hStockFont, FALSE);
  491. ShowWindow(hWndShow, SW_SHOW);
  492. EnableWindow(hWndShow, TRUE);
  493. if (bNewFaceList)
  494. {
  495. lcbRESETCONTENT(hWndShow, bLB);
  496. }
  497. dwExStyle = GetWindowLong(hWndShow, GWL_EXSTYLE);
  498. if(dwExStyle & RTL_MIRRORED_WINDOW)
  499. {
  500. // if mirrored RTL Reading means LTR !!
  501. SetWindowBits(hWndShow, GWL_EXSTYLE, WS_EX_RTLREADING, WS_EX_RTLREADING);
  502. }
  503. /* Initialize hWndShow list/combo box */
  504. for (i=0;i<pcpd->NumberOfFonts;i++) {
  505. int ShowX, ShowY;
  506. if (!bLB == !TM_IS_TT_FONT(pcpd->FontInfo[i].Family)) {
  507. continue;
  508. }
  509. if (fDbcsCharSet) {
  510. if (! IS_ANY_DBCS_CHARSET(pcpd->FontInfo[i].tmCharSet)) {
  511. continue;
  512. }
  513. }
  514. else {
  515. if (IS_ANY_DBCS_CHARSET(pcpd->FontInfo[i].tmCharSet)) {
  516. continue;
  517. }
  518. }
  519. if (!bLB) {
  520. if (lstrcmp(pcpd->FontInfo[i].FaceName, ptszTTFace) != 0 &&
  521. lstrcmp(pcpd->FontInfo[i].FaceName, ptszAltTTFace) != 0) {
  522. /*
  523. * A TrueType font, but not the one we're interested in,
  524. * so don't add it to the list of point sizes.
  525. */
  526. continue;
  527. }
  528. if (pcpd->gbBold != IS_BOLD(pcpd->FontInfo[i].Weight)) {
  529. continue;
  530. }
  531. }
  532. if (pcpd->FontInfo[i].SizeWant.X > 0) {
  533. ShowX = pcpd->FontInfo[i].SizeWant.X;
  534. } else {
  535. ShowX = pcpd->FontInfo[i].Size.X;
  536. }
  537. if (pcpd->FontInfo[i].SizeWant.Y > 0) {
  538. ShowY = pcpd->FontInfo[i].SizeWant.Y;
  539. } else {
  540. ShowY = pcpd->FontInfo[i].Size.Y;
  541. }
  542. /*
  543. * Add the size description string to the end of the right list
  544. */
  545. if (TM_IS_TT_FONT(pcpd->FontInfo[i].Family)) {
  546. // point size
  547. StringCchPrintf(tszText, ARRAYSIZE(tszText), TEXT("%2d"), pcpd->FontInfo[i].SizeWant.Y); // ok to truncate - for display only
  548. } else {
  549. // pixel size
  550. if ((LastShowX == ShowX) && (LastShowY == ShowY)) {
  551. nSameSize++;
  552. } else {
  553. LastShowX = ShowX;
  554. LastShowY = ShowY;
  555. nSameSize = 0;
  556. }
  557. /*
  558. * The number nSameSize is appended to the string to distinguish
  559. * between Raster fonts of the same size. It is not intended to
  560. * be visible and exists off the edge of the list
  561. */
  562. if(((dwExStyle & WS_EX_RIGHT) && !(dwExStyle & RTL_MIRRORED_WINDOW))
  563. || (!(dwExStyle & WS_EX_RIGHT) && (dwExStyle & RTL_MIRRORED_WINDOW))) {
  564. // flip it so that the hidden part be at the far left
  565. StringCchPrintf(tszText, ARRAYSIZE(tszText), TEXT("#%d %2d x %2d"),
  566. nSameSize, ShowX, ShowY); // ok to truncate - for display only
  567. } else {
  568. StringCchPrintf(tszText, ARRAYSIZE(tszText), TEXT("%2d x %2d #%d"),
  569. ShowX, ShowY, nSameSize); // ok to truncate - for display only
  570. }
  571. }
  572. lListIndex = (LONG) lcbFINDSTRINGEXACT(hWndShow, bLB, tszText);
  573. if (lListIndex == LB_ERR) {
  574. lListIndex = (LONG) lcbADDSTRING(hWndShow, bLB, tszText);
  575. }
  576. lcbSETITEMDATA(hWndShow, bLB, (DWORD)lListIndex, i);
  577. }
  578. /*
  579. * Get the FontIndex from the currently selected item.
  580. * (i will be LB_ERR if no currently selected item).
  581. */
  582. lListIndex = (LONG) lcbGETCURSEL(hWndShow, bLB);
  583. i = (int) lcbGETITEMDATA(hWndShow, bLB, lListIndex);
  584. return i;
  585. }
  586. /** ConsoleDrawItemFontList
  587. *
  588. * Answer the WM_DRAWITEM message sent from the font list box or
  589. * facename list box.
  590. *
  591. * Entry:
  592. * lpdis -> DRAWITEMSTRUCT describing object to be drawn
  593. *
  594. * Returns:
  595. * None.
  596. *
  597. * The object is drawn.
  598. */
  599. VOID WINAPI
  600. ConsoleDrawItemFontList(CONSOLEPROP_DATA * pcpd, const LPDRAWITEMSTRUCT lpdis)
  601. {
  602. HDC hDC, hdcMem;
  603. DWORD rgbBack, rgbText, rgbFill;
  604. TCHAR tszFace[LF_FACESIZE];
  605. HBITMAP hOld;
  606. int dy;
  607. HBRUSH hbrFill;
  608. HWND hWndItem;
  609. BOOL bLB;
  610. int dxttbmp;
  611. if ((int)lpdis->itemID < 0)
  612. return;
  613. hDC = lpdis->hDC;
  614. if (lpdis->itemAction & ODA_FOCUS) {
  615. if (lpdis->itemState & ODS_SELECTED) {
  616. DrawFocusRect(hDC, &lpdis->rcItem);
  617. }
  618. } else {
  619. UINT cch;
  620. if (lpdis->itemState & ODS_SELECTED) {
  621. rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  622. rgbBack = SetBkColor(hDC, rgbFill = GetSysColor(COLOR_HIGHLIGHT));
  623. } else {
  624. rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  625. rgbBack = SetBkColor(hDC, rgbFill = GetSysColor(COLOR_WINDOW));
  626. }
  627. // draw selection background
  628. hbrFill = CreateSolidBrush(rgbFill);
  629. if (hbrFill) {
  630. FillRect(hDC, &lpdis->rcItem, hbrFill);
  631. DeleteObject(hbrFill);
  632. }
  633. // get the string
  634. if (IsWindow(hWndItem = lpdis->hwndItem) == FALSE) {
  635. return;
  636. }
  637. cch = (UINT)SendMessage(hWndItem, LB_GETTEXTLEN, lpdis->itemID, 0);
  638. if (cch < ARRAYSIZE(tszFace))
  639. {
  640. SendMessage(hWndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)tszFace);
  641. }
  642. else
  643. {
  644. tszFace[0] = TEXT('\0');
  645. }
  646. bLB = (BOOL) SendMessage(hWndItem, LB_GETITEMDATA, lpdis->itemID, 0L);
  647. dxttbmp = bLB ? 0 : g_bmTT.bmWidth;
  648. // draw the text
  649. TabbedTextOut(hDC, lpdis->rcItem.left + dxttbmp,
  650. lpdis->rcItem.top, tszFace,
  651. lstrlen(tszFace), 0, NULL, dxttbmp);
  652. // and the TT bitmap if needed
  653. if (!bLB) {
  654. hdcMem = CreateCompatibleDC(hDC);
  655. if (hdcMem) {
  656. hOld = SelectObject(hdcMem, g_hbmTT);
  657. dy = ((lpdis->rcItem.bottom - lpdis->rcItem.top) - g_bmTT.bmHeight) / 2;
  658. BitBlt(hDC, lpdis->rcItem.left, lpdis->rcItem.top + dy,
  659. dxttbmp, g_dyFacelistItem, hdcMem,
  660. 0, 0, SRCINVERT);
  661. if (hOld)
  662. SelectObject(hdcMem, hOld);
  663. DeleteDC(hdcMem);
  664. }
  665. }
  666. SetTextColor(hDC, rgbText);
  667. SetBkColor(hDC, rgbBack);
  668. if (lpdis->itemState & ODS_FOCUS) {
  669. DrawFocusRect(hDC, &lpdis->rcItem);
  670. }
  671. }
  672. }
  673. UINT
  674. GetPointSizeInRange(
  675. HWND hDlg,
  676. INT Min,
  677. INT Max)
  678. /*++
  679. Routine Description:
  680. Get a size from the Point Size ComboBox edit field
  681. Return Value:
  682. Point Size - of the edit field limited by Min/Max size
  683. 0 - if the field is empty or invalid
  684. --*/
  685. {
  686. TCHAR szBuf[90];
  687. int nTmp = 0;
  688. BOOL bOK;
  689. if (GetDlgItemText(hDlg, IDC_CNSL_POINTSLIST, szBuf, NELEM(szBuf))) {
  690. nTmp = GetDlgItemInt(hDlg, IDC_CNSL_POINTSLIST, &bOK, TRUE);
  691. if (bOK && nTmp >= Min && nTmp <= Max) {
  692. return nTmp;
  693. }
  694. }
  695. return 0;
  696. }
  697. /* ----- Preview routines ----- */
  698. LRESULT
  699. _FontPreviewWndProc(
  700. HWND hWnd,
  701. UINT wMessage,
  702. WPARAM wParam,
  703. LPARAM lParam
  704. )
  705. /* FontPreviewWndProc
  706. * Handles the font preview window
  707. */
  708. {
  709. PAINTSTRUCT ps;
  710. RECT rect;
  711. HBRUSH hbrClient;
  712. HBRUSH hbrOld;
  713. COLORREF rgbText;
  714. COLORREF rgbBk;
  715. CONSOLEPROP_DATA * pcpd = (CONSOLEPROP_DATA *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
  716. switch (wMessage) {
  717. case WM_CREATE:
  718. pcpd = (CONSOLEPROP_DATA *)((LPCREATESTRUCT)lParam)->lpCreateParams;
  719. SetWindowLongPtr( hWnd, GWLP_USERDATA, (LPARAM)pcpd );
  720. break;
  721. case WM_PAINT:
  722. BeginPaint(hWnd, &ps);
  723. /* Draw the font sample */
  724. rgbText = GetNearestColor(ps.hdc, ScreenTextColor(pcpd));
  725. rgbBk = GetNearestColor(ps.hdc, ScreenBkColor(pcpd));
  726. SelectObject(ps.hdc, pcpd->FontInfo[pcpd->CurrentFontIndex].hFont);
  727. SetTextColor(ps.hdc, rgbText);
  728. SetBkColor(ps.hdc, rgbBk);
  729. GetClientRect(hWnd, &rect);
  730. InflateRect(&rect, -2, -2);
  731. hbrClient = CreateSolidBrush(rgbBk);
  732. if (hbrClient)
  733. hbrOld = SelectObject(ps.hdc, hbrClient);
  734. PatBlt(ps.hdc, rect.left, rect.top,
  735. rect.right - rect.left, rect.bottom - rect.top,
  736. PATCOPY);
  737. DrawText(ps.hdc, g_szPreviewText, -1, &rect, 0);
  738. if (hbrClient)
  739. {
  740. SelectObject(ps.hdc, hbrOld);
  741. DeleteObject(hbrClient);
  742. }
  743. EndPaint(hWnd, &ps);
  744. break;
  745. default:
  746. return DefWindowProc(hWnd, wMessage, wParam, lParam);
  747. }
  748. return 0L;
  749. }
  750. /*
  751. * SelectCurrentSize - Select the right line of the Size listbox/combobox.
  752. * bLB : Size controls is a listbox (TRUE for RasterFonts)
  753. * FontIndex : Index into FontInfo[] cache
  754. * If < 0 then choose a good font.
  755. * Returns
  756. * FontIndex : Index into FontInfo[] cache
  757. */
  758. int
  759. SelectCurrentSize(CONSOLEPROP_DATA * pcpd, HWND hDlg, BOOL bLB, int FontIndex)
  760. {
  761. int iCB;
  762. HWND hWndList;
  763. hWndList = GetDlgItem(hDlg, bLB ? IDC_CNSL_PIXELSLIST : IDC_CNSL_POINTSLIST);
  764. iCB = (int) lcbGETCOUNT(hWndList, bLB);
  765. if (FontIndex >= 0) {
  766. /*
  767. * look for FontIndex
  768. */
  769. while (iCB > 0) {
  770. iCB--;
  771. if (lcbGETITEMDATA(hWndList, bLB, iCB) == FontIndex) {
  772. lcbSETCURSEL(hWndList, bLB, iCB);
  773. break;
  774. }
  775. }
  776. } else {
  777. /*
  778. * look for a reasonable default size: looking backwards, find
  779. * the first one same height or smaller.
  780. */
  781. DWORD Size;
  782. Size = pcpd->FontLong;
  783. if (IsFarEastCP(pcpd->uOEMCP) & bLB
  784. && (pcpd->FontInfo[pcpd->CurrentFontIndex].tmCharSet != LOBYTE(LOWORD(Size)))
  785. )
  786. {
  787. TCHAR AltFaceName[LF_FACESIZE];
  788. COORD AltFontSize;
  789. BYTE AltFontFamily;
  790. ULONG AltFontIndex = 0;
  791. MakeAltRasterFont(pcpd, pcpd->lpFEConsole->uCodePage, &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName, ARRAYSIZE(AltFaceName));
  792. while(iCB > 0) {
  793. iCB--;
  794. if (lcbGETITEMDATA(hWndList, bLB, iCB) == (int)AltFontIndex) {
  795. lcbSETCURSEL(hWndList, bLB, iCB);
  796. break;
  797. }
  798. }
  799. }
  800. else
  801. {
  802. while (iCB > 0) {
  803. iCB--;
  804. FontIndex = (ULONG) lcbGETITEMDATA(hWndList, bLB, iCB);
  805. if (pcpd->FontInfo[FontIndex].Size.Y <= HIWORD(Size)) {
  806. lcbSETCURSEL(hWndList, bLB, iCB);
  807. break;
  808. }
  809. }
  810. }
  811. }
  812. return FontIndex;
  813. }
  814. BOOL
  815. SelectCurrentFont(CONSOLEPROP_DATA * pcpd, HWND hDlg, int FontIndex)
  816. {
  817. BOOL bLB;
  818. bLB = !TM_IS_TT_FONT(pcpd->FontInfo[FontIndex].Family);
  819. SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_SELECTSTRING, (DWORD)-1,
  820. bLB ? (LPARAM)tszRasterFonts : (LPARAM)(pcpd->FontInfo[FontIndex].FaceName));
  821. SelectCurrentSize(pcpd, hDlg, bLB, FontIndex);
  822. return bLB;
  823. }
  824. BOOL
  825. ConsolePreviewInit(
  826. CONSOLEPROP_DATA * pcpd,
  827. HWND hDlg,
  828. BOOL* pfRaster
  829. )
  830. /* PreviewInit
  831. * Prepares the preview code, sizing the window and the dialog to
  832. * make an attractive preview.
  833. * *pfRaster is TRUE if Raster Fonts, FALSE if TT Font
  834. * Returns FALSE on critical failure, TRUE otherwise
  835. */
  836. {
  837. HDC hDC;
  838. TEXTMETRIC tm;
  839. RECT rectLabel;
  840. RECT rectGroup;
  841. int nFont;
  842. SHORT xChar;
  843. SHORT yChar;
  844. /* Get the system char size */
  845. hDC = GetDC(hDlg);
  846. if (!hDC)
  847. {
  848. // Out of memory; just close the dialog - better than crashing: Prefix 98162
  849. return FALSE;
  850. }
  851. GetTextMetrics(hDC, &tm);
  852. ReleaseDC(hDlg, hDC);
  853. xChar = (SHORT) (tm.tmAveCharWidth);
  854. yChar = (SHORT) (tm.tmHeight + tm.tmExternalLeading);
  855. /* Compute the size of the font preview */
  856. GetWindowRect(GetDlgItem(hDlg, IDC_CNSL_GROUP), &rectGroup);
  857. MapWindowRect(HWND_DESKTOP, hDlg, &rectGroup);
  858. rectGroup.bottom -= rectGroup.top;
  859. GetWindowRect(GetDlgItem(hDlg, IDC_CNSL_STATIC2), &rectLabel);
  860. MapWindowRect(HWND_DESKTOP, hDlg, &rectLabel);
  861. /* Create the font preview */
  862. CreateWindowEx(0L, TEXT("WOACnslFontPreview"), NULL,
  863. WS_CHILD | WS_VISIBLE,
  864. rectGroup.left + xChar, rectGroup.top + 3 * yChar / 2,
  865. rectLabel.left - rectGroup.left - 2 * xChar,
  866. rectGroup.bottom - 2 * yChar,
  867. hDlg, (HMENU)IDC_CNSL_FONTWINDOW, g_hinst, (LPVOID)pcpd);
  868. /*
  869. * Set the current font
  870. */
  871. nFont = FindCreateFont(pcpd,
  872. pcpd->lpConsole->uFontFamily,
  873. pcpd->lpFaceName,
  874. pcpd->lpConsole->dwFontSize,
  875. pcpd->lpConsole->uFontWeight);
  876. pcpd->CurrentFontIndex = nFont;
  877. *pfRaster = SelectCurrentFont(pcpd, hDlg, nFont);
  878. return TRUE;
  879. }
  880. BOOL
  881. ConsolePreviewUpdate(
  882. CONSOLEPROP_DATA * pcpd,
  883. HWND hDlg,
  884. BOOL bLB
  885. )
  886. /*++
  887. Does the preview of the selected font.
  888. --*/
  889. {
  890. FONT_INFO *lpFont;
  891. int FontIndex;
  892. LONG lIndex;
  893. HWND hWnd;
  894. TCHAR tszText[60];
  895. TCHAR tszFace[LF_FACESIZE + CCH_SELECTEDFONT];
  896. HWND hWndList;
  897. hWndList = GetDlgItem(hDlg, bLB ? IDC_CNSL_PIXELSLIST : IDC_CNSL_POINTSLIST);
  898. /* When we select a font, we do the font preview by setting it into
  899. * the appropriate list box
  900. */
  901. lIndex = (LONG) lcbGETCURSEL(hWndList, bLB);
  902. if ((lIndex < 0) && !bLB) {
  903. COORD NewSize;
  904. UINT cch;
  905. lIndex = (LONG) SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETCURSEL, 0, 0L);
  906. cch = (UINT)SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETTEXTLEN, lIndex, 0);
  907. if (cch < ARRAYSIZE(tszFace))
  908. {
  909. SendDlgItemMessage(hDlg, IDC_CNSL_FACENAME, LB_GETTEXT, lIndex, (LPARAM)tszFace);
  910. }
  911. else
  912. {
  913. tszFace[0] = TEXT('\0');
  914. }
  915. NewSize.X = 0;
  916. NewSize.Y = (SHORT) GetPointSizeInRange(hDlg, MIN_PIXEL_HEIGHT, MAX_PIXEL_HEIGHT);
  917. if (NewSize.Y == 0) {
  918. TCHAR tszBuf[60];
  919. /*
  920. * Use tszText, tszBuf to put up an error msg for bad point size
  921. */
  922. pcpd->gbPointSizeError = TRUE;
  923. GetWindowText(hDlg, tszBuf, NELEM(tszBuf));
  924. ShellMessageBox(HINST_THISDLL, hDlg, MAKEINTRESOURCE(IDS_CNSL_FONTSIZE),
  925. tszBuf, MB_OK|MB_ICONINFORMATION,
  926. MIN_PIXEL_HEIGHT, MAX_PIXEL_HEIGHT);
  927. SetFocus(hWndList);
  928. pcpd->gbPointSizeError = FALSE;
  929. return FALSE;
  930. }
  931. FontIndex = FindCreateFont(pcpd,
  932. FF_MODERN|TMPF_VECTOR|TMPF_TRUETYPE,
  933. tszFace, NewSize, 0);
  934. } else {
  935. FontIndex = (int) lcbGETITEMDATA(hWndList, bLB, lIndex);
  936. }
  937. if (FontIndex < 0) {
  938. FontIndex = pcpd->DefaultFontIndex;
  939. }
  940. /*
  941. * If we've selected a new font, tell the property sheet we've changed
  942. */
  943. if (pcpd->CurrentFontIndex != (ULONG)FontIndex) {
  944. pcpd->CurrentFontIndex = FontIndex;
  945. }
  946. lpFont = &pcpd->FontInfo[FontIndex];
  947. /* Display the new font */
  948. StringCchCopy(tszFace, ARRAYSIZE(tszFace), tszSelectedFont); // ok to truncate - for display only
  949. StringCchCat(tszFace, ARRAYSIZE(tszFace), lpFont->FaceName); // ok to truncate - for display only
  950. SetDlgItemText(hDlg, IDC_CNSL_GROUP, tszFace);
  951. /* Put the font size in the static boxes */
  952. StringCchPrintf(tszText, ARRAYSIZE(tszText), TEXT("%u"), lpFont->Size.X); // ok to truncate - for display only
  953. hWnd = GetDlgItem(hDlg, IDC_CNSL_FONTWIDTH);
  954. SetWindowText(hWnd, tszText);
  955. InvalidateRect(hWnd, NULL, TRUE);
  956. StringCchPrintf(tszText, ARRAYSIZE(tszText), TEXT("%u"), lpFont->Size.Y); // ok to truncate - for display only
  957. hWnd = GetDlgItem(hDlg, IDC_CNSL_FONTHEIGHT);
  958. SetWindowText(hWnd, tszText);
  959. InvalidateRect(hWnd, NULL, TRUE);
  960. /* Force the preview windows to repaint */
  961. hWnd = GetDlgItem(hDlg, IDC_CNSL_PREVIEWWINDOW);
  962. SendMessage(hWnd, CM_PREVIEW_UPDATE, 0, 0);
  963. hWnd = GetDlgItem(hDlg, IDC_CNSL_FONTWINDOW);
  964. InvalidateRect(hWnd, NULL, TRUE);
  965. return TRUE;
  966. }