File:  [OS/2 SDKs] / pmsdk / samples / petzold / chap11 / head.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1988, HEAD
Microsoft OS/2 SDK PM 08-08-1988

/*------------------------------
   HEAD.C -- Displays File Head
  ------------------------------*/

#define INCL_WIN
#define INCL_GPI

#include <os2.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "head.h"

SHORT ParseFileName (CHAR *, CHAR *) ;
MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;

CHAR szFileName [80] ;

int main (int argc, char *argv[])
     {
     static CHAR szClientClass [] = "Head" ;
     HAB         hab ;
     HMQ         hmq ;
     HWND        hwndClient, hwndFrame ;
     QMSG        qmsg ;
     ULONG       flFrameFlags = FCF_STANDARD ;
     ULONG       flFrameStyle = WS_VISIBLE ;

               /*-----------------------------------------------------
                  Check for filename parameter and copy to szFileName
                 -----------------------------------------------------*/

     if (argc > 1)
          ParseFileName (szFileName, argv [1]) ;

               /*-------------------
                  Continue normally
                 -------------------*/
     
     hab = WinInitialize (0) ;
     hmq = WinCreateMsgQueue (hab, 0) ;

     WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;

     hwndFrame = WinCreateStdWindow (HWND_DESKTOP, flFrameStyle,
                                     &flFrameFlags, szClientClass,
                                     szClientClass,
				     0L, NULL, ID_RESOURCE, &hwndClient) ;

     while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
          WinDispatchMsg (hab, &qmsg) ;

     WinDestroyWindow (hwndFrame) ;
     WinDestroyMsgQueue (hmq) ;
     WinTerminate (hab) ;
     return 0 ;
     }

SHORT ParseFileName (CHAR *pcOut, CHAR *pcIn)
     {
          /*----------------------------------------------------------------
             Input:    pcOut -- Pointer to parsed file specification.
                       pcIn  -- Pointer to raw file specification.
                       
             Returns:  0 -- pcIn had invalid drive or directory.
                       1 -- pcIn was empty or had no filename.
                       2 -- pcOut points to drive, full dir, and file name.

             Changes current drive and directory per pcIn string.
            ----------------------------------------------------------------*/

     CHAR   *pcLastSlash, *pcFileOnly ;
     ULONG  ulDriveMap ;
     USHORT usDriveNum, usDirLen = 64 ;

     strupr (pcIn) ;

               /*------------------------------------
                  If input string is empty, return 1
                 ------------------------------------*/

     if (pcIn [0] == '\0')
          return 1 ;

               /*----------------------------------------------
                  Get drive from input string or current drive
                 ----------------------------------------------*/

     if (pcIn [1] == ':')
          {
          if (DosSelectDisk (pcIn [0] - '@'))
               return 0 ;

          pcIn += 2 ;
          }

     DosQCurDisk (&usDriveNum, &ulDriveMap) ;

     *pcOut++ = (CHAR) usDriveNum + '@' ;
     *pcOut++ = ':' ;
     *pcOut++ = '\\' ;

               /*--------------------------------------
                  If rest of string is empty, return 1
                 -------------------------------------*/

     if (pcIn [0] == '\0')
          return 1 ;

               /*----------------------------------------------------------
                  Search for last backslash.  If none, could be directory.
                 ----------------------------------------------------------*/

     if (NULL == (pcLastSlash = strrchr (pcIn, '\\')))
          {
	  if (!DosChDir (pcIn, 0L))
               return 1 ;

                    /*----------------------------------------------------
                       Otherwise, get current dir & attach input filename
                      ----------------------------------------------------*/

          DosQCurDir (0, pcOut, &usDirLen) ;

          if (strlen (pcIn) > 12)
               return 0 ;

          if (*(pcOut + strlen (pcOut) - 1) != '\\')
               strcat (pcOut++, "\\") ;

          strcat (pcOut, pcIn) ;
          return 2 ;
          }

               /*-------------------------------------------------------
                  If the only backslash is at beginning, change to root
                 -------------------------------------------------------*/

     if (pcIn == pcLastSlash)
          {
	  DosChDir ("\\", 0L) ;

          if (pcIn [1] == '\0')
               return 1 ;

          strcpy (pcOut, pcIn + 1) ;
          return 2 ;
          }

               /*------------------------------------------------------
                  Attempt to change directory -- Get current dir if OK
                 ------------------------------------------------------*/

     *pcLastSlash = '\0' ;

     if (DosChDir (pcIn, 0L))
          return 0 ;

     DosQCurDir (0, pcOut, &usDirLen) ;

               /*-------------------------------
                  Append input filename, if any
                 -------------------------------*/

     pcFileOnly = pcLastSlash + 1 ;

     if (*pcFileOnly == '\0')
          return 1 ;

     if (strlen (pcFileOnly) > 12)
          return 0 ;

     if (*(pcOut + strlen (pcOut) - 1) != '\\')
          strcat (pcOut++, "\\") ;

     strcat (pcOut, pcFileOnly) ;
     return 2 ;
     }

