home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk11 / petzold / chap14 / head.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-20  |  16.3 KB  |  468 lines

  1. /*------------------------------
  2.    HEAD.C -- Displays File Head
  3.   ------------------------------*/
  4.  
  5. #define INCL_WIN
  6. #define INCL_GPI
  7. #include <os2.h>
  8. #include <malloc.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "easyfont.h"
  12. #include "head.h"
  13.  
  14. #define LCID_FIXEDFONT   1L
  15. #define LCID_BOLDFONT    2L
  16.  
  17. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  18. MRESULT EXPENTRY AboutDlgProc  (HWND, USHORT, MPARAM, MPARAM) ;
  19. MRESULT EXPENTRY OpenDlgProc   (HWND, USHORT, MPARAM, MPARAM) ;
  20. SHORT            ParseFileName (CHAR *, CHAR *) ;
  21.  
  22. CHAR szClientClass [] = "Head" ;
  23. CHAR szFileName [80] ;
  24. HAB  hab ;
  25.  
  26. int main (int argc, char *argv[])
  27.      {
  28.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU  |
  29.                                  FCF_SIZEBORDER    | FCF_MINMAX   |
  30.                                  FCF_SHELLPOSITION | FCF_TASKLIST |
  31.                                  FCF_MENU ;
  32.      HMQ          hmq ;
  33.      HWND         hwndFrame, hwndClient ;
  34.      QMSG         qmsg ;
  35.  
  36.                // Check for filename parameter and copy to szFileName
  37.  
  38.      if (argc > 1)
  39.           ParseFileName (szFileName, argv [1]) ;
  40.  
  41.                // Continue normally
  42.      
  43.      hab = WinInitialize (0) ;
  44.      hmq = WinCreateMsgQueue (hab, 0) ;
  45.  
  46.      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
  47.  
  48.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  49.                                      &flFrameFlags, szClientClass, NULL,
  50.                                      0L, NULL, ID_RESOURCE, &hwndClient) ;
  51.  
  52.      if (hwndFrame != NULL)
  53.           {
  54.           WinSendMsg (hwndFrame, WM_SETICON,
  55.                       WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
  56.                       NULL) ;
  57.  
  58.           while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  59.                WinDispatchMsg (hab, &qmsg) ;
  60.  
  61.           WinDestroyWindow (hwndFrame) ;
  62.           }
  63.      WinDestroyMsgQueue (hmq) ;
  64.      WinTerminate (hab) ;
  65.      return 0 ;
  66.      }
  67.  
  68. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  69.      {
  70.      static CHAR  szErrorMsg [] = "File not found or could not be opened" ;
  71.      static SHORT cxClient, cyClient, cxChar, cyChar, cyDesc ;
  72.      CHAR         *pcReadBuffer ;
  73.      FILE         *fileInput ;
  74.      FONTMETRICS  fm ;
  75.      HPS          hps ;
  76.      POINTL       ptl ;
  77.      SHORT        sLength ;
  78.  
  79.      switch (msg)
  80.           {
  81.           case WM_CREATE:
  82.                hps = WinGetPS (hwnd) ;
  83.                EzfQueryFonts (hps) ;
  84.  
  85.                if (!EzfCreateLogFont (hps, LCID_FIXEDFONT, FONTFACE_COUR,
  86.                                                            FONTSIZE_10, 0))
  87.                     {
  88.                     WinReleasePS (hps) ;
  89.  
  90.                     WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  91.                          "Cannot find a fixed-pitch font.  Load the Courier "
  92.                          "fonts from the Control Panel and try again.",
  93.                          szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;
  94.  
  95.                     return 1 ;
  96.                     }
  97.                GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm) ;
  98.                cxChar = (SHORT) fm.lAveCharWidth ;
  99.                cyChar = (SHORT) fm.lMaxBaselineExt ;
  100.                cyDesc = (SHORT) fm.lMaxDescender ;
  101.  
  102.                GpiSetCharSet (hps, LCID_DEFAULT) ;
  103.                GpiDeleteSetId (hps, LCID_FIXEDFONT) ;
  104.                WinReleasePS (hps) ;
  105.                return 0 ;
  106.           
  107.           case WM_SIZE:
  108.                cxClient = SHORT1FROMMP (mp2) ;
  109.                cyClient = SHORT2FROMMP (mp2) ;
  110.                return 0 ;
  111.  
  112.           case WM_COMMAND:
  113.                switch (COMMANDMSG(&msg)->cmd)
  114.                     {
  115.                     case IDM_OPEN:
  116.                          if (WinDlgBox (HWND_DESKTOP, hwnd, OpenDlgProc,
  117.                                         NULL, IDD_OPEN, NULL))
  118.                               WinInvalidateRect (hwnd, NULL, FALSE) ;
  119.                          return 0 ;
  120.  
  121.                     case IDM_ABOUT:
  122.                          WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
  123.                                     NULL, IDD_ABOUT, NULL) ;
  124.                          return 0 ;
  125.                     }
  126.                break ;
  127.  
  128.           case WM_PAINT:
  129.                hps = WinBeginPaint (hwnd, NULL, NULL) ;
  130.                GpiErase (hps) ;
  131.  
  132.                if (szFileName [0] != '\0')
  133.                     {
  134.                     EzfCreateLogFont (hps, LCID_FIXEDFONT, FONTFACE_COUR,
  135.                                            FONTSIZE_10,    0) ;
  136.                     EzfCreateLogFont (hps, LCID_BOLDFONT,  FONTFACE_COUR,
  137.                                            FONTSIZE_10,    FATTR_SEL_BOLD) ;
  138.  
  139.                     GpiSetCharSet (hps, LCID_BOLDFONT) ;
  140.                     ptl.x = cxChar ;
  141.                     ptl.y = cyClient - cyChar + cyDesc ;
  142.                     GpiCharStringAt (hps, &ptl, (LONG) strlen (szFileName),
  143.                                                 szFileName) ;
  144.                     ptl.y -= cyChar ;
  145.                                 
  146.                     if ((fileInput = fopen (szFileName, "r")) != NULL)
  147.                          {
  148.                          GpiSetCharSet (hps, LCID_FIXEDFONT) ;
  149.                          pcReadBuffer = malloc (cxClient / cxChar) ;
  150.  
  151.                          while ((ptl.y -= cyChar) > 0 &&
  152.                                 fgets (pcReadBuffer, cxClient / cxChar - 2,
  153.                                        fileInput) != NULL)
  154.                               {
  155.                               sLength = strlen (pcReadBuffer) ;
  156.  
  157.                               if (pcReadBuffer [sLength - 1] == '\n')
  158.                                    sLength-- ;
  159.  
  160.                               if (sLength > 0)
  161.                                    GpiCharStringAt (hps, &ptl, (LONG) sLength,
  162.                                                          pcReadBuffer) ;
  163.                               }
  164.                          free (pcReadBuffer) ;
  165.                          fclose (fileInput) ;
  166.                          }
  167.                     else           // file cannot be opened
  168.                          {
  169.                          ptl.y -= cyChar ;
  170.                          GpiCharStringAt (hps, &ptl,
  171.                                           (LONG) strlen (szErrorMsg),
  172.                                           szErrorMsg) ;
  173.                          }
  174.                     GpiSetCharSet (hps, LCID_DEFAULT) ;
  175.                     GpiDeleteSetId (hps, LCID_FIXEDFONT) ;
  176.                     GpiDeleteSetId (hps, LCID_BOLDFONT) ;
  177.                     }
  178.                WinEndPaint (hps) ;
  179.                return 0 ;
  180.           }
  181.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  182.      }
  183.  
  184. MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  185.      {
  186.      switch (msg)
  187.           {
  188.           case WM_COMMAND:
  189.                switch (COMMANDMSG(&msg)->cmd)
  190.                     {
  191.                     case DID_OK:
  192.                     case DID_CANCEL:
  193.                          WinDismissDlg (hwnd, TRUE) ;
  194.                          return 0 ;
  195.                     }
  196.                break ;
  197.           }
  198.      return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
  199.      }
  200.  
  201. VOID FillDirListBox (HWND hwnd, CHAR *pcCurrentPath)
  202.      {
  203.      static CHAR szDrive [] = "  :" ;
  204.      FILEFINDBUF findbuf ;
  205.      HDIR        hDir = 1 ;
  206.      SHORT       sDrive ;
  207.      USHORT      usDriveNum, usCurPathLen, usSearchCount = 1 ;
  208.      ULONG       ulDriveMap ;
  209.  
  210.      DosQCurDisk (&usDriveNum, &ulDriveMap) ;
  211.      pcCurrentPath [0] = (CHAR) usDriveNum + '@' ;
  212.      pcCurrentPath [1] = ':' ;
  213.      pcCurrentPath [2] = '\\' ;
  214.      usCurPathLen = 64 ;
  215.      DosQCurDir (0, pcCurrentPath + 3, &usCurPathLen) ;
  216.  
  217.      WinSetDlgItemText (hwnd, IDD_PATH, pcCurrentPath) ;
  218.      WinSendDlgItemMsg (hwnd, IDD_DIRLIST, LM_DELETEALL, NULL, NULL) ;
  219.  
  220.      for (sDrive = 0 ; sDrive < 26 ; sDrive++)
  221.           if (ulDriveMap & 1L << sDrive)
  222.                {
  223.                szDrive [1] = (CHAR) sDrive + 'A' ;
  224.  
  225.                WinSendDlgItemMsg (hwnd, IDD_DIRLIST, LM_INSERTITEM,
  226.                                   MPFROM2SHORT (LIT_END, 0),
  227.                                   MPFROMP (szDrive)) ;
  228.                }
  229.  
  230.      DosFindFirst ("*.*", &hDir, 0x0017, &findbuf, sizeof findbuf,
  231.                               &usSearchCount, 0L) ;
  232.      while (usSearchCount)
  233.           {
  234.           if (findbuf.attrFile & 0x0010 &&
  235.                     (findbuf.achName [0] != '.' || findbuf.achName [1]))
  236.                
  237.                WinSendDlgItemMsg (hwnd, IDD_DIRLIST, LM_INSERTITEM,
  238.                                   MPFROM2SHORT (LIT_SORTASCENDING, 0),
  239.                                   MPFROMP (findbuf.achName)) ;
  240.  
  241.           DosFindNext (hDir, &findbuf, sizeof findbuf, &usSearchCount) ;
  242.           }
  243.      }
  244.  
  245. VOID FillFileListBox (HWND hwnd)
  246.      {
  247.      FILEFINDBUF findbuf ;
  248.      HDIR        hDir = 1 ;
  249.      USHORT      usSearchCount = 1 ;
  250.  
  251.      WinSendDlgItemMsg (hwnd, IDD_FILELIST, LM_DELETEALL, NULL, NULL) ;
  252.  
  253.      DosFindFirst ("*.*", &hDir, 0x0007, &findbuf, sizeof findbuf,
  254.                               &usSearchCount, 0L) ;
  255.      while (usSearchCount)
  256.           {
  257.           WinSendDlgItemMsg (hwnd, IDD_FILELIST, LM_INSERTITEM,
  258.                              MPFROM2SHORT (LIT_SORTASCENDING, 0),
  259.                              MPFROMP (findbuf.achName)) ;
  260.  
  261.           DosFindNext (hDir, &findbuf, sizeof findbuf, &usSearchCount) ;
  262.           }
  263.      }
  264.  
  265. MRESULT EXPENTRY OpenDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  266.      {
  267.      static CHAR szCurrentPath [80], szBuffer [80] ;
  268.      SHORT       sSelect ;
  269.  
  270.      switch (msg)
  271.           {
  272.           case WM_INITDLG:
  273.                FillDirListBox (hwnd, szCurrentPath) ;
  274.                FillFileListBox (hwnd) ;
  275.  
  276.                WinSendDlgItemMsg (hwnd, IDD_FILEEDIT, EM_SETTEXTLIMIT,
  277.                                         MPFROM2SHORT (80, 0), NULL) ;
  278.                return 0 ;
  279.  
  280.           case WM_CONTROL:
  281.                if (SHORT1FROMMP (mp1) == IDD_DIRLIST ||
  282.                    SHORT1FROMMP (mp1) == IDD_FILELIST)
  283.                     {
  284.                     sSelect = (USHORT) WinSendDlgItemMsg (hwnd,
  285.                                                   SHORT1FROMMP (mp1),
  286.                                                   LM_QUERYSELECTION, 0L, 0L) ;
  287.  
  288.                     WinSendDlgItemMsg (hwnd, SHORT1FROMMP (mp1),
  289.                                        LM_QUERYITEMTEXT,
  290.                                        MPFROM2SHORT (sSelect, sizeof szBuffer),
  291.                                        MPFROMP (szBuffer)) ;
  292.                     }
  293.  
  294.                switch (SHORT1FROMMP (mp1))             // Control ID
  295.                     {
  296.                     case IDD_DIRLIST:
  297.                          switch (SHORT2FROMMP (mp1))   // notification code
  298.                               {
  299.                               case LN_ENTER:
  300.                                    if (szBuffer [0] == ' ')
  301.                                         DosSelectDisk (szBuffer [1] - '@') ;
  302.                                    else
  303.                     DosChDir (szBuffer, 0L) ;
  304.  
  305.                                    FillDirListBox (hwnd, szCurrentPath) ;
  306.                                    FillFileListBox (hwnd) ;
  307.  
  308.                                    WinSetDlgItemText (hwnd, IDD_FILEEDIT, "") ;
  309.                                    return 0 ;
  310.                               }
  311.                          break ;
  312.  
  313.                     case IDD_FILELIST:
  314.                          switch (SHORT2FROMMP (mp1))   // notification code
  315.                               {
  316.                               case LN_SELECT:
  317.                                    WinSetDlgItemText (hwnd, IDD_FILEEDIT,
  318.                                                       szBuffer) ;
  319.                                    return 0 ;
  320.  
  321.                               case LN_ENTER:
  322.                                    ParseFileName (szFileName, szBuffer) ;
  323.                                    WinDismissDlg (hwnd, TRUE) ;
  324.                                    return 0 ;
  325.                               }
  326.                          break ;
  327.                     }
  328.                break ;
  329.  
  330.           case WM_COMMAND:
  331.                switch (COMMANDMSG(&msg)->cmd)
  332.                     {
  333.                     case DID_OK:
  334.                          WinQueryDlgItemText (hwnd, IDD_FILEEDIT,
  335.                                               sizeof szBuffer, szBuffer) ;
  336.  
  337.                          switch (ParseFileName (szCurrentPath, szBuffer))
  338.                               {
  339.                               case 0:
  340.                                    WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  341.                                    FillDirListBox (hwnd, szCurrentPath) ;
  342.                                    FillFileListBox (hwnd) ;
  343.                                    return 0 ;
  344.  
  345.                               case 1:
  346.                                    FillDirListBox (hwnd, szCurrentPath) ;
  347.                                    FillFileListBox (hwnd) ;
  348.                                    WinSetDlgItemText (hwnd, IDD_FILEEDIT, "") ;
  349.                                    return 0 ;
  350.  
  351.                               case 2:
  352.                                    strcpy (szFileName, szCurrentPath) ;
  353.                                    WinDismissDlg (hwnd, TRUE) ;
  354.                                    return 0 ;
  355.                               }
  356.                          break ;
  357.  
  358.                     case DID_CANCEL:
  359.                          WinDismissDlg (hwnd, FALSE) ;
  360.                          return 0 ;
  361.                     }
  362.                break ;
  363.           }
  364.      return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
  365.      }
  366.  
  367. SHORT ParseFileName (CHAR *pcOut, CHAR *pcIn)
  368.      {
  369.           /*----------------------------------------------------------------
  370.              Input:    pcOut -- Pointer to parsed file specification.
  371.                        pcIn  -- Pointer to raw file specification.
  372.                        
  373.              Returns:  0 -- pcIn had invalid drive or directory.
  374.                        1 -- pcIn was empty or had no filename.
  375.                        2 -- pcOut points to drive, full dir, and file name.
  376.  
  377.              Changes current drive and directory per pcIn string.
  378.             ----------------------------------------------------------------*/
  379.  
  380.      CHAR   *pcLastSlash, *pcFileOnly ;
  381.      ULONG  ulDriveMap ;
  382.      USHORT usDriveNum, usDirLen = 64 ;
  383.  
  384.      strupr (pcIn) ;
  385.  
  386.                // If input string is empty, return 1
  387.  
  388.      if (pcIn [0] == '\0')
  389.           return 1 ;
  390.  
  391.                // Get drive from input string or current drive
  392.  
  393.      if (pcIn [1] == ':')
  394.           {
  395.           if (DosSelectDisk (pcIn [0] - '@'))
  396.                return 0 ;
  397.  
  398.           pcIn += 2 ;
  399.           }
  400.      DosQCurDisk (&usDriveNum, &ulDriveMap) ;
  401.  
  402.      *pcOut++ = (CHAR) usDriveNum + '@' ;
  403.      *pcOut++ = ':' ;
  404.      *pcOut++ = '\\' ;
  405.  
  406.                // If rest of string is empty, return 1
  407.  
  408.      if (pcIn [0] == '\0')
  409.           return 1 ;
  410.  
  411.                // Search for last backslash.  If none, could be directory.
  412.  
  413.      if (NULL == (pcLastSlash = strrchr (pcIn, '\\')))
  414.           {
  415.       if (!DosChDir (pcIn, 0L))
  416.                return 1 ;
  417.  
  418.                     // Otherwise, get current dir & attach input filename
  419.  
  420.           DosQCurDir (0, pcOut, &usDirLen) ;
  421.  
  422.           if (strlen (pcIn) > 12)
  423.                return 0 ;
  424.  
  425.           if (*(pcOut + strlen (pcOut) - 1) != '\\')
  426.                strcat (pcOut++, "\\") ;
  427.  
  428.           strcat (pcOut, pcIn) ;
  429.           return 2 ;
  430.           }
  431.                // If the only backslash is at beginning, change to root
  432.  
  433.      if (pcIn == pcLastSlash)
  434.           {
  435.       DosChDir ("\\", 0L) ;
  436.  
  437.           if (pcIn [1] == '\0')
  438.                return 1 ;
  439.  
  440.           strcpy (pcOut, pcIn + 1) ;
  441.           return 2 ;
  442.           }
  443.                // Attempt to change directory -- Get current dir if OK
  444.  
  445.      *pcLastSlash = '\0' ;
  446.  
  447.      if (DosChDir (pcIn, 0L))
  448.           return 0 ;
  449.  
  450.      DosQCurDir (0, pcOut, &usDirLen) ;
  451.  
  452.                // Append input filename, if any
  453.  
  454.      pcFileOnly = pcLastSlash + 1 ;
  455.  
  456.      if (*pcFileOnly == '\0')
  457.           return 1 ;
  458.  
  459.      if (strlen (pcFileOnly) > 12)
  460.           return 0 ;
  461.  
  462.      if (*(pcOut + strlen (pcOut) - 1) != '\\')
  463.           strcat (pcOut++, "\\") ;
  464.  
  465.      strcat (pcOut, pcFileOnly) ;
  466.      return 2 ;
  467.      }
  468.