home *** CD-ROM | disk | FTP | other *** search
/ Boink! 1995 May/June / Image.bin / musik / midi / tools / cakewalk / wincake.ms_ / wincake.bin
Text File  |  1993-08-22  |  18KB  |  572 lines

  1. '**************************************************************************
  2. '* $Header:   G:/SRC/WCW/MSSETUP/VCS/WINCAKE.MSV   1.20   23 Aug 1993 14:06:06   CP  $
  3. '*
  4. '* DESCRIPTION: MS-Setup script for Wincake and Wcwdemo.
  5. '*
  6. '* $Log:   G:/SRC/WCW/MSSETUP/VCS/WINCAKE.MSV  $
  7. '* 
  8. '*    Rev 1.20   23 Aug 1993 14:06:06   CP
  9. '* Default installation directory for Demo is now C:\WCWDEMO to prevent
  10. '* nuking of previous installations.
  11. '* 
  12. '*    Rev 1.19   24 May 1993 17:09:22   gwh
  13. '* Removed serial number item from user info prompt.
  14. '* 
  15. '*    Rev 1.18   18 Apr 1993 17:50:40   gwh
  16. '* More refinements for user name, organization, serial number stamping.
  17. '* 
  18. '*    Rev 1.17   01 Apr 1993 18:32:44   gwh
  19. '* Prompt user for Name, Organization, and Serial number.
  20. '* Stamp the .EXE resources for these items.
  21. '* 
  22. '*    Rev 1.16   18 Mar 1993 14:06:42   pws
  23. '* No more need to clean up old DLL's in Windows sys dir (or TTSSEQ.INI).
  24. '* Also check for existence of TTSSEQ.INI in install dir before copying
  25. '* any TTSSEQ.INI found in Windows sys dir before copying new files.
  26. '* 
  27. '*    Rev 1.15   05 Mar 1993 12:08:38   pws
  28. '* Fix support for multiple-disk installations, which had broken when
  29. '* we started determining which product we were by testing for the
  30. '* existence of name.EXE on the first diskette but it had been put
  31. '* on the second one.  Now determine which product we are by testing
  32. '* for existence of product-specific section in SETUP.INF file.
  33. '* 
  34. '*    Rev 1.14   22 Dec 1992 13:17:36   pws
  35. '* Reflect changed dialog id's in BLDCUI\DIALOGS.H.
  36. '* 
  37. '*    Rev 1.13   15 Dec 1992 14:47:18   pws
  38. '* Added CTL3D.DLL.
  39. '* 
  40. '*    Rev 1.12   10 Nov 1992 12:37:56   pws
  41. '* Made more dialogs product-specific.
  42. '* 
  43. '* ---
  44. '* See logfile for earlier revision comments
  45. '*
  46. '* Copyright (C) 1990- by Greg Hendershott.  All rights reserved.
  47. '**************************************************************************
  48.  
  49. '$INCLUDE 'setupapi.inc'
  50. '$INCLUDE 'msdetect.inc'
  51. '$INCLUDE 'msregdb.inc'
  52.  
  53. ''These should have all been in SETUPAPI.INC.
  54. ''Note that duplicate definitions are errors and so are commented out!
  55.  
  56. 'CONST MB_OK               = &H0000
  57. CONST MB_OKCANCEL         = &H0001
  58. CONST MB_ABORTRETRYIGNORE = &H0002
  59. CONST MB_YESNOCANCEL      = &H0003
  60. CONST MB_YESNO            = &H0004
  61. CONST MB_RETRYCANCEL      = &H0005
  62. CONST MB_TYPEMASK         = &H000F
  63.  
  64. 'CONST MB_ICONHAND         = &H0010
  65. CONST MB_ICONQUESTION     = &H0020
  66. CONST MB_ICONEXCLAMATION  = &H0030
  67. CONST MB_ICONASTERISK     = &H0040
  68. CONST MB_ICONMASK         = &H00F0
  69.  
  70. CONST MB_ICONINFORMATION  = MB_ICONASTERISK
  71. CONST MB_ICONSTOP         = MB_ICONHAND
  72.  
  73. CONST MB_DEFBUTTON1       = &H0000
  74. CONST MB_DEFBUTTON2       = &H0100
  75. CONST MB_DEFBUTTON3       = &H0200
  76. CONST MB_DEFMASK          = &H0F00
  77.  
  78. CONST MB_APPLMODAL        = &H0000
  79. CONST MB_SYSTEMMODAL      = &H1000
  80. 'CONST MB_TASKMODAL        = &H2000
  81.  
  82. CONST MB_NOFOCUS          = &H8000
  83.  
  84. CONST IDOK                = 1
  85. CONST IDCANCEL            = 2
  86. CONST IDABORT             = 3
  87. CONST IDRETRY             = 4
  88. CONST IDIGNORE            = 5
  89. CONST IDYES               = 6
  90. CONST IDNO                = 7
  91.  
  92. ''Dialog ID's
  93. CONST WELCOME_PRO             = 170
  94. CONST WELCOME_DEMO            = 171
  95. CONST WELCOME_LITE            = 172
  96. CONST ASKQUIT                 = 200
  97. CONST DESTPATH                = 300
  98. CONST USERINFO                  = 310
  99. CONST EXITFAILURE             = 400
  100. CONST EXITQUIT_PRO            = 670
  101. CONST EXITQUIT_DEMO           = 671
  102. CONST EXITQUIT_LITE           = 672
  103. CONST EXITSUCCESS_PRO         = 770
  104. CONST EXITSUCCESS_DEMO        = 771
  105. CONST EXITSUCCESS_LITE        = 772
  106. CONST APPHELP_PRO             = 970
  107. CONST APPHELP_DEMO            = 971
  108. CONST APPHELP_LITE            = 972
  109. CONST INI_NOT_OVERWRITTEN     = 1000
  110. CONST PATCHES_NOT_OVERWRITTEN = 1100
  111. CONST BADPATH                 = 6400
  112.  
  113. ''Bitmap ID
  114. CONST LOGO = 1
  115.  
  116. GLOBAL COMPANY$
  117. GLOBAL PROGNAME$
  118. GLOBAL PRODUCTNAME$
  119. GLOBAL DEST$        ''Default destination directory.
  120.  
  121. DECLARE FUNCTION MakePath (szDir$, szFile$) AS STRING
  122. DECLARE SUB MaybeAssociate (szExt$)
  123.  
  124. INIT:
  125.     CUIDLL$ = "mscuistf.dll"            ''Custom user interface dll
  126.     HELPPROC$ = "FHelpDlgProc"          ''Help dialog procedure
  127.     COMPANY$ = "Twelve Tone Systems"
  128.  
  129.     ''Determine full SETUP.INF path+name (same name for all products).
  130.     szInf$ = GetSymbolValue("STF_SRCINFPATH")
  131.     IF szInf$ = "" THEN
  132.         szInf$ = GetSymbolValue("STF_CWDDIR") + "SETUP.INF"
  133.     END IF
  134.     ReadInfFile szInf$
  135.  
  136.     ''Determine which product we are by seeing if specific section name exists.
  137.     IF DoesIniSectionExist(szInf$, "pro") <> 0 THEN
  138.         PROGNAME$ = "WINCAKE"
  139.         PRODUCTNAME$ = "Cakewalk Professional"
  140.         PROGMANGROUPNAME$ = "Cakewalk Professional"
  141.         INIBASENAME$ = "WINCAKE"
  142.         DEST$ = "C:\WINCAKE"
  143.     ELSEIF DoesIniSectionExist(szInf$, "demo") <> 0 THEN
  144.         PROGNAME$ = "WCWDEMO"
  145.         PRODUCTNAME$ = "Cakewalk Professional Demo"
  146.         PROGMANGROUPNAME$ = "Cakewalk Professional"
  147.         INIBASENAME$ = "WINCAKE"
  148.         DEST$ = "C:\WCWDEMO"
  149.     ELSEIF DoesIniSectionExist(szInf$, "lite") <> 0 THEN
  150.         PROGNAME$ = "WCWLITE"
  151.         PRODUCTNAME$ = "Cakewalk Apprentice"
  152.         PROGMANGROUPNAME$ = "Cakewalk Apprentice"
  153.         INIBASENAME$ = "WCWLITE"
  154.         DEST$ = "C:\WCWLITE"
  155.     ELSE
  156.         GOTO ERRQUIT
  157.     END IF
  158.  
  159.     winVerReqd$ = "3.1"
  160.  
  161.     SetBitmap CUIDLL$, LOGO
  162.     SetTitle PRODUCTNAME$ + " Setup"
  163.  
  164.     winVer$ = LTRIM$(STR$(GetWindowsMajorVersion())) + "." + LTRIM$(STR$(GetWindowsMinorVersion()))
  165.     IF winVer$ < winVerReqd$ THEN             ''String sort works
  166.         i% = DoMsgBox("Sorry, but your Windows version is "+winVer$+" and "+PRODUCTNAME$+" requires at least Windows "+winVerReqd$+".", "Setup Message", MB_OK+MB_TASKMODAL+MB_ICONHAND)
  167.         END
  168.     END IF
  169.  
  170.     ''Disk cost list symbols
  171.     FILECOSTS$   = "FileCosts"
  172.     EXTRACOSTS$  = "ExtraCosts"
  173.     STILLNEEDED$ = "StillNeeded"
  174.     FOR i% = 1 TO 26 STEP 1
  175.         AddListItem EXTRACOSTS$, "0"
  176.     NEXT i%
  177.     ''Add extra cost to Windows drive for ini/progman, etc.
  178.     ixWinDrive% = ASC(UCASE$( MID$(GetWindowsDir(), 1, 1) )) - ASC("A") + 1
  179.     ReplaceListItem EXTRACOSTS$, ixWinDrive%, "10240"
  180.  
  181.  
  182. WELCOME:
  183.     IF PROGNAME$ = "WINCAKE" THEN
  184.         dlg% = WELCOME_PRO
  185.         dlghelp% = APPHELP_PRO
  186.     ELSEIF PROGNAME$ = "WCWDEMO" THEN
  187.         dlg% = WELCOME_DEMO
  188.         dlghelp% = APPHELP_DEMO
  189.     ELSEIF PROGNAME$ = "WCWLITE" THEN
  190.         dlg% = WELCOME_LITE
  191.         dlghelp% = APPHELP_LITE
  192.     END IF
  193.     sz$ = UIStartDlg(CUIDLL$, dlg%, "FInfoDlgProc", dlghelp%, HELPPROC$)
  194.     IF sz$ = "CONTINUE" THEN
  195.         UIPop 1
  196.     ELSE
  197.         GOSUB ASKQUIT
  198.         GOTO WELCOME
  199.     END IF
  200.  
  201.  
  202. GETPATH:
  203.     SetSymbolValue "EditTextIn", DEST$
  204.     SetSymbolValue "EditFocus", "END"
  205. GETPATHL1:
  206.     sz$ = UIStartDlg(CUIDLL$, DESTPATH, "FEditDlgProc", dlghelp%, HELPPROC$)
  207.     DEST$ = GetSymbolValue("EditTextOut")
  208.  
  209.     IF sz$ = "CONTINUE" THEN
  210.         IF IsDirWritable(DEST$) = 0 THEN
  211.             GOSUB BADPATH
  212.             GOTO GETPATHL1
  213.         END IF
  214.         UIPop 1
  215.         ixAppDrive% = ASC(UCASE$( MID$(DEST$, 1, 1) )) - ASC("A") + 1
  216.     ELSEIF sz$ = "REACTIVATE" THEN
  217.         GOTO GETPATHL1
  218.     ELSEIF sz$ = "BACK" THEN
  219.         UIPop 1
  220.         GOTO WELCOME
  221.     ELSE
  222.         GOSUB ASKQUIT
  223.         GOTO GETPATH
  224.     END IF
  225.  
  226. ' Install
  227.     GOSUB INSTALL
  228.     IF StillNeed& > 0 THEN
  229.         GOTO GETPATH
  230.     END IF
  231.  
  232. QUIT:
  233.     ON ERROR GOTO ERRQUIT
  234.  
  235.     IF ERR = 0 THEN
  236.         IF PROGNAME$ = "WINCAKE" THEN
  237.             dlg% = EXITSUCCESS_PRO
  238.         ELSEIF PROGNAME$ = "WCWDEMO" THEN
  239.             dlg% = EXITSUCCESS_DEMO
  240.         ELSEIF PROGNAME$ = "WCWLITE" THEN
  241.             dlg% = EXITSUCCESS_LITE
  242.         END IF
  243.     ELSEIF ERR = STFQUIT THEN
  244.         IF PROGNAME$ = "WINCAKE" THEN
  245.             dlg% = EXITQUIT_PRO
  246.         ELSEIF PROGNAME$ = "WCWDEMO" THEN
  247.             dlg% = EXITQUIT_DEMO
  248.         ELSEIF PROGNAME$ = "WCWLITE" THEN
  249.             dlg% = EXITQUIT_LITE
  250.         END IF
  251.     ELSE
  252.         dlg% = EXITFAILURE
  253.     END IF
  254. QUITL1:
  255.     sz$ = UIStartDlg(CUIDLL$, dlg%, "FInfo0DlgProc", 0, "")
  256.     IF sz$ = "REACTIVATE" THEN
  257.         GOTO QUITL1
  258.     END IF
  259.     UIPop 1
  260.  
  261.     END
  262.  
  263. ERRQUIT:
  264.     i% = DoMsgBox("Installation failure.  Call " + COMPANY$ + " Technical Support", "Setup Message", MB_OK+MB_TASKMODAL+MB_ICONHAND)
  265.     END
  266.  
  267.  
  268.  
  269. BADPATH:
  270.     sz$ = UIStartDlg(CUIDLL$, BADPATH, "FInfo0DlgProc", 0, "")
  271.     IF sz$ = "REACTIVATE" THEN
  272.         GOTO BADPATH
  273.     END IF
  274.     UIPop 1
  275.     RETURN
  276.  
  277.  
  278.  
  279. ASKQUIT:
  280.     sz$ = UIStartDlg(CUIDLL$, ASKQUIT, "FQuitDlgProc", 0, "")
  281.  
  282.     IF sz$ = "EXIT" THEN
  283.         UIPopAll
  284.         ERROR STFQUIT
  285.     ELSEIF sz$ = "REACTIVATE" THEN
  286.         GOTO ASKQUIT
  287.     ELSE
  288.         UIPop 1
  289.     END IF
  290.     RETURN
  291.  
  292.  
  293.  
  294. '**
  295. '** Purpose:
  296. '**     Builds the copy list and performs all installation operations.
  297. '** Arguments:
  298. '**     none.
  299. '** Returns:
  300. '**     none.
  301. '*************************************************************************
  302. INSTALL:
  303.  
  304.     ' Get user information; we'll stamp later.
  305.     GOSUB DOUSERINFODIALOG
  306.  
  307.     SrcDir$ = GetSymbolValue("STF_SRCDIR")
  308.  
  309.     AddSectionFilesToCopyList "app", SrcDir$, DEST$
  310.     IF PROGNAME$ = "WINCAKE" THEN
  311.         AddSectionFilesToCopyList "pro", SrcDir$, DEST$
  312.     ELSEIF PROGNAME$ = "WCWDEMO" THEN
  313.         AddSectionFilesToCopyList "demo", SrcDir$, DEST$
  314.     ELSEIF PROGNAME$ = "WCWLITE" THEN
  315.         AddSectionFilesToCopyList "lite", SrcDir$, DEST$
  316.     END IF
  317.     AddSectionFilesToCopyList "appdlls", SrcDir$, DEST$
  318.     AddSectionFilesToCopyList "system", SrcDir$, GetWindowsSysDir()
  319.  
  320.     StillNeed& = GetCopyListCost(EXTRACOSTS$, FILECOSTS$, STILLNEEDED$)
  321.     IF StillNeed& > 0 THEN
  322.         ClearCopyList
  323.         FOR ix% = 1 TO 26 STEP 1              ''find first drive that needs space
  324.             need1& = VAL(GetListItem(STILLNEEDED$, ix%))
  325.             IF need1& > 0 THEN
  326.                 GOTO FNDDRV
  327.             END IF
  328.         NEXT ix%
  329.         ix = ixAppDrive                       ''(shouldn't happen)
  330.         need1& = 0
  331.         StillNeed& = 1
  332. FNDDRV:
  333.         need$  = LTRIM$(STR$( (need1&+1023) / 1024 )) + "K bytes"
  334.         cost$  = LTRIM$(STR$( (VAL(GetListItem(FILECOSTS$, ix%))+1023) / 1024 )) + "K"
  335.         drive$ = CHR$(ix% - 1 + ASC("A")) + ":"
  336.         msg$ = "Sorry, "+PRODUCTNAME$+" needs "+need$+" more ("+cost$+" total) on drive "+drive$+".  Clear space or try a new path."
  337.         i% = DoMsgBox(msg$, "Setup Problem", MB_RETRYCANCEL+MB_TASKMODAL+MB_ICONHAND)
  338.         IF i% = IDCANCEL THEN
  339.             GOSUB ASKQUIT
  340.         END IF
  341.         RETURN          ''must RETURN out of GOSUB to pop stack, not just GOTO
  342.     END IF
  343.  
  344.     CreateDir DEST$, cmoNone
  345.  
  346.     OpenLogFile MakePath(DEST$, "LOGFILE.OUT"), 0
  347.     WriteToLogFile ""
  348.     WriteToLogFile "User chose as destination directory: '" + DEST$ + "'"
  349.     WriteToLogFile "May have had to create the directory: " + DEST$
  350.     WriteToLogFile ""
  351.  
  352.     CopyFilesInCopyList
  353.  
  354.     ' Important: Do this here before any dialogs with an Exit button, so
  355.     ' user cannot avoid stamping.
  356.     GOSUB STAMPUSERINFO
  357.  
  358.     SetRegKeyValue PROGNAME$, PRODUCTNAME$
  359.     SetRegKeyValue PROGNAME$+"\shell\print", ""
  360.     SetRegKeyValue PROGNAME$+"\shell\open\command", MakePath(DEST$,PROGNAME$+".EXE") + " %1"
  361.     MaybeAssociate "wrk"
  362.     MaybeAssociate "mid"
  363.     MaybeAssociate "mff"
  364.  
  365. ''Deal with old installation where our app DLL's were in WINDOWS\SYSTEM.
  366. ''No more need to delete old DLL's, since we don't use any with same name now.
  367. ''If old TTSSEQ.INI exists in sysdir but not in appdir, copy it now to preserve settings.
  368.     SysDir$ = GetWindowsSysDir()
  369.     IF DoesFileExist(SysDir$+"TTSSEQ.INI",femExists) <> 0 AND DoesFileExist(DEST$+"TTSSEQ.INI",femExists) = 0 THEN
  370.         CopyFile SysDir$+"TTSSEQ.INI", DEST$+"\TTSSEQ.INI", cmoNone, 0
  371.     END IF
  372.  
  373.     IF PROGNAME$ <> "WCWLITE" THEN
  374.         ini$ = MakePath(DEST$, INIBASENAME$+".INI")
  375.         drm$ = MakePath(DEST$, "DRM.INI")
  376.         IF DoesFileExist(ini$,femExists) = 0 THEN
  377.             CopyFile drm$, ini$, cmoVital, 0
  378.         ELSE
  379.             sz$ = UIStartDlg(CUIDLL$, INI_NOT_OVERWRITTEN, "FInfoDlgProc", 0, "")
  380.             IF sz$ = "EXIT" THEN
  381.                 GOSUB ASKQUIT
  382.             ELSE
  383.                 UIPop 1
  384.             END IF
  385.         END IF
  386.     END IF
  387.  
  388.     patches$ = MakePath(DEST$, "PATCHES.INI")
  389.     pat$ = MakePath(DEST$, "PAT.INI")
  390.     IF DoesFileExist(patches$,femExists) = 0 THEN
  391.         CopyFile pat$, patches$, cmoVital, 0
  392.     ELSE
  393.         sz$ = UIStartDlg(CUIDLL$, PATCHES_NOT_OVERWRITTEN, "FInfoDlgProc", 0, "")
  394.         IF sz$ = "EXIT" THEN
  395.             GOSUB ASKQUIT
  396.         ELSE
  397.             UIPop 1
  398.         END IF
  399.     END IF
  400.  
  401.     CreateProgmanGroup PROGMANGROUPNAME$, "", cmoNone
  402.     ShowProgmanGroup  PROGMANGROUPNAME$, 1, cmoNone
  403.     CreateProgmanItem PROGMANGROUPNAME$, PRODUCTNAME$, MakePath(DEST$,PROGNAME$+".EXE"), "", cmoOverwrite
  404.     CreateProgmanItem PROGMANGROUPNAME$, "README.WRI", "write.exe "+MakePath(DEST$,"readme.wri"), "", cmoOverwrite
  405.     WriteToLogFile ""
  406.  
  407.     WriteToLogFile "SUB Install completed."
  408.     CloseLogFile
  409.  
  410.     RETURN
  411.  
  412.  
  413.  
  414. '**
  415. '** Purpose:
  416. '**     Appends a file name to the end of a directory path,
  417. '**     inserting a backslash character as needed.
  418. '** Arguments:
  419. '**     szDir$  - full directory path (with optional ending "\")
  420. '**     szFile$ - filename to append to directory
  421. '** Returns:
  422. '**     Resulting fully qualified path name.
  423. '*************************************************************************
  424. FUNCTION MakePath (szDir$, szFile$) STATIC AS STRING
  425.     IF szDir$ = "" THEN
  426.         MakePath = szFile$
  427.     ELSEIF szFile$ = "" THEN
  428.         MakePath = szDir$
  429.     ELSEIF MID$(szDir$, LEN(szDir$), 1) = "\" THEN
  430.         MakePath = szDir$ + szFile$
  431.     ELSE
  432.         MakePath = szDir$ + "\" + szFile$
  433.     END IF
  434. END FUNCTION
  435.  
  436.  
  437.  
  438. '**
  439. '** Purpose:
  440. '** Arguments:
  441. '** Returns:
  442. '**     none.
  443. '*************************************************************************
  444. DOUSERINFODIALOG:
  445. ' Get user info for stamping later
  446.     IF PROGNAME$ <> "WCWDEMO" THEN
  447. GETUSERINFO:
  448.         sz$ = UIStartDlg(CUIDLL$, USERINFO, "FNameOrgDlgProc", dlghelp%, HELPPROC$)
  449.         IF sz$ = "REACTIVATE" THEN
  450.             GOTO GETUSERINFO
  451.         END IF
  452.  
  453.         szUser$ = GetSymbolValue( "NameOut" )
  454.         szCo$ = GetSymbolValue( "OrgOut" )
  455.     
  456.         ' Company may be blank, but not the other two
  457.         IF szUser$ = "" THEN
  458.             msg$ = "You must supply your name or Setup cannot proceed."
  459.             i% = DoMsgBox(msg$, "Setup Problem", MB_OK+MB_TASKMODAL+MB_ICONHAND)
  460.             GOTO GETUSERINFO
  461.         END IF
  462.  
  463.         ' Dismiss dialog now that we've validated
  464.         UIPop 1
  465.     END IF
  466.  
  467.     RETURN
  468.  
  469.  
  470. '**
  471. '** Purpose:
  472. '** Arguments:
  473. '** Returns:
  474. '**     none.
  475. '*************************************************************************
  476. STAMPUSERINFO:
  477. ' Stamp user info
  478.     IF PROGNAME$ <> "WCWDEMO" THEN
  479.  
  480.         ' szUser$ szCo$ were prompted for above
  481.         szDat$ = CHR$(LEN(szUser$)) + szUser$
  482.         szDat$ = szDat$ + CHR$(LEN(szCo$)) + szCo$
  483.  
  484.         IF PROGNAME$ = "WINCAKE" THEN
  485.             szInfSect$ = "pro"
  486.         ELSEIF PROGNAME$ = "WCWLITE" THEN
  487.             szInfSect$ = "lite"
  488.         END IF
  489.     
  490.         ' 6 is the resource type for STRINGTABLE entries
  491.         '
  492.         ' &H401 is the upper 12 bits of IDS_USERNAME (0x4000) + 1.
  493.         '
  494.         ' In DSKLAYT we specified a reference key for the .EXE which
  495.         ' is the same as PROGNAME$.
  496.         StampResource szInfSect$,PROGNAME$,DEST$,6,&H401,szDat$,LEN(szDat$)
  497.     END IF
  498.  
  499.     RETURN
  500.  
  501.  
  502. '**
  503. '** Purpose:
  504. '**     Associates given filetype with us, but asks for user confirmation
  505. '**     if already set to something else.
  506. '** Arguments:
  507. '**     szExt$ - filetype extension, e.g. "mid"
  508. '** Returns:
  509. '**     none.
  510. '*************************************************************************
  511. SUB MaybeAssociate (szExt$) STATIC
  512.     oldProg$ = ""
  513.     ok% = IDYES
  514.  
  515. 'Check Registration Database (overrides WIN.INI [Extensions]).
  516.  
  517.     oldCmd$ = UCASE$( LTRIM$( GetRegKeyValue("."+szExt$+"\shell\open\command") ) )
  518.     IF oldCmd$ = "" THEN    'didn't find direct association, check via prog name
  519.         oldProg$ = LTRIM$( RTRIM$( GetRegKeyValue("."+szExt$) ) )
  520.         IF oldProg$ <> "" THEN
  521.             oldCmd$ = UCASE$( LTRIM$( GetRegKeyValue(oldProg$+"\shell\open\command") ) )
  522.             oldProduct$ = LTRIM$( RTRIM$( GetRegKeyValue(oldProg$) ) )
  523.             IF oldProduct$ <> "" THEN    'long product name found, use it
  524.                 oldProg$ = oldProduct$
  525.             END IF
  526.         END IF
  527.     END IF
  528.     IF oldCmd$ <> "" THEN
  529.         IF INSTR(oldCmd$, PROGNAME$+".EXE") = 0 THEN    'not us, must confirm
  530.             IF oldProg$ = "" THEN   'no short or long name, parse command string
  531.                 j% = INSTR(oldCmd$, " ")
  532.                 IF j% > 1 THEN
  533.                     oldProg$ = MID$(oldCmd$, 1, j%-1)
  534.                 ELSE
  535.                     oldProg$ = oldCmd$
  536.                 END IF
  537.             END IF
  538.         ELSE                            'it's us, clear oldProg$ => no confirm
  539.             oldProg$ = ""
  540.         END IF
  541.         GOTO MAYBE_CONFIRM      'found association, no need to examine WIN.INI
  542.     END IF
  543.  
  544. 'Check WIN.INI [Extensions].
  545.  
  546.     oldCmd$ = UCASE$( LTRIM$( GetIniKeyString("WIN.INI","Extensions",szExt$) ) )
  547.     IF oldCmd$ <> "" THEN
  548.         IF INSTR(oldCmd$, PROGNAME$+".EXE") = 0 THEN    'not us, must confirm
  549.             j% = INSTR(oldCmd$, " ")
  550.             IF j% > 1 THEN
  551.                 oldProg$ = MID$(oldCmd$, 1, j%-1)
  552.             ELSE
  553.                 oldProg$ = oldCmd$
  554.             END IF
  555.         END IF
  556.     END IF
  557.  
  558. 'Get user confirmation if necessary, and do the association if ok.
  559.  
  560. MAYBE_CONFIRM:
  561.     IF oldProg$ <> "" THEN
  562.         ok% = DoMsgBox("."+UCASE$(szExt$)+" files are currently associated with "+oldProg$+".  Switch association to "+PRODUCTNAME$+"?", "Setup Question", MB_YESNO+MB_TASKMODAL+MB_ICONQUESTION)
  563.     END IF
  564.  
  565.     IF ok% = IDYES THEN
  566.         DeleteRegKey   "."+szExt$       'delete all keys for any old direct association
  567.         SetRegKeyValue "."+szExt$, PROGNAME$
  568.         CreateIniKeyValue "WIN.INI", "Extensions", szExt$, MakePath(DEST$,PROGNAME$+".EXE") + " ^." + szExt$, cmoOverwrite
  569.     END IF
  570.  
  571. END SUB
  572.