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.

458 lines
13 KiB

  1. /* CUSTFONT.C
  2. **
  3. ** Copyright (C) Microsoft, 1993, All Rights Reserved.
  4. **
  5. ** History:
  6. **
  7. */
  8. #include "priv.h"
  9. #pragma hdrstop
  10. static struct
  11. {
  12. UINT wWidth;
  13. UINT wHeight;
  14. UINT wSizeFontId;
  15. UINT wStartPos;
  16. UINT wStartPix;
  17. } g;
  18. static UINT g_iCurPercent;
  19. static RECT g_rcRuler;
  20. static TCHAR g_szRulerDirections[200];
  21. static TCHAR g_szSample[100];
  22. static TCHAR g_szSampleFace[32];
  23. static int g_cxRulerDirections;
  24. static BOOL g_bTypeTimer = FALSE;
  25. static TCHAR szPctD[] = TEXT("%d");
  26. static TCHAR szPercentNum[] = TEXT("%d%%");
  27. #define NUM_DEFPERCENTS 5
  28. static UINT g_DefaultPercents[NUM_DEFPERCENTS] = {75, 100, 125, 150, 200};
  29. #define MAX_PERCENT 500
  30. #define MIN_PERCENT 20
  31. #define GETPERCENT(dpi) ((dpi * 100 + 50) / 96)
  32. #define GETDPI(percent) ((percent * 96 + 48) /100)
  33. #define UPDATE_CURPER 0x0001
  34. #define UPDATE_COMBO 0x0002
  35. #define UPDATE_SAMPLE 0x0004
  36. #define UPDATE_RULER 0x0008
  37. #define UPDATE_ALL 0x000F
  38. void NEAR PASCAL DrawRuler(HWND hDlg, LPDRAWITEMSTRUCT lpdis)
  39. {
  40. int nFact;
  41. RECT rc;
  42. HDC hdc;
  43. int nPixInch;
  44. int i, j;
  45. TCHAR szTemp[10];
  46. int nOldMode;
  47. hdc = lpdis->hDC;
  48. nOldMode = SetBkMode(hdc, TRANSPARENT);
  49. // use g_rcRuler to draw the ruler. it's already been spaced
  50. rc = g_rcRuler;
  51. // first, draw the directions
  52. i = rc.left + ((rc.right - rc.left) - g_cxRulerDirections)/2;
  53. nPixInch = GETDPI(g_iCurPercent);
  54. // draw the top and left edge of the ruler
  55. DrawEdge(hdc, &rc, EDGE_ETCHED, BF_TOPLEFT);
  56. // rest of drawing happens just below the top
  57. rc.top += ClassicGetSystemMetrics(SM_CYEDGE);
  58. nFact = 1;
  59. // draw one of the etch heights (1", 1/2", 1/4") per iteration
  60. for (j=0; j<3; ++j)
  61. {
  62. for (i=0; ; ++i)
  63. {
  64. rc.left = g_rcRuler.left + (j==0 ? i*nPixInch : (2*i+1)*nPixInch/nFact);
  65. if (rc.left >= g_rcRuler.right)
  66. {
  67. break;
  68. }
  69. DrawEdge(hdc, &rc, EDGE_ETCHED, BF_LEFT | BF_ADJUST);
  70. // dominant etch deserves a number
  71. if (j == 0)
  72. {
  73. StringCchPrintf(szTemp, ARRAYSIZE(szTemp), szPctD, i);
  74. TextOut(hdc, rc.left+1, rc.bottom-g.wHeight,
  75. szTemp, lstrlen(szTemp));
  76. }
  77. }
  78. rc.bottom -= (rc.bottom - rc.top)/2;
  79. nFact *= 2;
  80. }
  81. SetBkMode(hdc, nOldMode);
  82. }
  83. void NEAR PASCAL CF_UpdateRuler(HWND hDlg)
  84. {
  85. RECT rc;
  86. HWND hwnd;
  87. /* Don't do this stuff if the dialog is not
  88. ** visible yet, or other windows will flash.
  89. */
  90. if (IsWindowVisible(hDlg))
  91. {
  92. // don't invalidate top and left because they never change.
  93. rc = g_rcRuler;
  94. rc.left += ClassicGetSystemMetrics(SM_CXEDGE);
  95. rc.top += ClassicGetSystemMetrics(SM_CYEDGE);
  96. hwnd = GetDlgItem(hDlg, IDC_CUSTOMRULER);
  97. InvalidateRect(hwnd, &rc, TRUE);
  98. UpdateWindow(hwnd);
  99. }
  100. }
  101. void NEAR PASCAL CF_ShowNewPercent(HWND hDlg, UINT uPer)
  102. {
  103. TCHAR szBuf[10];
  104. g_iCurPercent = uPer;
  105. StringCchPrintf(szBuf, ARRAYSIZE(szBuf), szPercentNum, uPer);
  106. SetWindowText(GetDlgItem(hDlg, IDC_CUSTOMCOMBO), szBuf);
  107. UpdateWindow(GetDlgItem(hDlg, IDC_CUSTOMCOMBO));
  108. }
  109. // Build lf with given face and height
  110. //
  111. int CALLBACK EnumProc(CONST LOGFONT *lplf, CONST TEXTMETRIC *lptm, DWORD nType, LPARAM lpData )
  112. {
  113. *(LPLOGFONT)lpData = *lplf;
  114. return FALSE;
  115. }
  116. HFONT CreateFontWithFace(HWND hwnd, int nHeight, LPCTSTR lpszFace)
  117. {
  118. LOGFONT lf;
  119. HDC hdc;
  120. hdc = GetDC(hwnd);
  121. if(hdc)
  122. {
  123. EnumFontFamilies(hdc, lpszFace, EnumProc, (LPARAM)&lf);
  124. ReleaseDC(hwnd,hdc);
  125. }
  126. lf.lfHeight = nHeight;
  127. lf.lfWidth = lf. lfEscapement = lf.lfOrientation = 0;
  128. return CreateFontIndirect(&lf);
  129. }
  130. void NEAR PASCAL CF_UpdateData(HWND hDlg, UINT uPer, UINT flags)
  131. {
  132. TCHAR szBuf[100];
  133. HFONT hfont;
  134. int i;
  135. HWND hwnd;
  136. int iDPI;
  137. if (flags & UPDATE_CURPER)
  138. {
  139. if (uPer == g_iCurPercent)
  140. return;
  141. if (uPer < MIN_PERCENT)
  142. uPer = MIN_PERCENT;
  143. else if (uPer > MAX_PERCENT)
  144. uPer = MAX_PERCENT;
  145. g_iCurPercent = uPer;
  146. }
  147. if (flags & UPDATE_COMBO)
  148. {
  149. hwnd = GetDlgItem(hDlg, IDC_CUSTOMCOMBO);
  150. StringCchPrintf(szBuf, ARRAYSIZE(szBuf), szPercentNum, g_iCurPercent);
  151. i = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)szBuf);
  152. SendMessage(hwnd, CB_SETCURSEL, (WPARAM)i, 0L);
  153. if (i == -1)
  154. {
  155. SetWindowText(hwnd, szBuf);
  156. UpdateWindow(hwnd);
  157. }
  158. }
  159. if (flags & UPDATE_RULER)
  160. CF_UpdateRuler(hDlg);
  161. if (flags & UPDATE_SAMPLE)
  162. {
  163. iDPI = GETDPI(g_iCurPercent);
  164. // build and set string with DPI info
  165. hwnd = GetDlgItem(hDlg, IDC_CUSTOMSAMPLE);
  166. StringCchPrintf(szBuf, ARRAYSIZE(szBuf), g_szSample, (LPTSTR)g_szSampleFace, iDPI);
  167. SetWindowText(hwnd, szBuf);
  168. hfont = CreateFontWithFace(hwnd, -10 * iDPI / 72, g_szSampleFace);
  169. if (hfont)
  170. {
  171. hfont = (HFONT)SendMessage(hwnd, WM_SETFONT, (WPARAM)hfont, 1L);
  172. if (hfont)
  173. DeleteObject(hfont);
  174. }
  175. }
  176. }
  177. void NEAR PASCAL CF_ReadNewPercent(HWND hDlg)
  178. {
  179. TCHAR szBuf[10];
  180. LPTSTR pstr;
  181. UINT uPer = 0;
  182. GetWindowText(GetDlgItem(hDlg, IDC_CUSTOMCOMBO), szBuf, ARRAYSIZE(szBuf));
  183. pstr = szBuf;
  184. while (*pstr && (*pstr != TEXT('%')))
  185. {
  186. if (*pstr >= TEXT('0') && *pstr <= TEXT('9'))
  187. uPer = uPer * 10 + (*pstr - TEXT('0'));
  188. pstr++;
  189. }
  190. CF_UpdateData(hDlg, uPer, UPDATE_ALL);
  191. }
  192. void NEAR PASCAL CF_InitDialog(HWND hDlg, UINT uDPI)
  193. {
  194. HWND hwnd;
  195. HDC hdc;
  196. HFONT hfont;
  197. SIZE szSize;
  198. int i;
  199. TCHAR szBuf[10];
  200. int iCurSel;
  201. g_iCurPercent = GETPERCENT(uDPI);
  202. hwnd = GetDlgItem(hDlg, IDC_CUSTOMCOMBO);
  203. iCurSel = -1; // assume not in list
  204. for (i = 0; i < NUM_DEFPERCENTS; i++)
  205. {
  206. StringCchPrintf(szBuf, ARRAYSIZE(szBuf), szPercentNum, g_DefaultPercents[i]);
  207. SendMessage(hwnd, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szBuf);
  208. SendMessage(hwnd, CB_SETITEMDATA, (WPARAM)i, g_DefaultPercents[i]);
  209. if (g_iCurPercent == g_DefaultPercents[i])
  210. iCurSel = i;
  211. }
  212. SendMessage(hwnd, CB_SETCURSEL, (WPARAM)iCurSel, 0L);
  213. if (iCurSel == -1)
  214. {
  215. StringCchPrintf(szBuf, ARRAYSIZE(szBuf), szPercentNum, g_iCurPercent);
  216. SetWindowText(hwnd, szBuf);
  217. }
  218. hdc = GetDC(hDlg);
  219. hfont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
  220. if (hfont)
  221. hfont = (HFONT) SelectObject(hdc, hfont);
  222. GetTextExtentPoint32(hdc, TEXT("0"), 1, &szSize);
  223. g.wWidth = szSize.cx;
  224. g.wHeight = szSize.cy;
  225. LoadString(HINST_THISDLL, IDS_RULERDIRECTION, g_szRulerDirections, ARRAYSIZE(g_szRulerDirections));
  226. GetTextExtentPoint32(hdc, g_szRulerDirections, lstrlen(g_szRulerDirections), &szSize);
  227. g_cxRulerDirections = szSize.cx;
  228. if (hfont)
  229. SelectObject(hdc, hfont);
  230. ReleaseDC(hDlg, hdc);
  231. // calculate the rectangle for the actual ruler drawing in relation
  232. // to its window
  233. GetClientRect(GetDlgItem(hDlg, IDC_CUSTOMRULER), &g_rcRuler);
  234. g_rcRuler.left += g.wWidth;
  235. g_rcRuler.right -= g.wWidth;
  236. // bottom offset like the sides
  237. g_rcRuler.bottom -= g.wWidth;
  238. LoadString(HINST_THISDLL, IDS_10PTSAMPLE, g_szSample, ARRAYSIZE(g_szSample));
  239. LoadString(HINST_THISDLL, IDS_10PTSAMPLEFACENAME, g_szSampleFace, ARRAYSIZE(g_szSampleFace));
  240. CF_UpdateData(hDlg, 0, UPDATE_SAMPLE);
  241. }
  242. /////////////////////////////////////////////////////////////////////////////
  243. const static DWORD FAR aCustFontHelpIds[] = {
  244. IDC_CUSTOMCOMBO, IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_LISTBOX,
  245. IDC_CUSTOMRULER, IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_RULER,
  246. IDC_CUSTOMSAMPLE,IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_SAMPLE,
  247. 0, 0
  248. };
  249. INT_PTR CALLBACK CustomFontDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)
  250. {
  251. HFONT hfont;
  252. int i;
  253. switch (uMessage)
  254. {
  255. case WM_CREATE:
  256. break;
  257. case WM_INITDIALOG:
  258. CF_InitDialog(hDlg, (UINT)lParam);
  259. break;
  260. case WM_DESTROY:
  261. hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_CUSTOMSAMPLE, WM_GETFONT, 0, 0L);
  262. if (hfont)
  263. DeleteObject(hfont);
  264. break;
  265. case WM_DRAWITEM:
  266. if (wParam == IDC_CUSTOMRULER)
  267. DrawRuler(hDlg, (LPDRAWITEMSTRUCT)lParam);
  268. break;
  269. case WM_TIMER:
  270. if (g_bTypeTimer)
  271. {
  272. KillTimer(hDlg, 13);
  273. g_bTypeTimer = FALSE;
  274. CF_ReadNewPercent(hDlg);
  275. }
  276. break;
  277. case WM_HELP:
  278. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, TEXT("display.hlp"), HELP_WM_HELP,
  279. (DWORD_PTR)(LPTSTR)aCustFontHelpIds);
  280. break;
  281. case WM_CONTEXTMENU:
  282. WinHelp((HWND)wParam, TEXT("display.hlp"), HELP_CONTEXTMENU,
  283. (DWORD_PTR)(LPTSTR)aCustFontHelpIds);
  284. break;
  285. case WM_COMMAND:
  286. switch (LOWORD(wParam))
  287. {
  288. case IDOK:
  289. EndDialog(hDlg, GETDPI(g_iCurPercent));
  290. break;
  291. case IDCANCEL:
  292. EndDialog(hDlg, 0);
  293. break;
  294. case IDC_CUSTOMRULER:
  295. switch (HIWORD(wParam))
  296. {
  297. case DSN_NCCREATE:
  298. SetWindowLong((HWND)lParam, GWL_EXSTYLE,
  299. GetWindowLong((HWND)lParam, GWL_EXSTYLE) | WS_EX_WINDOWEDGE);
  300. break;
  301. case DSN_BEGINDRAG:
  302. // Set the focus to the corresponding edit ctl
  303. SendMessage(hDlg, WM_NEXTDLGCTL,
  304. (WPARAM)GetDlgItem(hDlg, IDC_CUSTOMCOMBO), 1L);
  305. SendMessage((HWND)lParam, DSM_DRAGPOS, 0, (LPARAM)&(g.wStartPos));
  306. if ((int)g.wStartPos < g_rcRuler.left)
  307. {
  308. g.wStartPos = g_rcRuler.left;
  309. }
  310. g.wStartPix = g_iCurPercent;
  311. break;
  312. case DSN_DRAGGING:
  313. {
  314. UINT wNow, wPix;
  315. POINT pt;
  316. //wNow = LOWORD(SendMessage((HWND)lParam, DSM_DRAGPOS, 0, 0L));
  317. SendMessage((HWND)lParam, DSM_DRAGPOS, 0, (LPARAM)&pt);
  318. wNow = pt.x;
  319. if ((int)wNow < g_rcRuler.left)
  320. {
  321. wNow = g_rcRuler.left;
  322. }
  323. wPix = LOWORD((DWORD)wNow*g.wStartPix/g.wStartPos);
  324. if (wPix < MIN_PERCENT)
  325. {
  326. wPix = MIN_PERCENT;
  327. }
  328. if (wPix > MAX_PERCENT)
  329. {
  330. wPix = MAX_PERCENT;
  331. }
  332. if (wPix != g_iCurPercent)
  333. {
  334. CF_ShowNewPercent(hDlg, wPix);
  335. CF_UpdateRuler(hDlg);
  336. }
  337. break;
  338. }
  339. case DSN_ENDDRAG:
  340. CF_UpdateData(hDlg, 0, UPDATE_COMBO | UPDATE_SAMPLE);
  341. break;
  342. default:
  343. break;
  344. }
  345. break;
  346. case IDC_CUSTOMCOMBO:
  347. switch(HIWORD(wParam))
  348. {
  349. case CBN_SELCHANGE:
  350. i = (int)SendDlgItemMessage(hDlg, IDC_CUSTOMCOMBO, CB_GETCURSEL, 0, 0L);
  351. if (i != CB_ERR)
  352. {
  353. i = LOWORD(SendDlgItemMessage(hDlg, IDC_CUSTOMCOMBO, CB_GETITEMDATA, (WPARAM)i, 0L));
  354. CF_UpdateData(hDlg, (UINT)i, UPDATE_CURPER | UPDATE_SAMPLE | UPDATE_RULER);
  355. }
  356. break;
  357. case CBN_EDITCHANGE:
  358. if (g_bTypeTimer)
  359. {
  360. KillTimer(hDlg, 13);
  361. }
  362. g_bTypeTimer = TRUE;
  363. SetTimer(hDlg, 13, 500, NULL);
  364. break;
  365. }
  366. break;
  367. default:
  368. return(FALSE);
  369. }
  370. break;
  371. default:
  372. return(FALSE);
  373. }
  374. return(TRUE);
  375. }