home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 7.ddi / MWHC.007 / 05 < prev    next >
Encoding:
Text File  |  1991-10-23  |  13.4 KB  |  388 lines

  1. /*----------------------------------------
  2.    JUSTIFY.C -- Justified Type Program
  3.                 (c) Charles Petzold, 1990
  4.   ----------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <string.h>
  8. #include "justify.h"
  9.  
  10. typedef struct
  11.      {
  12.      short nNumFaces ;
  13.      char  szFaceNames [MAX_FACES] [LF_FACESIZE] ;
  14.      }
  15.      ENUMFACE, lpFAR *LPENUMFACE ;
  16.  
  17. typedef struct
  18.      {
  19.      short      nNumSizes ;
  20.      short      xLogPixPerInch ;
  21.      short      yLogPixPerInch ;
  22.      LOGFONT    lf [MAX_SIZES] ;
  23.      TEXTMETRIC tm [MAX_SIZES] ;
  24.      }
  25.      ENUMSIZE, lpFAR *LPENUMSIZE ;
  26.  
  27. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
  28.  
  29. #ifdef __HIGHC__
  30. int  FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, LPENUMFACE) ;
  31. int  FAR PASCAL EnumAllSizes (LPLOGFONT, LPTEXTMETRIC, short, LPENUMSIZE) ;
  32. #else
  33. int  FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, ENUMFACE FAR *) ;
  34. int  FAR PASCAL EnumAllSizes (LPLOGFONT, LPTEXTMETRIC, short, ENUMSIZE FAR *) ;
  35. #endif
  36.  
  37. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  38.                     LPSTR lpszCmdLine, int nCmdShow)
  39.      {
  40.      static   char szAppName[] = "Justify" ;
  41.      HWND     hwnd ;
  42.      MSG      msg ;
  43.      WNDCLASS wndclass ;
  44.  
  45.      if (!hPrevInstance) 
  46.           {
  47.           wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC ;
  48.           wndclass.lpfnWndProc   = WndProc ;
  49.           wndclass.cbClsExtra    = 0 ;
  50.           wndclass.cbWndExtra    = 0 ;
  51.           wndclass.hInstance     = hInstance ;
  52.           wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  53.           wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  54.           wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
  55.           wndclass.lpszMenuName  = szAppName ;
  56.           wndclass.lpszClassName = szAppName ;
  57.  
  58.           RegisterClass (&wndclass) ;
  59.           }
  60.      hwnd = CreateWindow (szAppName, "Justified Type",
  61.                           WS_OVERLAPPEDWINDOW,
  62.                           CW_USEDEFAULT, CW_USEDEFAULT,
  63.                           CW_USEDEFAULT, CW_USEDEFAULT,
  64.                           NULL, NULL, hInstance, NULL) ;
  65.  
  66.      ShowWindow (hwnd, nCmdShow) ;
  67.      UpdateWindow (hwnd) ;
  68.  
  69.      while (GetMessage (&msg, NULL, 0, 0))
  70.           {
  71.           TranslateMessage (&msg) ;
  72.           DispatchMessage (&msg) ;
  73.           }
  74.      return msg.wParam ;
  75.      }
  76.  
  77. int FAR PASCAL EnumAllFaces (LPLOGFONT lplf, LPTEXTMETRIC lptm,
  78. #ifdef ORIG
  79.                              short nFontType, ENUMFACE FAR *lpef)
  80. #else
  81.                              short nFontType, LPENUMFACE lpef)
  82. #endif
  83.      {
  84.      if (nFontType & RASTER_FONTTYPE)
  85.           {
  86.           lstrcpy (lpef->szFaceNames[lpef->nNumFaces], lplf->lfFaceName) ;
  87.           if (++lpef->nNumFaces == MAX_FACES)
  88.                return 0 ;
  89.           }
  90.      return 1 ;
  91.      }
  92.  
  93. int FAR PASCAL EnumAllSizes (LPLOGFONT lplf, LPTEXTMETRIC lptm,
  94. #ifdef ORIG
  95.                              short nFontType, ENUMSIZE FAR *lpes)
  96. #else
  97.                              short nFontType, LPENUMSIZE lpes)
  98. #endif
  99.      {
  100.      if (lpes->xLogPixPerInch == lptm->tmDigitizedAspectX &&
  101.          lpes->yLogPixPerInch == lptm->tmDigitizedAspectY)
  102.           {
  103.           lpes->lf [lpes->nNumSizes] = *lplf ;
  104.           lpes->tm [lpes->nNumSizes] = *lptm ;
  105.           if (++lpes->nNumSizes == MAX_SIZES)
  106.                return 0 ;
  107.           }
  108.      return 1 ;
  109.      }
  110.  
  111. short MakeSizeMenu (HWND hwnd, FARPROC lpfnEnumAllSizes,
  112.                     ENUMSIZE *pes, char *szFaceName)
  113.      {
  114.      static LOGFONT lfBlank ;
  115.      char           szBuffer[20] ;
  116.      HDC            hdc ;
  117.      HMENU          hPopup ;
  118.      short          i ;
  119.  
  120.      hdc = GetDC (hwnd) ;
  121.      hPopup = GetSubMenu (GetMenu (hwnd), SIZE_MENU) ;
  122.  
  123.      pes->nNumSizes = 0 ;
  124.      EnumFonts (hdc, szFaceName, lpfnEnumAllSizes, (LPSTR) pes) ;
  125.      ReleaseDC (hwnd, hdc) ;
  126.  
  127.      while (GetMenuItemCount (hPopup) > 0)
  128.           DeleteMenu (hPopup, 0, MF_BYPOSITION) ;
  129.  
  130.      if (pes->nNumSizes)
  131.           for (i = 0 ; i < pes->nNumSizes ; i++)
  132.                {
  133.                wsprintf (szBuffer, "%i  %2d / %2d", i + 1,
  134.                     (pes->tm[i].tmHeight - pes->tm[i].tmInternalLeading + 10)
  135.                                                                         / 20,
  136.                     (pes->tm[i].tmHeight + 10) / 20) ;
  137.                AppendMenu (hPopup, 0, IDM_ISIZE + i, szBuffer) ;
  138.                }
  139.      else           /* no fonts found that match aspect ratio of display */
  140.           {
  141.           pes->lf[0] = lfBlank ;
  142.           strcpy (pes->lf[0].lfFaceName, szFaceName) ;
  143.           AppendMenu (hPopup, 0, IDM_ISIZE, "Default") ;
  144.           }
  145.  
  146.      CheckMenuItem (hPopup, IDM_ISIZE, MF_CHECKED) ;
  147.      return 0 ;
  148.      }
  149.  
  150. void DrawRuler (HDC hdc, POINT ptClient)
  151.      {
  152.      static short nRuleSize [16] = { 360, 72, 144, 72, 216, 72, 144, 72,
  153.                                      288, 72, 144, 72, 216, 72, 144, 72 } ;
  154.      short        i, j ;
  155.  
  156.      MoveTo (hdc, 0,          -360) ;
  157.      LineTo (hdc, ptClient.x, -360) ;
  158.      MoveTo (hdc, -360,          0) ;
  159.      LineTo (hdc, -360, ptClient.y) ;
  160.  
  161.      for (i = 0, j = 0 ; i <= ptClient.x ; i += 1440 / 16, j++)
  162.           {
  163.           MoveTo (hdc, i, -360) ;
  164.           LineTo (hdc, i, -360 - nRuleSize [j % 16]) ;
  165.           }
  166.      for (i = 0, j = 0 ; i <= ptClient.y ; i += 1440 / 16, j++)
  167.           {
  168.           MoveTo (hdc, -360, i) ;
  169.           LineTo (hdc, -360 - nRuleSize [j % 16], i) ;
  170.           }
  171.      }
  172.  
  173. void Justify (HDC hdc, HANDLE hResource, POINT ptClient, short nCurAlign)
  174.      {
  175.      DWORD  dwExtent ;
  176.      LPSTR  lpText, lpBegin, lpEnd ;
  177.      short  i, xStart, yStart, nBreakCount ;
  178.  
  179.      lpText = LockResource (hResource) ;
  180.  
  181.      yStart = 0 ;
  182.      do                            // for each text line
  183.           {
  184.           nBreakCount = 0 ;
  185.           while (*lpText == ' ')   // skip over leading blanks
  186.                lpText++ ;
  187.           lpBegin = lpText ;
  188.  
  189.           do                       // until the line is known
  190.                {
  191.                lpEnd = lpText ;
  192.  
  193.                while (*lpText != '\0' && *lpText++ != ' ') ;
  194.                if (*lpText == '\0')
  195.                     break ;
  196.                                    // for each space, calculate extents
  197.                nBreakCount++ ;
  198.                SetTextJustification (hdc, 0, 0) ;
  199.                dwExtent = GetTextExtent (hdc, lpBegin, lpText - lpBegin - 1) ;
  200.                }
  201.           while (LOWORD (dwExtent) < ptClient.x) ;
  202.  
  203.           nBreakCount-- ;
  204.           while (*(lpEnd - 1) == ' ')   // eliminate trailing blanks
  205.                {
  206.                lpEnd-- ;
  207.                nBreakCount-- ;
  208.                }
  209.  
  210.           if (*lpText == '\0' || nBreakCount <= 0)
  211.                lpEnd = lpText ;
  212.  
  213.           SetTextJustification (hdc, 0, 0) ;
  214.           dwExtent = GetTextExtent (hdc, lpBegin, lpEnd - lpBegin) ;
  215.  
  216.           if (nCurAlign == IDM_LEFT)         // use alignment for xStart
  217.                xStart = 0 ;
  218.  
  219.           else if (nCurAlign == IDM_RIGHT)
  220.                xStart = ptClient.x - LOWORD (dwExtent) ;
  221.  
  222.           else if (nCurAlign == IDM_CENTER)
  223.                xStart = (ptClient.x - LOWORD (dwExtent)) / 2 ;
  224.  
  225.           else
  226.                {
  227.                if (*lpText != '\0' && nBreakCount > 0)
  228.                     SetTextJustification (hdc, ptClient.x - LOWORD (dwExtent),
  229.                                                   nBreakCount) ;
  230.                xStart = 0 ;
  231.                }
  232.  
  233.           TextOut (hdc, xStart, yStart, lpBegin, lpEnd - lpBegin) ;
  234.           yStart += HIWORD (dwExtent) ;
  235.           lpText = lpEnd ;
  236.           }
  237.      while (*lpText && yStart < ptClient.y) ;
  238.  
  239.      GlobalUnlock (hResource) ;
  240.      }
  241.  
  242. long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  243.      {
  244.      static ENUMFACE ef ;
  245.      static ENUMSIZE es ;
  246.      static FARPROC  lpfnEnumAllFaces, lpfnEnumAllSizes ;
  247.      static HANDLE   hResource ;
  248.      static POINT    ptClient ;
  249.      static short    nCurSize, nCurFace, nCurAttr, nCurAlign = IDM_LEFT ;
  250.      HANDLE          hInstance ;
  251.      HDC             hdc ;
  252.      HFONT           hFont ;
  253.      HMENU           hMenu, hPopup ;
  254.      PAINTSTRUCT     ps ;
  255.      short           i ;
  256.  
  257.      switch (message)
  258.           {
  259.           case WM_CREATE:
  260.                hdc = GetDC (hwnd) ;
  261.                es.xLogPixPerInch = GetDeviceCaps (hdc, LOGPIXELSX) ;
  262.                es.yLogPixPerInch = GetDeviceCaps (hdc, LOGPIXELSY) ;
  263.  
  264.                               // Set Map Mode
  265.  
  266.                SetMapMode (hdc, MM_ANISOTROPIC) ;
  267.                SetWindowExt (hdc, 1440, 1440) ;
  268.                SetViewportExt (hdc, es.xLogPixPerInch, es.yLogPixPerInch) ;
  269.                SetWindowOrg (hdc, -720, -720) ;
  270.  
  271.                               // MakeProcInstance for 2 routines
  272.  
  273.                hInstance = ((LPCREATESTRUCT) lParam)-> hInstance ;
  274.                lpfnEnumAllFaces = MakeProcInstance (EnumAllFaces, hInstance) ;
  275.                lpfnEnumAllSizes = MakeProcInstance (EnumAllSizes, hInstance) ;
  276.  
  277.                               // Enumerate the Font Faces
  278.  
  279.                EnumFonts (hdc, NULL, lpfnEnumAllFaces, (LPSTR) &ef) ;
  280.                ReleaseDC (hwnd, hdc) ;
  281.  
  282.                               // Initialize the Menus
  283.  
  284.                hMenu  = GetMenu (hwnd) ;
  285.                hPopup = CreateMenu () ;
  286.  
  287.                for (i = 0 ; i < ef.nNumFaces ; i++) {
  288.                     AppendMenu (hPopup, 0, IDM_IFACE + i, ef.szFaceNames[i]) ;
  289.             }
  290.  
  291.                ModifyMenu (hMenu, IDM_FACE, MF_POPUP, hPopup, "&FaceName") ;
  292.                CheckMenuItem (hMenu, IDM_IFACE, MF_CHECKED) ;
  293.  
  294.                nCurSize = MakeSizeMenu (hwnd, lpfnEnumAllSizes, &es,
  295.                                    ef.szFaceNames [nCurFace]) ;
  296.  
  297.                               // Load the Text Resource
  298.  
  299.                hResource = LoadResource (hInstance, 
  300.                            FindResource (hInstance, "Ismael", "TEXT")) ;
  301.                return 0 ;
  302.  
  303.           case WM_SIZE:
  304.                hdc = GetDC (hwnd) ;
  305.                ptClient = MAKEPOINT (lParam) ;
  306.                DPtoLP (hdc, &ptClient, 1) ;
  307.                ptClient.x -= 360 ;
  308.                ReleaseDC (hwnd, hdc) ;
  309.                return 0 ;
  310.  
  311.           case WM_COMMAND:
  312.                hMenu = GetMenu (hwnd) ;
  313.  
  314.                if (wParam >= IDM_IFACE && wParam < IDM_IFACE + MAX_FACES)
  315.                     {
  316.                     CheckMenuItem (hMenu, nCurFace + IDM_IFACE, MF_UNCHECKED) ;
  317.                     CheckMenuItem (hMenu, wParam, MF_CHECKED) ;
  318.                     nCurFace = wParam - IDM_IFACE ;
  319.  
  320.                     nCurSize = MakeSizeMenu (hwnd, lpfnEnumAllSizes, &es,
  321.                                         ef.szFaceNames [nCurFace]) ;
  322.                     }
  323.  
  324.                else if (wParam >= IDM_ISIZE && wParam < IDM_ISIZE + MAX_SIZES)
  325.                     {
  326.                     CheckMenuItem (hMenu, nCurSize + IDM_ISIZE, MF_UNCHECKED) ;
  327.                     CheckMenuItem (hMenu, wParam, MF_CHECKED) ;
  328.                     nCurSize = wParam - IDM_ISIZE ;
  329.                     }
  330.  
  331.                else switch (wParam)
  332.                     {
  333.                     case IDM_BOLD:
  334.                     case IDM_ITALIC:
  335.                     case IDM_STRIKE:
  336.                     case IDM_UNDER:
  337.                          CheckMenuItem (hMenu, wParam, MF_CHECKED &
  338.                               GetMenuState (hMenu, wParam, MF_BYCOMMAND) ?
  339.                                    MF_UNCHECKED : MF_CHECKED) ;
  340.                          nCurAttr ^= wParam ;
  341.                          break ;
  342.  
  343.                     case IDM_NORM:
  344.                          nCurAttr = 0 ;
  345.                          CheckMenuItem (hMenu, IDM_BOLD,   MF_UNCHECKED) ;
  346.                          CheckMenuItem (hMenu, IDM_ITALIC, MF_UNCHECKED) ;
  347.                          CheckMenuItem (hMenu, IDM_STRIKE, MF_UNCHECKED) ;
  348.                          CheckMenuItem (hMenu, IDM_UNDER,  MF_UNCHECKED) ;
  349.                          break ;
  350.  
  351.                     case IDM_LEFT:
  352.                     case IDM_RIGHT:
  353.                     case IDM_CENTER:
  354.                     case IDM_JUST:
  355.                          CheckMenuItem (hMenu, nCurAlign, MF_UNCHECKED) ;
  356.                          nCurAlign = wParam ;
  357.                          CheckMenuItem (hMenu, nCurAlign, MF_CHECKED) ;
  358.                          break ;
  359.                     }
  360.                InvalidateRect (hwnd, NULL, TRUE) ;
  361.                return 0 ;
  362.  
  363.           case WM_PAINT:
  364.                hdc = BeginPaint (hwnd, &ps) ;
  365.  
  366.                es.lf[nCurSize].lfWeight    = nCurAttr & IDM_BOLD ? 700 : 400 ;
  367.                es.lf[nCurSize].lfItalic    = (BYTE) (nCurAttr & IDM_ITALIC) ;
  368.                es.lf[nCurSize].lfUnderline = (BYTE) (nCurAttr & IDM_UNDER) ;
  369.                es.lf[nCurSize].lfStrikeOut = (BYTE) (nCurAttr & IDM_STRIKE) ;
  370.  
  371.                hFont = CreateFontIndirect (&es.lf[nCurSize]) ;
  372.                hFont = SelectObject (hdc, hFont) ;
  373.  
  374.                DrawRuler (hdc, ptClient) ;
  375.                Justify (hdc, hResource, ptClient, nCurAlign) ;
  376.  
  377.                DeleteObject (SelectObject (hdc, hFont)) ;
  378.                EndPaint (hwnd, &ps) ;
  379.                return 0 ;
  380.  
  381.           case WM_DESTROY:
  382.                FreeResource (hResource) ;
  383.                PostQuitMessage (0) ;
  384.                return 0 ;
  385.           }
  386.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  387.      }
  388.