VOID FillDirListBox (HWND hwnd, CHAR *pcCurrentPath)
     {
     static CHAR szDrive [] = "  :" ;
     FILEFINDBUF findbuf ;
     HDIR        hDir = 1 ;
     SHORT       sDrive ;
     USHORT      usDriveNum, usCurPathLen, usSearchCount = 1 ;
     ULONG       ulDriveMap ;

     DosQCurDisk (&usDriveNum, &ulDriveMap) ;
     pcCurrentPath [0] = (CHAR) usDriveNum + '@' ;
     pcCurrentPath [1] = ':' ;
     pcCurrentPath [2] = '\\' ;
     usCurPathLen = 64 ;
     DosQCurDir (0, pcCurrentPath + 3, &usCurPathLen) ;

     WinSetWindowText (WinWindowFromID (hwnd, IDD_PATH), pcCurrentPath) ;

     WinSendDlgItemMsg (hwnd, IDD_DIRLIST, LM_DELETEALL, NULL, NULL) ;

     for (sDrive = 0 ; sDrive < 26 ; sDrive++)
          if (ulDriveMap & 1L << sDrive)
               {
               szDrive [1] = (CHAR) sDrive + 'A' ;

               WinSendDlgItemMsg (hwnd, IDD_DIRLIST, LM_INSERTITEM,
                                  MPFROM2SHORT (LIT_END, 0),
                                  MPFROMP (szDrive)) ;
               }

     DosFindFirst ("*.*", &hDir, 0x0017, &findbuf, sizeof findbuf,
                              &usSearchCount, 0L) ;
     while (usSearchCount)
          {
          if (findbuf.attrFile & 0x0010 &&
                    (findbuf.achName [0] != '.' || findbuf.achName [1]))
               
               WinSendDlgItemMsg (hwnd, IDD_DIRLIST, LM_INSERTITEM,
                                  MPFROM2SHORT (LIT_SORTASCENDING, 0),
                                  MPFROMP (findbuf.achName)) ;

          DosFindNext (hDir, &findbuf, sizeof findbuf, &usSearchCount) ;
          }
     }

VOID FillFileListBox (HWND hwnd)
     {
     FILEFINDBUF findbuf ;
     HDIR        hDir = 1 ;
     USHORT      usSearchCount = 1 ;

     WinSendDlgItemMsg (hwnd, IDD_FILELIST, LM_DELETEALL, NULL, NULL) ;

     DosFindFirst ("*.*", &hDir, 0x0007, &findbuf, sizeof findbuf,
                              &usSearchCount, 0L) ;
     while (usSearchCount)
          {
          WinSendDlgItemMsg (hwnd, IDD_FILELIST, LM_INSERTITEM,
                             MPFROM2SHORT (LIT_SORTASCENDING, 0),
                             MPFROMP (findbuf.achName)) ;

          DosFindNext (hDir, &findbuf, sizeof findbuf, &usSearchCount) ;
          }
     }

