custfont.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 14k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*  CUSTFONT.C
  2. **
  3. **  Copyright (C) Microsoft, 1993, All Rights Reserved.
  4. **
  5. **  History:
  6. **
  7. */
  8. #include "precomp.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.     TextOut(hdc, i, lpdis->rcItem.top + g.wHeight/4,
  54.                                 g_szRulerDirections, lstrlen(g_szRulerDirections));
  55.     nPixInch = GETDPI(g_iCurPercent);
  56.     // draw the top and left edge of the ruler
  57.     DrawEdge(hdc, &rc, EDGE_ETCHED, BF_TOPLEFT);
  58.     // rest of drawing happens just below the top
  59.     rc.top += GetSystemMetrics(SM_CYEDGE);
  60.     nFact = 1;
  61.     // draw one of the etch heights (1", 1/2", 1/4") per iteration
  62.     for (j=0; j<3; ++j)
  63.     {
  64.         for (i=0; ; ++i)
  65.         {
  66.             rc.left = g_rcRuler.left + (j==0 ? i*nPixInch : (2*i+1)*nPixInch/nFact);
  67.             if (rc.left >= g_rcRuler.right)
  68.             {
  69.                 break;
  70.             }
  71.             DrawEdge(hdc, &rc, EDGE_ETCHED, BF_LEFT | BF_ADJUST);
  72.             // dominant etch deserves a number
  73.             if (j == 0)
  74.             {
  75.                 TextOut(hdc, rc.left+1, rc.bottom-g.wHeight,
  76.                                         szTemp, wsprintf(szTemp, szPctD, i));
  77.             }
  78.         }
  79.         rc.bottom -= (rc.bottom - rc.top)/2;
  80.         nFact *= 2;
  81.     }
  82.     SetBkMode(hdc, nOldMode);
  83. }
  84. void NEAR PASCAL CF_UpdateRuler(HWND hDlg)
  85. {
  86.     RECT rc;
  87.     HWND hwnd;
  88.     /* Don't do this stuff if the dialog is not
  89.     ** visible yet, or other windows will flash.
  90.     */
  91.     if (IsWindowVisible(hDlg))
  92.     {
  93.         // don't invalidate top and left because they never change.
  94.         rc = g_rcRuler;
  95.         rc.left += GetSystemMetrics(SM_CXEDGE);
  96.         rc.top += GetSystemMetrics(SM_CYEDGE);
  97.         hwnd = GetDlgItem(hDlg, IDC_CUSTOMRULER);
  98.         InvalidateRect(hwnd, &rc, TRUE);
  99.         UpdateWindow(hwnd);
  100.     }
  101. }
  102. void NEAR PASCAL CF_ShowNewPercent(HWND hDlg, UINT uPer)
  103. {
  104.     TCHAR szBuf[10];
  105.     g_iCurPercent = uPer;
  106.     wsprintf(szBuf, szPercentNum, uPer);
  107.     SetWindowText(GetDlgItem(hDlg, IDC_CUSTOMCOMBO), szBuf);
  108.     UpdateWindow(GetDlgItem(hDlg, IDC_CUSTOMCOMBO));
  109. }
  110. // Build lf with given face and height
  111. //
  112. int CALLBACK EnumProc(CONST LOGFONT *lplf, CONST TEXTMETRIC *lptm, DWORD nType, LPARAM lpData )
  113. {
  114.     *(LPLOGFONT)lpData = *lplf;
  115.     return FALSE;
  116. }
  117. HFONT CreateFontWithFace(HWND hwnd, int nHeight, LPCTSTR lpszFace)
  118. {
  119.     LOGFONT lf;
  120.     HDC     hdc;
  121.     if(hdc = GetDC(hwnd))
  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.         wsprintf(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.         wsprintf(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.         wsprintf(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.         wsprintf(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 = SelectObject(hdc, hfont);
  222.     //dwSize = GetTextExtentPoint32(hdc, TEXT("0"), 1);
  223.     GetTextExtentPoint32(hdc, TEXT("0"), 1, &szSize);
  224.     g.wWidth = szSize.cx;
  225.     g.wHeight = szSize.cy;
  226.     LoadString(hInstance, IDS_RULERDIRECTION, g_szRulerDirections, ARRAYSIZE(g_szRulerDirections));
  227.     //g_cxRulerDirections = LOWORD(GetTextExtent(hdc, g_szRulerDirections, lstrlen(g_szRulerDirections)));
  228.     GetTextExtentPoint32(hdc, g_szRulerDirections, lstrlen(g_szRulerDirections), &szSize);
  229.     g_cxRulerDirections = szSize.cx;
  230.     if (hfont)
  231.         SelectObject(hdc, hfont);
  232.     ReleaseDC(hDlg, hdc);
  233.     // calculate the rectangle for the actual ruler drawing in relation
  234.     // to its window
  235.     GetClientRect(GetDlgItem(hDlg, IDC_CUSTOMRULER), &g_rcRuler);
  236.     g_rcRuler.left += g.wWidth;
  237.     g_rcRuler.right -= g.wWidth;
  238.     // room for explanatory string
  239.     g_rcRuler.top += g.wHeight + g.wHeight/2;
  240.     // bottom offset like the sides
  241.     g_rcRuler.bottom -= g.wWidth;
  242.     LoadString(hInstance, IDS_10PTSAMPLE, g_szSample, ARRAYSIZE(g_szSample));
  243.     LoadString(hInstance, IDS_10PTSAMPLEFACENAME, g_szSampleFace, ARRAYSIZE(g_szSampleFace));
  244.     CF_UpdateData(hDlg, 0, UPDATE_SAMPLE);
  245. }
  246. /////////////////////////////////////////////////////////////////////////////
  247. const static DWORD FAR aCustFontHelpIds[] = {
  248.         // IDC_NO_HELP_1,      IDH_COMM_GROUPBOX,
  249.         IDC_CUSTOMCOMBO, IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_LISTBOX,
  250.         IDC_CUSTOMRULER, IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_RULER,
  251.         IDC_CUSTOMSAMPLE,IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_SAMPLE,
  252.         0, 0
  253. };
  254. BOOL CALLBACK CustomFontDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)
  255. {
  256.     HFONT hfont;
  257.     int i;
  258.     switch (uMessage)
  259.     {
  260.         case WM_CREATE:
  261.             break;
  262.         case WM_INITDIALOG:
  263.             CF_InitDialog(hDlg, (UINT)lParam);
  264.             break;
  265.         case WM_DESTROY:
  266.             hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_CUSTOMSAMPLE, WM_GETFONT, 0, 0L);
  267.             if (hfont)
  268.                 DeleteObject(hfont);
  269.             break;
  270.         case WM_DRAWITEM:
  271.             if (wParam == IDC_CUSTOMRULER)
  272.                 DrawRuler(hDlg, (LPDRAWITEMSTRUCT)lParam);
  273.             break;
  274.         case WM_TIMER:
  275.             if (g_bTypeTimer)
  276.             {
  277.                 KillTimer(hDlg, 13);
  278.                 g_bTypeTimer = FALSE;
  279.                 CF_ReadNewPercent(hDlg);
  280.             }
  281.             break;
  282.         case WM_HELP:
  283.             WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, TEXT("display.hlp"), HELP_WM_HELP,
  284.                 (DWORD_PTR)(LPTSTR)aCustFontHelpIds);
  285.             break;
  286.         case WM_CONTEXTMENU:
  287.             WinHelp((HWND)wParam, TEXT("display.hlp"), HELP_CONTEXTMENU,
  288.                 (DWORD_PTR)(LPTSTR)aCustFontHelpIds);
  289.             break;
  290.         case WM_COMMAND:
  291.             switch (LOWORD(wParam))
  292.             {
  293.                 case IDOK:
  294.                     EndDialog(hDlg, GETDPI(g_iCurPercent));
  295.                     break;
  296.                 case IDCANCEL:
  297.                     EndDialog(hDlg, 0);
  298.                     break;
  299.                 case IDC_CUSTOMRULER:
  300.                     switch (HIWORD(wParam))
  301.                     {
  302.                         case DSN_NCCREATE:
  303.                             SetWindowLong((HWND)lParam, GWL_EXSTYLE,
  304.                                     GetWindowLong((HWND)lParam, GWL_EXSTYLE) | WS_EX_WINDOWEDGE);
  305.                             break;
  306.                         case DSN_BEGINDRAG:
  307.                             // Set the focus to the corresponding edit ctl
  308.                             SendMessage(hDlg, WM_NEXTDLGCTL,
  309.                                         (WPARAM)GetDlgItem(hDlg, IDC_CUSTOMCOMBO), 1L);
  310.                             SendMessage((HWND)lParam, DSM_DRAGPOS, 0, (LPARAM)&(g.wStartPos));
  311.                             if ((int)g.wStartPos < g_rcRuler.left)
  312.                             {
  313.                                 g.wStartPos = g_rcRuler.left;
  314.                             }
  315.                             g.wStartPix = g_iCurPercent;
  316.                             break;
  317.                         case DSN_DRAGGING:
  318.                         {
  319.                             UINT wNow, wPix;
  320.                             POINT pt;
  321.                             //wNow = LOWORD(SendMessage((HWND)lParam, DSM_DRAGPOS, 0, 0L));
  322.                             SendMessage((HWND)lParam, DSM_DRAGPOS, 0, (LPARAM)&pt);
  323.                             wNow = pt.x;
  324.                             if ((int)wNow < g_rcRuler.left)
  325.                             {
  326.                                 wNow = g_rcRuler.left;
  327.                             }
  328.                             wPix = LOWORD((DWORD)wNow*g.wStartPix/g.wStartPos);
  329.                             if (wPix < MIN_PERCENT)
  330.                             {
  331.                                 wPix = MIN_PERCENT;
  332.                             }
  333.                             if (wPix > MAX_PERCENT)
  334.                             {
  335.                                 wPix = MAX_PERCENT;
  336.                             }
  337.                             if (wPix != g_iCurPercent)
  338.                             {
  339.                                 CF_ShowNewPercent(hDlg, wPix);
  340.                                 CF_UpdateRuler(hDlg);
  341.                             }
  342.                             break;
  343.                         }
  344.                         case DSN_ENDDRAG:
  345.                             CF_UpdateData(hDlg, 0, UPDATE_COMBO | UPDATE_SAMPLE);
  346.                             break;
  347.                         default:
  348.                             break;
  349.                         }
  350.                     break;
  351.                 case IDC_CUSTOMCOMBO:
  352.                     switch(HIWORD(wParam))
  353.                     {
  354.                         case CBN_SELCHANGE:
  355.                             i = (int)SendDlgItemMessage(hDlg, IDC_CUSTOMCOMBO, CB_GETCURSEL, 0, 0L);
  356.                             if (i != CB_ERR)
  357.                             {
  358.                                 i = LOWORD(SendDlgItemMessage(hDlg, IDC_CUSTOMCOMBO, CB_GETITEMDATA, (WPARAM)i, 0L));
  359.                                 CF_UpdateData(hDlg, (UINT)i, UPDATE_CURPER | UPDATE_SAMPLE | UPDATE_RULER);
  360.                             }
  361.                             break;
  362.                         case CBN_EDITCHANGE:
  363.                             if (g_bTypeTimer)
  364.                             {
  365.                                 KillTimer(hDlg, 13);
  366.                             }
  367.                             g_bTypeTimer = TRUE;
  368.                             SetTimer(hDlg, 13, 500, NULL);
  369.                             break;
  370.                     }
  371.                     break;
  372.                 default:
  373.                         return(FALSE);
  374.             }
  375.             break;
  376.         default:
  377.             return(FALSE);
  378.     }
  379.     return(TRUE);
  380. }