home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OS2BAS.ZIP / SETUP.BAS < prev    next >
BASIC Source File  |  1989-09-11  |  33KB  |  848 lines

  1. '***********************************************************
  2. '* Program Name: Setup.BAS
  3. '*
  4. '* Description : Setup provides an easy way for the files
  5. '*               from the BASIC PM Toolkit Supplement to be
  6. '*               copied.  Besides copying the files into the
  7. '*               specified directories, the program also
  8. '*               modifies the PMBC command files and creates
  9. '*               the file, NEW-VARS.SYS, which contains the
  10. '*               values that need to be added to the
  11. '*               environment variables in the user's
  12. '*               CONFIG.SYS.
  13. '*
  14. '*               There are 2 sections of help and an about box.
  15. '*
  16. '*               The directory structure is limited.  All
  17. '*               files must be copied to the same and under
  18. '*               the same base directory.
  19. '*
  20. '*               Errors during copying are not checked
  21. '*               because the SHELL function is used to start
  22. '*               another process.  The user can, however,
  23. '*               check that process.
  24. '*----------------------------------------------------------
  25. '* Program Flow: The program is based on the SKELETON.BAS
  26. '*               program.  Setup gets the PM structure
  27. '*               (module level code and ClientWndProc) from
  28. '*               SKELETON.
  29. '*
  30. '*               Setup is driven from ClientWndProc in the
  31. '*               WMTIMER message.  This section of CWP calls
  32. '*               each of the CopyXxxxDisk routines and
  33. '*               controls the flow using the global variable
  34. '*               SetupStage.
  35. '*
  36. '* Procedures  : The routines in Setup can be divided into
  37. '*               the following groups:
  38. '*
  39. '*    Window Procedures
  40. '*             ClientWndProc     Main window procedure
  41. '*             ClientWndProc1    Dialog procedure for SetDrives/Paths
  42. '*
  43. '*    Setup Routines
  44. '*             CopyMainDisk      Copies main disk
  45. '*             CopyExampleDisk   Copies all example disks
  46. '*             ModifyCmdFiles    Modifies PMBC command files
  47. '*             CreateNewVars     Creates NEW-VARS.SYS
  48. '*
  49. '*    File/Directory Routines
  50. '*             CreateDirs        Create necessary directories
  51. '*             MakeDir           Create specified directory
  52. '*             ValidDrive        Check if drive is "<any letter>:"
  53. '*             ValidDir          Minor check (start "\", no base)
  54. '*             FileExists        Use DosFindFirst to check if file exists
  55. '*             GetDiskName       Returns diskname (from DISKNAME.DAT)
  56. '*
  57. '*    String Routines
  58. '*             Replace           Standard search/replace
  59. '*             FarSADD           MakeLong(VARSEG,SADD) far string pointer
  60. '*
  61. '*    PM Readability Routines
  62. '*             DisplayMessageBox Displays message box (Appl modal)
  63. '*             StartTimer        Starts timer (2 seconds)
  64. '*             StopTimer         Stops timer
  65. '*             SetTitleBar       Sets title bar
  66. '*             DisableMenu       Disables menu
  67. '*             SetCheck          Sets checkbox
  68. '*             ToggleCheck       Changes flag and sets checkbox
  69. '*             QueryDlgText      Returns upper case string
  70. '***********************************************************
  71.  
  72. '*********         Initialization section        ***********
  73.  
  74. REM $INCLUDE: 'Setup.INC'
  75.  
  76. DIM aqmsg AS QMSG
  77.  
  78. '****
  79. '** Global variables:
  80. '**
  81. '** Handles      for Start/StopTimer
  82. '** DrivesPaths  for everything
  83. '** ErrorFlag    for checking directories (set in ON ERROR)
  84. '** SetupStage   for distinguishing the stage of Setup for WMTIMER message
  85. '** InstallFlags for installing optional files
  86.  
  87. COMMON SHARED /Handles/ hab&, hwndClient&
  88. COMMON SHARED /DrivesPaths/ SourceDrive$, DestDrive$, BaseDir$, CmdDir$,_
  89.               LibDir$, IncludeDir$, UtilityDir$, HelpDir$, ExampleDir$
  90. COMMON SHARED /ErrorFlag/  DirError%
  91. COMMON SHARED /SetupStage/ SetupStage%
  92. COMMON SHARED /InstallFlags/ CmdFlag%, HelpFlag%, UtilityFlag%, ExampleFlag%
  93.  
  94. ON ERROR GOTO handle:
  95. flFrameFlags& = FCFTITLEBAR      OR FCFSYSMENU OR _
  96.                 FCFSIZEBORDER    OR FCFMINMAX  OR _
  97.                 FCFSHELLPOSITION OR FCFTASKLIST OR_
  98.                 FCFMENU          OR FCFACCELTABLE OR_
  99.                 FCFICON
  100.  
  101. szClientClass$ = "Setup" + CHR$(0)
  102.  
  103. hab& = WinInitialize(0)
  104. hmq& = WinCreateMsgQueue(hab&, 0)
  105.  
  106. warning$  = "WARNING:" + CHR$(0)
  107. moreinfo$ = "Setup must be run from a hard disk." + STRING$(2,13) +_
  108.             "Because Setup requires that disks be changed "+_
  109.             "and OS/2 can swap segments to disk, it is "+_
  110.             "necessary to run setup from a fixed disk." + STRING$(2,13) +_
  111.             "If you are running Setup from a fixed disk, "+_
  112.             "press OK and continue with Setup." + STRING$(2,13)+_
  113.             "Otherwise, press Cancel, copy SETUP.EXE to "+_
  114.             "a fixed disk, and run Setup again." + CHR$(0)
  115.  
  116. bool% = DisplayMessageBox(moreinfo$, warning$, MBOKCANCEL OR MBICONEXCLAMATION)
  117.  
  118. IF bool% = MBIDOK THEN
  119.  
  120.    bool% = WinRegisterClass(hab&, FarSADD(szClientClass$), RegBas, 0, 0)
  121.  
  122.    hwndFrame& = WinCreateStdWindow (HWNDDESKTOP, WSVISIBLE,_
  123.                 MakeLong (VARSEG(flFrameFlags&), VARPTR(flFrameFlags&)),_
  124.                 FarSADD(szClientClass$), 0, 0, 0, IDSETUP,_
  125.                 MakeLong (VARSEG(hwndClient&), VARPTR(hwndClient&)))
  126.  
  127.    '**************         Message loop         ***************
  128.  
  129.    WHILE WinGetMsg(hab&, MakeLong(VARSEG(aqmsg), VARPTR(aqmsg)), 0, 0, 0)
  130.      bool% = WinDispatchMsg(hab&, MakeLong(VARSEG(aqmsg), VARPTR(aqmsg)))
  131.    WEND
  132.  
  133.    '***********         Finalize section        ***************
  134.  
  135.    bool% = WinDestroyWindow(hwndFrame&)
  136. END IF
  137.  
  138. bool% = WinDestroyMsgQueue(hmq&)
  139. bool% = WinTerminate(hab&)
  140.  
  141. END
  142.  
  143. handle:
  144.    SELECT CASE ERR
  145.       CASE 76
  146.          DirError% = -1
  147.          Title$    = "Path/File Access Error" + CHR$(0)
  148.          Caption$  = "Invalid path. Reenter drives/paths." + CHR$(0)
  149.          bool% = DisplayMessageBox(caption$, title$, MBOK OR MBICONEXCLAMATION)
  150.       CASE ELSE
  151.    END SELECT
  152.    RESUME NEXT
  153.  
  154. '***********         Window Procedures        ***************
  155.  
  156. '****
  157. '** ClientWndProc is the main window procedure.
  158. '**
  159. '**  WMCREATE  sets the initial values for global vars and initial title
  160. '**  WMCLOSE   asks user if the want to Quit then does so
  161. '**  WMCOMMAND handles menu options: dialog boxes or start setup with timer
  162. '**  WMHELP    displays the help string in a message box
  163. '**  WMPAINT   loads and draws bitmap to window dimensions
  164. '**  WMTIMER   copies files, etc.
  165. FUNCTION ClientWndProc& (hwnd&, msg%, mp1&, mp2&) STATIC
  166.  
  167.      SHARED szClientClass$
  168.      DIM ClientRect AS RECTL
  169.  
  170.      ClientWndProc& = 0
  171.      SELECT CASE msg%
  172.  
  173.      CASE WMCREATE   'WMCREATE sets initial global vars, local handles and title
  174.  
  175.         SourceDrive$  = "A:"               'Global variables
  176.         DestDrive$    = "C:"
  177.         BaseDir$      = "\PMBASIC"
  178.         CmdDir$       = "\CMD"
  179.         LibDir$       = "\LIB"
  180.         IncludeDir$   = "\INCLUDE"
  181.         HelpDir$      = "\HELP"
  182.         UtilityDir$   = "\UTILITY"
  183.         ExampleDir$   = "\EXAMPLES"
  184.         CmdFlag%      = -1
  185.         HelpFlag%     = -1
  186.         UtilityFlag%  = -1
  187.         ExampleFlag%  = -1
  188.  
  189.         InitTitleBar$ = "BASIC PM Setup" + CHR$(0)              'Set title bar
  190.         CALL SetTitleBar(hwnd&, InitTitleBar$)
  191.  
  192.      CASE WMCLOSE      'WMCLOSE asks if user wants to quit and does so
  193.  
  194.         message$ = "Are you sure you want to QUIT?" + CHR$(0)
  195.         caption$ = " " + CHR$(0)
  196.         IF DisplayMessageBox(message$, caption$,_
  197.            MBYESNO OR MBICONQUESTION) = MBIDYES THEN
  198.            bool% = WinPostMsg(hwnd&, WMQUIT, 0, 0)
  199.         END IF
  200.  
  201.      CASE WMCOMMAND                           'WMCOMMAND processes the menus
  202.  
  203.         CALL BreakLong(mp1&, hiword%, loword%)
  204.         SELECT CASE loword%
  205.  
  206.            CASE IDDRPATH      'IDDRPATH displays dialog processed in CWP1
  207.               bool% = WinDlgBox(HWNDDESKTOP, hwnd&, RegBas1, 0, IDDRPATH, 0)
  208.  
  209.            CASE IDSTART       'IDSTART starts setup with timer (disables menus)
  210.               SetupStage% = 1
  211.               CALL DisableMenu(hwnd&, IDDRPATH, MIADISABLED)
  212.               CALL DisableMenu(hwnd&, IDSTART,  MIADISABLED)
  213.               CALL StartTimer
  214.  
  215.            CASE IDABOUT       'IDABOUT brings up simple dialog (no procedure)
  216.               bool% = WinDlgBox(HWNDDESKTOP, hwnd&, 0, 0, IDABOUT, 0)
  217.  
  218.            CASE ELSE          'Pass control to default (should not get here)
  219.               ClientWndProc& = WinDefWindowProc(hwnd&, msg%, mp1&, mp2&)
  220.         END SELECT
  221.  
  222.      CASE WMHELP              'WMHELP displays help dialog
  223.  
  224.         bool% = WinDlgBox(HWNDDESKTOP, hwnd&, 0, 0, WMHELP, 0)
  225.  
  226.      CASE WMPAINT     'WMPAINT loads and displays bitmap
  227.  
  228.         bool% = WinInvalidateRect(hwnd&, 0, 0)     'inval to redraw full window
  229.         hps&  = WinBeginPaint(hwnd&, 0,_
  230.                 MakeLong(VARSEG(ClientRect), VARPTR(ClientRect)))
  231.         hbmp& = GpiLoadBitmap(hps&, 0, IDBITMAP, 0, 0)
  232.         bool% = WinDrawBitmap(hps&, hbmp&, 0,_
  233.                 MakeLong(VARSEG(ClientRect), VARPTR(ClientRect)),_
  234.                 1, 0, DBMSTRETCH)
  235.         bool% = WinEndPaint(hps&)
  236.  
  237.      CASE WMTIMER     'WMTIMER drives setup. SetupStage shows current state
  238.  
  239.         IF SetupStage% = 1 THEN      'SetupStage=1 copy main disk
  240.            CALL StopTimer
  241.            SetupStage% = -1
  242.            MainTitleBar$ = "BASIC PM Setup:Copying Main Disk" + CHR$(0)
  243.            CALL SetTitleBar(hwnd&, MainTitleBar$)
  244.            CALL CopyMainDisk
  245.            CALL StartTimer
  246.         END IF
  247.  
  248.         IF SetupStage% = -1 THEN     'SetupStage=-1 waiting for main to finish
  249.            fileSpec$ = DestDrive$ + BaseDir$ + "\DISKNAME.DAT"
  250.            IF FileExists(fileSpec$) THEN  'Wait until DISKNAME.DAT is copied
  251.  
  252.               IF ExampleFlag% THEN
  253.                  SetupStage% = 2          'SetupStage=2 for example
  254.               ELSE
  255.                  SetupStage% = 4          'SetupStage=4 for done
  256.               END IF
  257.  
  258.               cmdFile$ = DestDrive$ + BaseDir$ + "\MAINDISK.CMD"
  259.               KILL fileSpec$              'Delete DISKNAME.DAT and MAINDISK.CMD
  260.               KILL cmdFile$
  261.            END IF
  262.         END IF
  263.  
  264.         IF (SetupStage% = 2) OR_           'SetupStage=2 copy 1st Example disk
  265.            (SetupStage% = 3) THEN          'SetupStage=3 copy extra Exam disks
  266.            CALL StopTimer
  267.            IF SetupStage% = 2 THEN         'SetupStage=2 prompt for Disk #2
  268.               Title$ = "Insert Disk" + CHR$(0)
  269.               Caption$ = "Insert (First) EXAMPLE Disk (Disk #2), "+_
  270.                          "then press Enter." + STRING$(2,13) + _
  271.                          "NOTE:Another process will be started in the "+_
  272.                          "foreground to copy the disk.  This process requires " +_
  273.                          "XCOPY.EXE to be in your PATH." + CHR$(0)
  274.  
  275.               flStyle% = MBENTERCANCEL OR MBNOICON
  276.            ELSE                            'SetupStage=3 ask if more disks
  277.               Title$ = "More Disks?" + CHR$(0)
  278.               Caption$ = "This package is designed to be dynamic.  That is, " + _
  279.                          "as more examples become available, additional disks " +_
  280.                          "can easily be added." + STRING$(2,13) +_
  281.                          "If this edition contains additional EXAMPLES disks, " +_
  282.                          "wait for the drive access to stop, insert next disk, " +_
  283.                          "then press Enter." + STRING$(2,13) + _
  284.                          "NOTE:Another process will be started in the "+_
  285.                          "foreground to copy the disk.  This process requires " +_
  286.                          "XCOPY.EXE to be in your PATH." + CHR$(0)
  287.  
  288.               'Default CANCEL for this one
  289.               flStyle% = MBENTERCANCEL OR MBICONQUESTION OR MBDEFBUTTON2
  290.            END IF
  291.         wrong:                            'loop until correct disk
  292.            bool% = DisplayMessageBox(caption$, title$, flStyle%)
  293.            IF bool% = MBIDENTER THEN      'Copy current Example disk
  294.  
  295.               'Check the diskname is correct ("EXAM" 1st example, "MORE" extra)
  296.               IF ((GetDiskName$ <> "EXAM") AND (SetupStage% = 2)) OR_
  297.                  ((GetDiskName$ <> "MORE") AND (SetupStage% = 3)) THEN
  298.                    title$ = "Wrong Disk" + CHR$(0)
  299.                    caption$ = "Please insert correct disk and press Enter." + CHR$(0)
  300.                    flStyle% = MBENTERCANCEL OR MBICONHAND
  301.                    GOTO wrong
  302.               END IF
  303.  
  304.               ExamTitleBar$ = "BASIC PM Setup:Copying Example Disk" + CHR$(0)
  305.               SetupStage% = -2
  306.               CALL SetTitleBar(hwnd&, ExamTitleBar$)
  307.               CALL CopyExampleDisk
  308.               CALL StartTimer
  309.  
  310.            ELSE               'If Disk CANCELed, Setup done (SetupStage=4)
  311.               SetupStage% = 4
  312.            END IF
  313.         END IF
  314.  
  315.         IF SetupStage% = -2 THEN          'SetupStage=-2 wait for disk to copy
  316.  
  317.            fileSpec$ = DestDrive$ + BaseDir$   + "\DISKNAME.DAT"
  318.            IF FileExists(fileSpec$) THEN     'Wait until DISKNAME.DAT is copied
  319.  
  320.               SetupStage% = 3
  321.               cmdFile$ = DestDrive$ + BaseDir$ + ExampleDir$ + "\TREECOPY.CMD"
  322.               diskname$= DestDrive$ + BaseDir$ + ExampleDir$ + "\DISKNAME.DAT"
  323.               KILL fileSpec$              'Delete DISKNAME.DAT and MAINDISK.CMD
  324.               KILL cmdFile$
  325.               KILL diskname$              'extra DISKNAME.DAT from TREECOPY
  326.  
  327.            END IF
  328.  
  329.         END IF
  330.  
  331.         IF SetupStage% = 4 THEN          'SetupStage=4 setup done.
  332.                                          'Stop timer, enable menus, ask to exit
  333.  
  334.            CALL StopTimer
  335.            CALL SetTitleBar(hwnd&, InitTitleBar$)
  336.            CALL DisableMenu(hwnd&, IDDRPATH, 0)
  337.            CALL DisableMenu(hwnd&, IDSTART,  0)
  338.  
  339.            Title$   = "Done" + CHR$(0)
  340.            Caption$ = "SETUP completed.  Exit SETUP?"+ CHR$(0)
  341.            IF DisplayMessageBox%(Caption$, Title$,_
  342.               MBYESNO OR MBICONQUESTION) = MBIDYES THEN
  343.               bool% = WinPostMsg(hwnd&, WMQUIT, 0, 0)
  344.            ELSE
  345.               SetupStage% = 0             'SetupStage=0 idle state
  346.            END IF
  347.         END IF
  348.         bool% = WinReleasePS(hps&)
  349.      CASE ELSE        'Pass control to system for other messages
  350.         ClientWndProc& = WinDefWindowProc(hwnd&, msg%, mp1&, mp2&)
  351.      END SELECT
  352.  
  353. END FUNCTION
  354.  
  355. '****
  356. '** ClientWndProc1 is the dialog procedure for setting drives and paths.
  357. '**       WMINITDLG creates temp variables and sets items accordingly
  358. '**       WMCOMMAND dismisses dialog or gets help
  359. '**         BNOK checks for valid values, assigns if valid and dismisses
  360. '**         BNCANCEL dismisses without changing global variables
  361. '**         BNHELP displays help for the dialog box
  362. '**       WMCONTROL toggles the checkboxes
  363. FUNCTION ClientWndProc1& (hwnd&, msg%, mp1&, mp2&) STATIC
  364.  
  365.    ClientWndProc1& = 0
  366.    SELECT CASE msg%
  367.  
  368.       CASE WMINITDLG          'WMINITDLG creates temp variables and sets items
  369.          TempSourceDrive$ = SourceDrive$ + CHR$(0)
  370.          TempDestDrive$   = DestDrive$   + CHR$(0)
  371.          TempBaseDir$     = BaseDir$     + CHR$(0)
  372.          TempIncludeDir$  = IncludeDir$  + CHR$(0)
  373.          TempLibDir$      = LibDir$      + CHR$(0)
  374.          TempCmdDir$      = CmdDir$      + CHR$(0)
  375.          TempHelpDir$     = HelpDir$     + CHR$(0)
  376.          TempUtilityDir$  = UtilityDir$  + CHR$(0)
  377.          TempExampleDir$  = ExampleDir$  + CHR$(0)
  378.          TempCmdFlag%     = CmdFlag%
  379.          TempHelpFlag%    = HelpFlag%
  380.          TempUtilityFlag% = UtilityFlag%
  381.          TempExampleFlag% = ExampleFlag%
  382.          bool% = WinSetDlgItemText(hwnd&, IDSOURCE,  FarSADD(TempSourceDrive$))
  383.          bool% = WinSetDlgItemText(hwnd&, IDDEST,    FarSADD(TempDestDrive$))
  384.          bool% = WinSetDlgItemText(hwnd&, IDBASE,    FarSADD(TempBaseDir$))
  385.          bool% = WinSetDlgItemText(hwnd&, IDINCLUDE, FarSADD(TempIncludeDir$))
  386.          bool% = WinSetDlgItemText(hwnd&, IDLIB,     FarSADD(TempLibDir$))
  387.          bool% = WinSetDlgItemText(hwnd&, IDCMD,     FarSADD(TempCmdDir$))
  388.          bool% = WinSetDlgItemText(hwnd&, IDHELP,    FarSADD(TempHelpDir$))
  389.          bool% = WinSetDlgItemText(hwnd&, IDUTILITY, FarSADD(TempUtilityDir$))
  390.          bool% = WinSetDlgItemText(hwnd&, IDEXAMPLE, FarSADD(TempExampleDir$))
  391.          CALL SetCheck(hwnd&, IDCMD,     TempCmdFlag%)
  392.          CALL SetCheck(hwnd&, IDHELP,    TempHelpFlag%)
  393.          CALL SetCheck(hwnd&, IDUTILITY, TempUtilityFlag%)
  394.          CALL SetCheck(hwnd&, IDEXAMPLE, TempExampleFlag%)
  395.       CASE WMCOMMAND                'WMCOMMAND dismisses dialog or displays help
  396.  
  397.          CALL BreakLong(mp1&, hiword%, loword%)
  398.          SELECT CASE loword%
  399.             CASE BNOK               'BNOK checks values and assigns if Ok
  400.  
  401.                TempSourceDrive$ = STRING$(256,0)      'Allocate space for query
  402.                TempDestDrive$   = STRING$(256,0)
  403.                TempBaseDir$     = STRING$(256,0)
  404.                TempCmdDir$      = STRING$(256,0)
  405.                TempLibDir$      = STRING$(256,0)
  406.                TempIncludeDir$  = STRING$(256,0)
  407.                TempHelpDir$     = STRING$(256,0)
  408.                TempUtilityDir$  = STRING$(256,0)
  409.                TempExampleDir$  = STRING$(256,0)
  410.  
  411.                'Query dlg text
  412.                CALL QueryDlgText(hwnd&, IDSOURCE,  TempSourceDrive$)
  413.                CALL QueryDlgText(hwnd&, IDDEST,    TempDestDrive$)
  414.                CALL QueryDlgText(hwnd&, IDBASE,    TempBaseDir$)
  415.                CALL QueryDlgText(hwnd&, IDINCLUDE, TempIncludeDir$)
  416.                CALL QueryDlgText(hwnd&, IDLIB,     TempLibDir$)
  417.                CALL QueryDlgText(hwnd&, IDCMD,     TempCmdDir$)
  418.                CALL QueryDlgText(hwnd&, IDHELP,    TempHelpDir$)
  419.                CALL QueryDlgText(hwnd&, IDUTILITY, TempUtilityDir$)
  420.                CALL QueryDlgText(hwnd&, IDEXAMPLE, TempExampleDir$)
  421.  
  422.                'Check drives amd directories
  423.                source%  = ValidDrive(hwnd&, TempSourceDrive$, IDSOURCE)
  424.                dest%    = ValidDrive(hwnd&, TempDestDrive$,   IDDEST)
  425.                basedir% = ValidDir(hwnd&, TempBaseDir$,    BaseDir$,    IDBASE)
  426.                cmd%     = ValidDir(hwnd&, TempCmdDir$,     CmdDir$,     IDINCLUDE)
  427.                lib%     = ValidDir(hwnd&, TempLibDir$,     LibDir$,     IDLIB)
  428.                include% = ValidDir(hwnd&, TempIncludeDir$, IncludeDir$, IDCMD)
  429.                utility% = ValidDir(hwnd&, TempHelpDir$,    HelpDir$,    IDHELP)
  430.                helpdir% = ValidDir(hwnd&, TempUtilityDir$, UtilityDir$, IDUTILITY)
  431.                example% = ValidDir(hwnd&, TempExampleDir$, ExampleDir$, IDEXAMPLE)
  432.                IF source%  AND dest%    AND basedir% AND cmd%     AND_
  433.                   lib%     AND include% AND helpdir% AND example% THEN
  434.                   SourceDrive$ = TempSourceDrive$
  435.                   DestDrive$   = TempDestDrive$
  436.                   BaseDir$     = TempBaseDir$
  437.                   CmdDir$      = TempCmdDir$
  438.                   LibDir$      = TempLibDir$
  439.                   IncludeDir$  = TempIncludeDir$
  440.                   HelpDir$     = TempHelpDir$
  441.                   UtilityDir$  = TempUtilityDir$
  442.                   ExampleDir$  = TempExampleDir$
  443.                   CmdFlag%     = TempCmdFlag%
  444.                   HelpFlag%    = TempHelpFlag%
  445.                   UtilityFlag% = TempUtilityFlag%
  446.                   ExampleFlag% = TempExampleFlag%
  447.                   bool%        = WinDismissDlg(hwnd&, -1)
  448.                END IF
  449.             CASE BNCANCEL            'BNCANCEL dismisses without changing
  450.                bool%    = WinDismissDlg(hwnd&, -1)
  451.             CASE BNHELP              'BNHELP brings up help for the dialog
  452.  
  453.                bool% = WinDlgBox(HWNDDESKTOP, hwnd&, 0, 0, BNHELP, 0)
  454.  
  455.             CASE ELSE
  456.          END SELECT
  457.       CASE WMCONTROL                   'WMCONTROL toggles the checkboxes
  458.          CALL BreakLong(mp1&, hiword%, loword%)
  459.          SELECT CASE loword%
  460.             CASE 26
  461.                CALL ToggleFlag(hwnd&, IDCMD,     TempCmdFlag%)
  462.             CASE 27
  463.                CALL ToggleFlag(hwnd&, IDHELP,    TempHelpFlag%)
  464.             CASE 28
  465.                CALL ToggleFlag(hwnd&, IDUTILITY, TempUtilityFlag%)
  466.             CASE 29
  467.                CALL ToggleFlag(hwnd&, IDEXAMPLE, TempExampleFlag%)
  468.             CASE ELSE
  469.          END SELECT
  470.       CASE ELSE        'Pass control to system for other messages
  471.          ClientWndProc1& = WinDefDlgProc(hwnd&, msg%, mp1&, mp2&)
  472.  
  473.    END SELECT
  474.  
  475. END FUNCTION
  476.  
  477. '****************************************************************
  478. '*
  479. '*                      Setup Routines
  480. '*
  481. '****************************************************************
  482.  
  483. '****
  484. '** CopyMainDisk copies the first disk (labeled "MAIN").
  485. '**
  486. '** The flow is as follows:
  487. '**
  488. '**     1) Prompt user for disk
  489. '**     2) Check for correct disk
  490. '**     3) Create directories
  491. '**     4) Modify PMBC.CMD files
  492. '**     5) Create NewVars.SYS
  493. '**     6) Create MAINDISK.CMD
  494. '**     7) Shell function to start MAINDISK.CMD
  495. SUB CopyMainDisk
  496.  
  497.    '* Prompt user for disk
  498.    Title$   = "Insert Disk" + CHR$(0)
  499.    Caption$ = "Insert MAIN Disk (Disk #1), " +_
  500.               "then press Enter." + STRING$(2,13) + _
  501.               "NOTE: Another process will be started in the "+_
  502.               "background to copy the disk." + CHR$(0)
  503. main:
  504.    bool% = DisplayMessageBox(caption$, title$, MBENTERCANCEL OR MBNOICON)
  505.    IF bool% = MBIDCANCEL THEN
  506.       SetupStage% = 4
  507.       EXIT SUB
  508.    END IF
  509.  
  510.    '* Check for correct disk
  511.    IF GetDiskName$ <> "MAIN" THEN
  512.       title$ = "Wrong Disk" + CHR$(0)
  513.       caption$ = "Please insert correct disk and press Enter." + CHR$(0)
  514.       GOTO main
  515.    END IF
  516.  
  517.    '* Create directories
  518.    CALL CreateDirs
  519.    IF DirError% THEN     'If error, stop setup and exit
  520.       SetupStage% = 4
  521.       EXIT SUB
  522.    END IF
  523.  
  524.    IF CmdFlag% THEN           '* If CmdFlag is chosen, Modify PMBC.CMD files
  525.       CALL ModifyCmdFiles
  526.    END IF
  527.  
  528.    CALL CreateNewVars         '* Create NEW-VARS.SYS
  529.  
  530.    '* Create MAINDISK.CMD
  531.    src$ = SourceDrive$
  532.    dst$ = DestDrive$ + BaseDir$
  533.    cmdFile$ = dst$ + "\MAINDISK.CMD"
  534.  
  535.    OPEN cmdFile$ FOR OUTPUT AS #1
  536.       PRINT #1, "COPY "+src$+"\LIB " + dst$ + LibDir$
  537.       PRINT #1, "COPY "+src$+"\INCLUDE " + dst$ + IncludeDir$
  538.  
  539.       IF HelpFlag% THEN
  540.          PRINT #1, "COPY "+src$+"\HELP " + dst$ + HelpDir$
  541.       END IF
  542.  
  543.       IF UtilityFlag% THEN
  544.          PRINT #1, "COPY "+src$+"\UTILITY " + dst$ + UtilityDir$
  545.       END IF
  546.       PRINT #1, "COPY "+src$+"\SKELETON.* " + dst$ + "\CODE"
  547.       PRINT #1, "COPY "+src$+"\DISKNAME.DAT " + dst$
  548.       PRINT #1, "EXIT"
  549.    CLOSE #1
  550.  
  551.    '* Shell function to start MAINDISK.CMD
  552.    pid% = SHELL("START " + cmdFile$)
  553.  
  554. END SUB
  555.  
  556. '****
  557. '** CopyExampleDisk is used to copy all example disks. It creates TREECOPY.CMD
  558. '** which uses XCOPY (user is warned of this) and uses the Shell function to
  559. '** start the command file in the foreground.
  560. '**
  561. '** The XCOPY command will copy all subdirectories and is thus optimal for
  562. '** copying the example disks, where directory structure can vary.
  563. SUB CopyExampleDisk
  564.       src$ = SourceDrive$
  565.       dst$ = DestDrive$ + BaseDir$ + ExampleDir$
  566.       TreeCopy$ = dst$ + "\TREECOPY.CMD"
  567.       OPEN TreeCopy$ FOR OUTPUT AS #1
  568.          cmdline$ = "XCOPY " + src$ + "\ "+ dst$ + " /s"
  569.          PRINT #1, cmdline$
  570.          cmdline$ = "COPY "+ src$ + "\DISKNAME.DAT "+_
  571.                     DestDrive$ + BaseDir$
  572.          PRINT #1, cmdline$
  573.          PRINT #1, "EXIT"
  574.       CLOSE #1
  575.       cmdline$ = "Start /f " + TreeCopy$
  576.       pid% = SHELL(cmdline$)
  577. END SUB
  578.  
  579. '****
  580. '** ModifyCmdFiles reads the 4 PMBC.CMD files from the Main Disk and
  581. '** modifies (with Replace$) the INCLUDE and CODE directories to the
  582. '** paths set in the dialog box.  The modified files are written to
  583. '** the Cmd directory.
  584. SUB ModifyCmdFiles
  585.    DIM Cmd$(3)
  586.    Cmd$(0) = "\PMBC.CMD"
  587.    Cmd$(1) = "\PMBCD.CMD"
  588.    Cmd$(2) = "\PMBCR.CMD"
  589.    Cmd$(3) = "\PMBCRD.CMD"
  590.  
  591.    src$ = SourceDrive$
  592.    dst$ = DestDrive$ + BaseDir$ + CmdDir$
  593.    inc$ = DestDrive$ + BaseDir$ + IncludeDir$
  594.    cod$ = DestDrive$ + BaseDir$ + "\CODE"
  595.  
  596.    FOR f% = 0 TO 3
  597.       OPEN src$+Cmd$(f%) FOR INPUT AS #1
  598.       OPEN dst$+Cmd$(f%) FOR OUTPUT AS #2
  599.          WHILE NOT(EOF(1))
  600.             LINE INPUT #1, CmdLine$
  601.             CmdLine$ = Replace$(CmdLine$, "C:\PMBASIC\INCLUDE", inc$)
  602.             CmdLine$ = Replace$(CmdLine$, "C:\PMBASIC\CODE",    cod$)
  603.             PRINT #2, CmdLine$
  604.          WEND
  605.       CLOSE #2
  606.       CLOSE #1
  607.    NEXT f%
  608. END SUB
  609.  
  610. '****
  611. '** CreateNewVars writes out a file containing the values which need to
  612. '** be added to the user's CONFIG.SYS
  613. SUB CreateNewVars
  614.    NewVars$ = DestDrive$ + BaseDir$ + "\NEW-VARS.SYS"
  615.    dest$    = DestDrive$
  616.    base$    = BaseDir$
  617.    cmd$     = dest$ + base$ + CmdDir$
  618.    lib$     = dest$ + base$ + LibDir$
  619.    include$ = dest$ + base$ + IncludeDir$
  620.    help$    = dest$ + base$ + HelpDir$
  621.    OPEN NewVars$ FOR OUTPUT AS #1
  622.       PRINT #1, "REM This file contains the values to be added to environment"
  623.       PRINT #1, "REM variables in your CONFIG.SYS"
  624.       PRINT #1,
  625.       PRINT #1, "REM %xx% is the current value for environment variable xx"
  626.       PRINT #1,
  627.       IF CmdFlag% THEN
  628.          PRINT #1, "SET PATH=%PATH%;";cmd$
  629.       END IF
  630.       PRINT #1, "SET LIB=%LIB%;";lib$
  631.       IF HelpFlag% THEN
  632.          PRINT #1, "SET QH=%QH%;";help$
  633.       END IF
  634.       PRINT #1,
  635.       PRINT #1, "REM INCLUDE path not used with BASIC Compiler 6.00"
  636.       PRINT #1, "SET INCLUDE=%INCLUDE%;";include$
  637.    CLOSE #1
  638. END SUB
  639.  
  640. '**********************************************************
  641. '*
  642. '*                 File/Directory Routines
  643. '*
  644. '**********************************************************
  645.  
  646. '****
  647. '** CreateDirs creates each of the directories needed for Setup
  648. SUB CreateDirs
  649.    sBaseDir$ = BaseDir$
  650.    CALL MakeDir(BaseDir$)
  651.    IF DirError% THEN EXIT SUB
  652.    IF CmdFlag% THEN
  653.       CALL MakeDir(sBaseDir$  +  CmdDir$    )
  654.       IF DirError% THEN EXIT SUB
  655.    END IF
  656.    CALL MakeDir(sBaseDir$  +  LibDir$    )
  657.    IF DirError% THEN EXIT SUB
  658.    CALL MakeDir(sBaseDir$  +  IncludeDir$)
  659.    IF DirError% THEN EXIT SUB
  660.    IF HelpFlag% THEN
  661.       CALL MakeDir(sBaseDir$  +  HelpDir$   )
  662.       IF DirError% THEN EXIT SUB
  663.    END IF
  664.    IF UtilityFlag% THEN
  665.       CALL MakeDir(sBaseDir$  +  UtilityDir$)
  666.       IF DirError% THEN EXIT SUB
  667.    END IF
  668.    IF ExampleFlag% THEN
  669.       CALL MakeDir(sBaseDir$  +  ExampleDir$)
  670.       IF DirError% THEN EXIT SUB
  671.    END IF
  672.    CALL MakeDir(sBaseDir$ + "\CODE")
  673. END SUB
  674.  
  675. '****
  676. '** MakeDir resets the error flag and creates the directory.
  677. SUB MakeDir (dir$)
  678.    DirError% = 0
  679.    MKDIR DestDrive$ + dir$
  680. END SUB
  681.  
  682. '****
  683. '** ValidDrive checks to see that the drive could be valid.  It does not
  684. '** check to see if the drive exists, only if it is valid.  This is done
  685. '** by checking the Length = 2, first char is letter, and last char is ":".
  686. FUNCTION ValidDrive%(hwnd&, drive$, id%)
  687.    ValidDrive% = -1
  688.    IF (LEN  (drive$)     = 2)   AND (LEFT$ (drive$, 1) >= "A") AND_
  689.       (LEFT$(drive$, 1) <= "Z") AND (RIGHT$(drive$, 1)  = ":") THEN
  690.       ValidDrive% = -1
  691.    ELSE
  692.       Title$    = "Set Drives/Paths" + CHR$(0)
  693.       Caption$  = "Invalid source drive:  " + drive$ + CHR$(13)+_
  694.                   "Reenter."   + CHR$(0)
  695.       bool%     = DisplayMessageBox(Caption$, Title$, MBOK OR MBICONHAND)
  696.       drive$    = SourceDrive$ + CHR$(0)
  697.       bool%     = WinSetDlgItemText(hwnd&, id%, FarSADD(TempSourcedrive$))
  698.       ValidDrive% = 0
  699.    END IF
  700. END FUNCTION
  701.  
  702. '****
  703. '** ValidDir does some simple checks of the directory name.
  704. '** Directories must begin with a backslash and need not
  705. '** contain the base directory.  Other errors in directory
  706. '** names are caught with ON ERROR.
  707. FUNCTION ValidDir%(hwnd&, new$, old$, id%)
  708.    ValidDir% = -1
  709.    IF LEN  (new$)   =   0  THEN EXIT FUNCTION
  710.    IF LEFT$(new$,1) <> "\" THEN
  711.       Title$    = "Set Drives/Paths" + CHR$(0)
  712.       Caption$  = "Invalid directory:  " +_
  713.                   new$ + STRING$(2,13)+_
  714.                   "Directories must begin with a backslash (\). "+_
  715.                   "Reenter." + CHR$(0)
  716.       bool%     = DisplayMessageBox(Caption$, Title$, MBOK OR MBICONHAND)
  717.       new$      = old$ + CHR$(0)
  718.       bool%     = WinSetDlgItemText(hwnd&, id%, FarSADD(new$))
  719.       ValidDir% = 0
  720.       EXIT FUNCTION
  721.    END IF
  722.    IF (id%<>3) AND INSTR(new$,BaseDir$) THEN
  723.       Title$    = "Set Drives/Paths" + CHR$(0)
  724.       Caption$  = "Invalid directory:  " +_
  725.                   new$ + CHR$(13)+_
  726.                   "Subdirectories do not require repetition of base directory." + CHR$(13)+_
  727.                   "Reenter." + CHR$(0)
  728.       bool%     = DisplayMessageBox(Caption$, Title$, MBOK OR MBICONHAND)
  729.       new$      = old$ + CHR$(0)
  730.       bool%     = WinSetDlgItemText(hwnd&, id%, FarSADD(new$))
  731.       ValidDir% = 0
  732.    END IF
  733. END FUNCTION
  734.  
  735. '****
  736. '** FileExists uses DosFindFirst to see if a file exists.  This is used
  737. '** to check when a process is finished; in which case, Setup will go on
  738. '** to the next disk.
  739. FUNCTION FileExists%(filespec$)
  740.         DIM ffb AS FILEFINDBUF
  741.         temp$ = filespec$ + CHR$(0)
  742.         phdir%= 1
  743.         usBL% = 36
  744.         usSC% = 1
  745.         ulR&  = 0
  746.         att%  = 0 + 2 + 4 + 16    'Normal, hidden, directory and system
  747.         FileExists% = (DosFindFirst(VARSEG(temp$), SADD(temp$),_
  748.                        phdir%, att%, ffb, usBL%, usSC%, ulR&) = 0)
  749. END FUNCTION
  750.  
  751. '****
  752. '** GetDiskName gets the name of the source disk from a file. This is used
  753. '** to check to make sure the correct disk is in the drive.
  754. '**
  755. '** Correct values are:
  756. '**
  757. '**       MAIN
  758. '**       EXAM
  759. '**       MORE
  760. FUNCTION GetDiskName$
  761.    fileName$ = SourceDrive$ + "\DISKNAME.DAT"
  762.    OPEN fileName$ FOR INPUT AS #1
  763.       LINE INPUT #1, temp$
  764.    CLOSE #1
  765.    GetDiskName$ = UCASE$(temp$)
  766. END FUNCTION
  767.  
  768. '**********************************************************
  769. '*
  770. '*                     String Routines
  771. '*
  772. '**********************************************************
  773.  
  774. '****
  775. '** Replace does a standard search and replace. It is used
  776. '** in ModifyCmdFiles.
  777. FUNCTION Replace$ (full$, oldPart$, newPart$)
  778.   Return$ = ""
  779.   temp$ = full$
  780.   DO
  781.     f% = INSTR(Temp$, oldPart$)
  782.     IF f% = 0 THEN
  783.       Return$ = Return$ + temp$
  784.       EXIT DO
  785.     END IF
  786.     Return$ = Return$ + LEFT$(temp$, f% - 1) + newPart$
  787.     temp$ = MID$(temp$, f% + LEN(oldPart$))
  788.   LOOP
  789.   Replace$ = Return$
  790. END FUNCTION
  791.  
  792. '****
  793. '** FarSADD returns the far string address (selector and offset).
  794. '** It is used to make code more readable and smaller.
  795. FUNCTION FarSADD&(s$)
  796.    FarSADD& = MakeLong(VARSEG(s$), SADD(s$))
  797. END FUNCTION
  798.  
  799. '***********************************************************
  800. '*
  801. '*              PM Readability Routines
  802. '*
  803. '*  Each of the following routines performs one simple task
  804. '*  to make main Setup code more readable.  The name of each
  805. '*  function describes what it does.
  806. '***********************************************************
  807.  
  808. FUNCTION DisplayMessageBox%(message$, caption$, flStyle%)
  809.   DisplayMessageBox% = WinMessageBox(HWNDDESKTOP, HWNDDESKTOP,_
  810.                        FarSADD(message$), FarSADD(caption$), 0,_
  811.                        flStyle% OR MBAPPLMODAL)
  812. END FUNCTION
  813.  
  814. SUB StartTimer
  815.    bool% = WinStartTimer(hab&, hwndClient&, 1, 2000)
  816. END SUB
  817.  
  818. SUB StopTimer
  819.    bool% = WinStopTimer(hab&, hwndClient&, 1)
  820. END SUB
  821.  
  822. SUB SetTitleBar(hwnd&, text$)
  823.    hwndParent& = WinQueryWindow  (hwnd&, QWPARENT, 0)
  824.    hwndTitle&  = WinWindowFromID (hwndParent&, FIDTITLEBAR)
  825.    bool%       = WinSetWindowText(hwndTitle&, FarSADD(text$))
  826. END SUB
  827.  
  828. SUB DisableMenu(hwnd&, id%, flag%)
  829.    hwndParent& = WinQueryWindow (hwnd&, QWPARENT, 0)
  830.    hwndMenu&   = WinWindowFromID(hwndParent&, FIDMENU)
  831.    bool%       = WinSendMsg     (hwndMenu&, MMSETITEMATTR,_
  832.                  MakeLong(1, id%), MakeLong(flag%, MIADISABLED))
  833. END SUB
  834.  
  835. SUB SetCheck(hwnd&, id%, flag%)
  836.    bool% = WinSendDlgItemMsg(hwnd&, IDCHECK + id%, BMSETCHECK, flag%, 0)
  837. END SUB
  838.  
  839. SUB ToggleFlag(hwnd&, id%, flag%)
  840.    flag% = NOT(flag%)
  841.    CALL SetCheck(hwnd&, id%, flag%)
  842. END SUB
  843.  
  844. SUB QueryDlgText(hwnd&, id%, text$)
  845.    length% = WinQueryDlgItemText(hwnd&, id%, 256, FarSADD(text$))
  846.    text$ = UCASE$(LEFT$(text$ , length%))
  847. END SUB
  848.