MRESULT EXPENTRY OpenDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
     {
     static CHAR szCurrentPath [80], szBuffer [80] ;
     SHORT       sSelect ;

     switch (msg)
          {
          case WM_INITDLG:
               FillDirListBox (hwnd, szCurrentPath) ;
               FillFileListBox (hwnd) ;

               WinSendDlgItemMsg (hwnd, IDD_FILEEDIT, EM_SETTEXTLIMIT,
                                        MPFROM2SHORT (80, 0), NULL) ;
               return 0 ;

          case WM_CONTROL:
               if (SHORT1FROMMP (mp1) == IDD_DIRLIST ||
                   SHORT1FROMMP (mp1) == IDD_FILELIST)
                    {
                    sSelect = (USHORT) WinSendDlgItemMsg (hwnd,
                                                  SHORT1FROMMP (mp1),
                                                  LM_QUERYSELECTION, 0L, 0L) ;

                    WinSendDlgItemMsg (hwnd, SHORT1FROMMP (mp1),
                                       LM_QUERYITEMTEXT,
                                       MPFROM2SHORT (sSelect, sizeof szBuffer),
                                       MPFROMP (szBuffer)) ;
                    }

               switch (SHORT1FROMMP (mp1))        /* Control ID */
                    {
                    case IDD_DIRLIST:
                         switch (SHORT2FROMMP (mp1))   /* notification code */
                              {
                              case LN_ENTER:
                                   if (szBuffer [0] == ' ')
                                        DosSelectDisk (szBuffer [1] - '@') ;
                                   else
					DosChDir (szBuffer, 0L) ;

                                   FillDirListBox (hwnd, szCurrentPath) ;
                                   FillFileListBox (hwnd) ;

                                   WinSetDlgItemText (hwnd, IDD_FILEEDIT, "") ;
                                   return 0 ;
                              }
                         break ;

                    case IDD_FILELIST:
                         switch (SHORT2FROMMP (mp1))   /* notification code */
                              {
                              case LN_SELECT:
                                   WinSetDlgItemText (hwnd, IDD_FILEEDIT,
                                                      szBuffer) ;
                                   return 0 ;

                              case LN_ENTER:
                                   ParseFileName (szFileName, szBuffer) ;
                                   WinDismissDlg (hwnd, TRUE) ;
                                   return 0 ;
                              }
                         break ;
                    }
               break ;

          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                    case DID_OK:
                         WinQueryDlgItemText (hwnd, IDD_FILEEDIT,
                                              sizeof szBuffer, szBuffer) ;

                         switch (ParseFileName (szCurrentPath, szBuffer))
                              {
                              case 0:
                                   WinAlarm (HWND_DESKTOP, WA_ERROR) ;
                                   FillDirListBox (hwnd, szCurrentPath) ;
                                   FillFileListBox (hwnd) ;
                                   return 0 ;

                              case 1:
                                   FillDirListBox (hwnd, szCurrentPath) ;
                                   FillFileListBox (hwnd) ;
                                   WinSetDlgItemText (hwnd, IDD_FILEEDIT, "") ;
                                   return 0 ;

                              case 2:
                                   strcpy (szFileName, szCurrentPath) ;
                                   WinDismissDlg (hwnd, TRUE) ;
                                   return 0 ;
                              }
                         break ;

                    case DID_CANCEL:
                         WinDismissDlg (hwnd, FALSE) ;
                         return 0 ;
                    }
               break ;
          }
     return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
     }

MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
     {
     switch (msg)
          {
          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                    case DID_OK:
                    case DID_CANCEL:
                         WinDismissDlg (hwnd, TRUE) ;
                         return 0 ;
                    }
               break ;
          }
     return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
     }

MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
     {
     static CHAR  szErrorMsg [] = "File not found or could not be opened" ;
     static SHORT cxClient, cyClient, cxChar, cyChar, cyDesc ;
     CHAR         *pcReadBuffer ;
     FILE         *fileInput ;
     FONTMETRICS  fm ;
     HPS          hps ;
     POINTL       ptl ;
     SHORT        sLength ;

     switch (msg)
          {
          case WM_CREATE:
               hps = WinGetPS (hwnd) ;
               GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm) ;
               cxChar = (SHORT) fm.lAveCharWidth ;
               cyChar = (SHORT) fm.lMaxBaselineExt ;
               cyDesc = (SHORT) fm.lMaxDescender ;
               WinReleasePS (hps) ;
               return 0 ;
          
          case WM_SIZE:
               cxClient = SHORT1FROMMP (mp2) ;
               cyClient = SHORT2FROMMP (mp2) ;
               return 0 ;

          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                    case IDM_OPEN:
                         if (WinDlgBox (HWND_DESKTOP, hwnd, OpenDlgProc,
                                        NULL, IDD_OPEN, NULL))
                              WinInvalidateRect (hwnd, NULL, FALSE) ;
                         return 0 ;

                    case IDM_ABOUT:
                         WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
                                    NULL, IDD_ABOUT, NULL) ;
                         return 0 ;
                    }
               break ;

          case WM_PAINT:
               hps = WinBeginPaint (hwnd, NULL, NULL) ;

               GpiErase (hps) ;

               if (szFileName [0] != '\0')
                    {
                    ptl.x = cxChar ;
                    ptl.y = cyClient - cyChar + cyDesc ;

                    GpiCharStringAt (hps, &ptl, (LONG) strlen (szFileName),
                                                szFileName) ;
                    ptl.y -= cyChar ;
                                
                    if (fileInput = fopen (szFileName, "r"))
                         {
                         pcReadBuffer = malloc (cxClient / cxChar) ;

                         while ((ptl.y -= cyChar) > 0)
                              {
                              if (NULL == fgets (pcReadBuffer,
                                                 cxClient / cxChar - 2,
                                                 fileInput))
                                   return 0 ;

                              sLength = strlen (pcReadBuffer) ;

                              if (pcReadBuffer [sLength - 1] == '\n')
                                   sLength-- ;

                              if (sLength > 0)
                                   GpiCharStringAt (hps, &ptl, (LONG) sLength,
                                                    pcReadBuffer) ;
                              }
                         free (pcReadBuffer) ;
                         fclose (fileInput) ;
                         }
                    else
                         {
                         ptl.y -= cyChar ;

                         GpiCharStringAt (hps, &ptl,
                                          (LONG) strlen (szErrorMsg),
                                          szErrorMsg) ;
                         }
                    }
               WinEndPaint (hps) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.