如果要实现完全中文化,必须将_isres.dll和setup.exe替换成中文版的,你使用的InstallShield6应该是英文版的,只带有德、英、日三种语言。该中文版只在InstallShield6 International East中有,价格好象不菲。另外一种方法就是自己动手汉化,找到在_isres.dll中的资源文件,将它进行汉化,生成一个_isuser.dll,放在Setup Files\Compressed Files\0009-English\Intel 32\的目录下,但无法改变setup.exe的汉化问题。另外就是干脆使用自己生成的资源文件作界面,使用自己的界面就可以了,不过setup.exe的汉化问题同样无法解决。可能采用InstallShield5.X Far East版为较好的办法。

解决方案 »

  1.   

    可以用InstallShiled的Script汉化
    如果你修改过MFC的源码,则修改InstallShiled的Script的源码也是一样的。
    用此方法可汉化大部分的英文。
    缺点:无法修改字体、出错框无法汉化。
    效果:在NT下比较好。Win95下一般。(主要是字体问题)
    _Setup.dll应进行二进制修改。
    以下是本人作汉化时的一些Script源码供参考:
    function SetupInstall()
     begin  Enable( CORECOMPONENTHANDLING );  bInstallAborted = FALSE;  listStartCopy = ListCreate(STRINGLIST);  ListAddString( listStartCopy, "您已经选择了瑞软表单全部程序及文档资料,\r\n包括:瑞软表单工厂、表单控件库、支持库、\r\n表单控件及瑞软脚本语言文档资料.", AFTER );  if (bIs32BitSetup) then
          svDir = PROGRAMFILES ^ "Readsoft" ^ @PRODUCT_NAME;
      else
          svDir = PROGRAMFILES ^ "Readsoft" ^ @PRODUCT_NAME16; // use shorten names
      endif;  TARGETDIR  = svDir;  SdProductName( @PRODUCT_NAME );  Enable( DIALOGCACHE );  return 0;
     end;///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function:  SetupScreen                                                    //
    //                                                                           //
    //  Purpose:  This function establishes  the screen look.  This includes     //
    //            colors, fonts, and text to be displayed.                       //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function SetupScreen()
     begin  Enable( FULLWINDOWMODE );
      Enable( INDVFILESTATUS );
      SetTitle( @TITLE_MAIN, 24, WHITE );  SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.  Enable( BACKGROUND );  Delay( 1 );
     end;///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function:  CheckRequirements                                              //
    //                                                                           //
    //  Purpose:  This function checks all minimum requirements for the          //
    //            application being installed.  If any fail, then the user       //
    //            is informed and the setup is terminated.                       //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function CheckRequirements()
        NUMBER  nvDx, nvDy, nvResult;
        STRING  svResult; begin  bWinNT           = FALSE;
      bIsShellExplorer = FALSE;  // Check screen resolution.
      GetExtents( nvDx, nvDy );  if (nvDy < 480) then
          MessageBox( @ERROR_VGARESOLUTION, WARNING );
          abort;
      endif;  // set 'setup' operation mode
      bIs32BitSetup = TRUE;
      GetSystemInfo( ISTYPE, nvResult, svResult );
      if (nvResult = 16) then
          bIs32BitSetup = FALSE; // running 16-bit setup
          return 0; // no additional information required
      endif;  // --- 32-bit testing after this point ---  // Determine the target system's operating system.
      GetSystemInfo( OS, nvResult, svResult );  if (nvResult =  IS_WINDOWSNT) then
          // Running Windows NT.
          bWinNT = TRUE;      // Check to see if the shell being used is EXPLORER shell.
          if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
              if (nvResult >= 4) then
                  bIsShellExplorer = TRUE;
              endif;
          endif;  elseif (nvResult = IS_WINDOWS95 ) then
          bIsShellExplorer = TRUE;  endif;end;
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function: DialogShowSdWelcome                                             //
    //                                                                           //
    //  Purpose: This function handles the standard welcome dialog.              //
    //                                                                           //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function DialogShowSdWelcome()
        NUMBER nResult;
        STRING szTitle, szMsg;
        STRING  szDlg, szTemp;
        NUMBER  nId, nMessage, nTemp;
        HWND    hwndDlg;
        BOOL    bDone;
     begin  szTitle = "欢迎";
      szMsg   = "欢迎使用瑞软表单2.4(中文版)安装程序,本安装程序将在您的机器上安装瑞软表单2.4(中文版)";
      //nResult = SdWelcome( szTitle, szMsg );
        szDlg     = SD_DLG_WELCOME;
        nSdDialog = SD_NDLG_WELCOME;           // record data produced by this dialog
       if (MODE=SILENTMODE) then
       SdMakeName( szAppKey, szDlg, szTitle, nSdWelcome );
       SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
       //return nId;
       endif;
              // ensure general initialization is complete
              if (!bSdInit) then
                 SdInit();
              endif;          if (EzDefineDialog( szDlg, "", "", SD_NDLG_WELCOME ) = DLG_ERR) then
                  return -1;
              endif;          // Loop in dialog until the user selects a standard button
              bDone = FALSE;          while (!bDone)             nId = WaitOnDialog( szDlg );             switch(nId)
                 case DLG_INIT:
                      // Put the corresponding Info in the List Field
                      if( szMsg != "" ) then
                          SdSetStatic(szDlg, SD_STA_MSG, szMsg);
                      endif;
                      SdSetStatic(szDlg,1,"继续");
                      SdSetStatic(szDlg,9,"取消");
                      SdSetStatic(szDlg,720,"在启动安装程序之前,建议您关闭所有Windows程序。");
                      SdSetStatic(szDlg,712,"单击\"取消\"退出安装程序并关闭所有正在运行的程序。");
                      SdSetStatic(szDlg,723,"版权所有(C) 1998-2000, 北京瑞软软件技术公司,\r\n警告:本软件受版权法及国际公约的保护,若未经合法授权而擅自复制此软件的全部或部分将承受严厉的法律责任。");
                      hwndDlg = CmdGetHwndDlg( szDlg );
                      SdGeneralInit( szDlg, hwndDlg, STYLE_NORMAL, szSdProduct );                  if(szTitle != "") then
                           SetWindowText(hwndDlg, szTitle);
                      endif;             case NEXT:
                      nId    = NEXT;
                      bDone  = TRUE;              case BACK:
                       nId    = BACK;
                       bDone  = TRUE;             case DLG_ERR:
                      SdError( -1, "SdWelcome" );
                      nId    = -1;
                      bDone  = TRUE;             case DLG_CLOSE:
                      SdCloseDlg( hwndDlg, nId, bDone );             default:
                      // check standard handling
                       if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
                          bDone = TRUE;
                      endif;
                 endswitch;          endwhile;          EndDialog( szDlg );
              ReleaseDialog( szDlg );          SdUnInit( );          // record data produced by this dialog
              SdMakeName( szAppKey, szDlg, szTitle, nSdWelcome );
              SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );  return nResult;
     end;
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function: DialogShowSdLicense                                             //
    //                                                                           //
    //  Purpose: This function displays the license agreement dialog.            //
    //                                                                           //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function DialogShowSdLicense()
        NUMBER nResult;
        STRING szTitle, szMsg, szQuestion, szLicenseFile;
        STRING  szDlg, szTemp, szFinalFile;
        INT     nId, list, nValue1, nValue2;
        HWND    hwndDlg;
        BOOL    bDone;
     begin  szLicenseFile = SUPPORTDIR ^ "license.txt";
      szTitle    = "许可协议";
      szMsg      ="安装前请仔细阅读下面的许可协议,按Page Down键看下面的部分";//= "欢迎使用瑞软表单";
      szQuestion ="您是否同意上述全部条款?如果不同意,请选择\"不同意\"退出安装程序,要安装瑞软表格你必须同意这些条款。";//= "使用瑞软表单许可协议";
      szDlg     = SD_DLG_LICENSE;
      nSdDialog = SD_NDLG_LICENSE;  // record data produced by this dialog
      if (MODE=SILENTMODE) then
        SdMakeName( szAppKey, szDlg, szTitle, nSdLicense );
        SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
        return nId;
      endif;  // Determine license file location. Check path for UNC or disk id
      szFinalFile = SUPPORTDIR ^ szLicenseFile;
      GetByte( nValue1, szLicenseFile, 0 );
      GetByte( nValue2, szLicenseFile, 1 );
      switch (nValue2)
      case 58: // colon
      if ( ((nValue1 >= 'a') && (nValue1 <= 'z'))  and  and 
         ((nValue1 >= 'A') && (nValue1 <= 'Z')) ) then
         szFinalFile = szLicenseFile; // path contains drive-path-file
      endif;
      case 92: // slash
      if (nValue1 = 92) then
         szFinalFile = szLicenseFile; // path is UNC
      endif;
      endswitch;  // ensure general initialization is complete
      if (!bSdInit) then
        SdInit();
      endif;  if (EzDefineDialog( szDlg, "", "", SD_NDLG_LICENSE) = DLG_ERR) then
         return -1;
      endif;  // Loop in dialog until the user selects a standard button
      bDone = FALSE;
      while (!bDone)
      nId = WaitOnDialog( szDlg );  switch (nId)
         case DLG_INIT:
         if(szMsg != "") then
           SdSetStatic( szDlg, SD_STA_MSG1, szMsg );
         endif;
         if(szQuestion != "") then
            SdSetStatic( szDlg, SD_STA_MSG2, szQuestion );
         endif;
         SdSetStatic(szDlg, 12, "上一步");
         SdSetStatic(szDlg, 6, "我同意");
         SdSetStatic(szDlg, 9, "不同意");
         hwndDlg = CmdGetHwndDlg( szDlg );
         SdGeneralInit( szDlg, hwndDlg, 0, szSdProduct );     if(szTitle != "") then
            SetWindowText( hwndDlg, szTitle );
         endif;     // set agreement multi-line edit field
         list = ListCreate( STRINGLIST );
         if (!ListReadFromFile( list, szFinalFile )) then
            CtrlSetMLEText( szDlg, SD_MULTEDIT_FIELD1, list );
         endif;
         ListDestroy( list );     case SD_PBUT_CONTINUE:
            nId   = NEXT;
            bDone = TRUE;     case SD_PBUT_YES:
            nId   = YES;
            bDone = TRUE;
         case BACK:
            nId    = BACK;
            bDone  = TRUE;
         case DLG_ERR:
            SdError( -1, szDlg );
            nId   = -1;
            bDone = TRUE;
         case DLG_CLOSE:
            SdCloseDlg( hwndDlg, nId, bDone );     default:
         // check standard handling
         if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
            bDone = TRUE;
         endif;
         endswitch;   endwhile;   EndDialog( szDlg );
       ReleaseDialog( szDlg );   SdUnInit();   // record data produced by this dialog
       SdMakeName( szAppKey, szDlg, szTitle, nSdLicense );
       SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );   return nId;
      //nResult    = SdLicense( szTitle, szMsg, szQuestion, szLicenseFile );  return nResult;
     end;
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function: DialogShowSdAskDestPath                                         //
    //                                                                           //
    //  Purpose: This function asks the user for the destination directory.      //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function DialogShowSdAskDestPath()
        NUMBER nResult;
        STRING szTitle, szMsg;
        STRING  szDlg, svDirLoc, szTemp;
              INT     nId, nTemp;
              HWND    hwndDlg;
              BOOL    bDone; begin  szTitle = "选择安装路径";
      szMsg   = "安装程序将在下面的文件夹中安装瑞软表单2.4(中文版)\r\n\r\n如果安装在此文件夹请选\"继续\"\r\n\r\n如果要安装在别的文件夹,单击Browse选择其他文件夹\r\n\r\n如果你选择\"取消\"将退出安装程序。";          szDlg     = SD_DLG_ASKDESTPATH;
              nSdDialog = SD_NDLG_ASKDESTPATH;
              svDirLoc = svDir;          // record data produced by this dialog
              if (MODE=SILENTMODE) then
                SdMakeName( szAppKey, szDlg, szTitle, nSdAskDestPath );
                SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
                if ((nId != BACK) && (nId != CANCEL)) then
                   SilentReadData( szAppKey, "szDir", DATA_STRING, svDir, nTemp );
                endif;            return nId;
              endif;          // ensure general initialization is complete
              if (!bSdInit) then
                 SdInit();
              endif;         if (EzDefineDialog( szDlg, "", "", SD_NDLG_ASKDESTPATH ) = DLG_ERR) then
                return -1;
              endif;          // Loop in dialog until the user selects a standard button
              bDone = FALSE;          while (!bDone)             nId = WaitOnDialog( szDlg );             switch (nId)
                 case DLG_INIT:
                      CtrlSetText( szDlg, 0x80000000  and  SD_STA_DESTDIR, svDirLoc );                  if(szMsg != "") then
                          SdSetStatic( szDlg, SD_STA_CHANGEDIRMSG, szMsg );
                      endif;
                      SdSetStatic(szDlg, 12, "<上一步");
                      SdSetStatic(szDlg, 1, "继续>");
                      SdSetStatic(szDlg, 9, "取消");
                      hwndDlg = CmdGetHwndDlg( szDlg );
                      SdGeneralInit( szDlg, hwndDlg, STYLE_NORMAL, szSdProduct );                  if(szTitle != "") then
                          SetWindowText( hwndDlg, szTitle );
                      endif;             case SD_PBUT_CHANGEDIR:
                      nTemp = MODE;
                      MODE  = NORMALMODE;
                      SelectDir( "",
                                 "",
                                 svDirLoc,
                                 TRUE );
                      CtrlSetText( szDlg, 0x80000000  and  SD_STA_DESTDIR, svDirLoc );
                      MODE = nTemp;             case SD_PBUT_CONTINUE:
                      svDir = svDirLoc;
                      nId   = NEXT;
                      bDone = TRUE;             case BACK:
                      nId    = BACK;
                      bDone  = TRUE;             case DLG_ERR:
                      SdError( -1, "SdAskDestPath" );
                      nId   = -1;
                      bDone = TRUE;             case DLG_CLOSE:
                      SdCloseDlg( hwndDlg, nId, bDone );             default:
                      // check standard handling
                      if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
                          bDone = TRUE;
                      endif;
                 endswitch;          endwhile;          EndDialog( szDlg );
              ReleaseDialog( szDlg );          SdUnInit( );          // record data produced by this dialog
              SdMakeName( szAppKey, szDlg, szTitle, nSdAskDestPath );
              SilentWriteData( szAppKey, "szDir", DATA_STRING, svDir, 0 );
              SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );
              TARGETDIR = svDir;
              return nId;
      //nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );  return nResult;
     end;
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function: DialogShowSdSelectFolder                                        //
    //                                                                           //
    //  Purpose: This function displays the standard folder selection dialog.    //
    //                                                                           //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function DialogShowSdSelectFolder()
        NUMBER nResult;
        STRING szTitle, szMsg;
        STRING  szDlg, szTemp, szGroup, szStr_InvalidFolder, szStr_InvalidFdr_Title;
              NUMBER  nId, nMessage, nTemp, nOS, hIsres;
              HWND    hwndDlg, hwndEdit;
              BOOL    bDone;
     begin  svDefGroup = SHELL_OBJECT_FOLDER;
      if (svDefGroup = "") then
          svDefGroup = @FOLDER_NAME;
      endif;
      szTitle    = "选择程序组";
      szMsg      = "安装程序将增加程序图标到如下的程序组中,你可以输入新的名字,或选择一个已存在的程序组,单击\"继续\"继续安装";           Enable(HOURGLASS);
               szDlg     = SD_DLG_SELECTFOLDER;
               nSdDialog = SD_NDLG_SELECTFOLDER;          // record data produced by this dialog
              if (MODE=SILENTMODE) then
                SdMakeName( szAppKey, szDlg, szTitle, nSdSelectFolder );
                SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
                if ((nId != BACK) && (nId != CANCEL)) then
                   SilentReadData( szAppKey, "szFolder", DATA_STRING, svDefGroup, nTemp );
                endif;
            Disable(HOURGLASS);
                return nId;
              endif;
               // ensure general initialization is complete
               if (!bSdInit) then
                  SdInit();
               endif;           if (EzDefineDialog( szDlg, "", "", SD_NDLG_SELECTFOLDER ) = DLG_ERR) then
               Disable(HOURGLASS);
                   return -1;
               endif;           // Loop in dialog until the user selects a standard button
               bDone = FALSE;           while (!bDone)              nId = WaitOnDialog( szDlg );
                  switch(nId)
                  case DLG_INIT:
                       if( szMsg != "" ) then
                           SdSetStatic(szDlg, SD_STA_MSG, szMsg);
                       endif;
                       SdSetStatic(szDlg, 12, "<上一步");
                       SdSetStatic(szDlg, 1, "继续>");
                       SdSetStatic(szDlg, 9, "取消");
                       szGroup = svDefGroup;                   CtrlSetText( szDlg, SD_EDIT_PROGGRP, szGroup );
                       CtrlPGroups( szDlg, SD_LIST_EXISTGRP );
                       CtrlSetCurSel( szDlg, SD_LIST_EXISTGRP, szGroup );                   hwndDlg = CmdGetHwndDlg( szDlg );
                       SdGeneralInit( szDlg, hwndDlg, STYLE_BOLD, szSdProduct );                   if(szTitle != "") then
                           SetWindowText(hwndDlg, szTitle);
                       endif;                   Disable(HOURGLASS);              case SD_LIST_EXISTGRP:
                       CtrlGetCurSel(szDlg, SD_LIST_EXISTGRP, szGroup );
                       CtrlSetText(szDlg, SD_EDIT_PROGGRP, szGroup );              case NEXT:
                       CtrlGetText(szDlg, SD_EDIT_PROGGRP, szGroup );
                       SdRemoveEndSpace( szGroup );                   if (szGroup = "") then // don't allow null group names
                         MessageBeep(0);
                         hwndEdit = GetDlgItem( hwndDlg, SD_EDIT_PROGGRP );
                         SetFocus( hwndEdit );
                 // don't allow illegal characters (\/:*?"<> and )
                   elseif ((szGroup % "/")  and  and 
                    (szGroup % ":")  and  and 
                    (szGroup % "*")  and  and 
                    (szGroup % "?")  and  and 
                    (szGroup % "\"")  and  and 
                    (szGroup % "<")  and  and 
                    (szGroup % ">")  and  and 
                    (szGroup % " and ") && SdIsShellExplorer() ) then
                   MessageBeep(0);
                   // Load String
                   hIsres = GetModuleHandle( ISRES );
                   if (hIsres) then
                    LoadString( hIsres, SD_STR_INVALID_FOLDER_TITLE, szStr_InvalidFdr_Title, _MAX_STRING );
                    LoadString( hIsres, SD_STR_INVALID_FOLDER, szStr_InvalidFolder, _MAX_STRING );
                   endif;
                   SetDialogTitle(DLG_MSG_SEVERE, szStr_InvalidFdr_Title);
                   MessageBox(szStr_InvalidFolder+ "\n\n\t            "+ "/ : * ? \" < >  and ", SEVERE);
                   SetDialogTitle(DLG_MSG_SEVERE, "Severe");
                   hwndEdit = GetDlgItem( hwndDlg, SD_EDIT_PROGGRP );
                       SetFocus( hwndEdit );
                       else
                         svDefGroup = szGroup;
                         nId        = NEXT;
                         bDone      = TRUE;
                       endif;              case BACK:
                       nId    = BACK;
                       bDone  = TRUE;              case DLG_ERR:
                       SdError( -1, "SdSelectFolder" );
                       nId    = -1;
                       bDone  = TRUE;              case DLG_CLOSE:
                       SdCloseDlg( hwndDlg, nId, bDone );              default:
                       // check standard handling
                       if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
                          bDone = TRUE;
                       endif;
                  endswitch;           endwhile;           EndDialog( szDlg );
               ReleaseDialog( szDlg );           SdUnInit( );
               Disable(HOURGLASS);           // record data produced by this dialog
               SdMakeName( szAppKey, szDlg, szTitle, nSdSelectFolder );
               SilentWriteData( szAppKey, "szFolder", DATA_STRING, svDefGroup, 0 );
               SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );           return nId;  return nResult;
     end;
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function: DialogShowSdStartCopy                                           //
    //                                                                           //
    //   Purpose: This function displays the dialog preceding the start of the   //
    //            file copying process.                                          //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function DialogShowSdStartCopy()
        NUMBER nResult;
        STRING szTitle, szMsg;
        STRING  szDlg, szTemp;
              INT     nId, list;
              BOOL    bDone;
              HWND    hwndChild, hwndDlg; begin  szTitle = "将要开始拷贝文件";
      szMsg   = "安装程序即将向您的机器拷贝下面的组件,按\"继续\"开始拷贝,按\"取消\"退出安装";          szDlg     = SD_DLG_STARTCOPY;
              nSdDialog = SD_NDLG_STARTCOPY;          // record data produced by this dialog
              if (MODE=SILENTMODE) then
                SdMakeName( szAppKey, szDlg, szTitle, nSdStartCopy );
                SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
                return nId;
              endif;          // ensure general initialization is complete
              if (!bSdInit) then
                 SdInit();
              endif;          if (EzDefineDialog( szDlg, "", "", SD_NDLG_STARTCOPY) = DLG_ERR) then
                 return -1;
              endif;          // Loop in dialog until the user selects a standard button
              bDone = FALSE;          while (!bDone)             nId = WaitOnDialog( szDlg );             switch (nId)
                 case DLG_INIT:
                      if(szMsg != "") then
                          SdSetStatic( szDlg, SD_STA_MSG1, szMsg );
                      endif;
                      SdSetStatic(szDlg, 12, "<上一步");
                      SdSetStatic(szDlg, 1, "继续>");
                      SdSetStatic(szDlg, 9, "取消");                  hwndDlg = CmdGetHwndDlg( szDlg );
                      SdGeneralInit( szDlg, hwndDlg, 0, szSdProduct );                  if(szTitle != "") then
                          SetWindowText( hwndDlg, szTitle );
                      endif;                  if (listStartCopy = 0) then
                         hwndChild = GetDlgItem( hwndDlg, SD_MULTEDIT_FIELD1 );
                         ShowWindow( hwndChild, SW_HIDE );
                         hwndChild = GetDlgItem( hwndDlg, SD_STA_SETTINGS );
                         ShowWindow( hwndChild, SW_HIDE );
                      else
                         CtrlSetMLEText( szDlg, SD_MULTEDIT_FIELD1, listStartCopy );
                      endif;             case SD_PBUT_CONTINUE:
                      nId   = NEXT;
                      bDone = TRUE;             case BACK:
                      nId    = BACK;
                      bDone  = TRUE;             case DLG_ERR:
                      SdError( -1, szDlg );
                      nId   = -1;
                      bDone = TRUE;             case DLG_CLOSE:
                      SdCloseDlg( hwndDlg, nId, bDone );             default:
                      // check standard handling
                      if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
                          bDone = TRUE;
                      endif;
                 endswitch;          endwhile;          EndDialog( szDlg );
              ReleaseDialog( szDlg );          SdUnInit();          // record data produced by this dialog
              SdMakeName( szAppKey, szDlg, szTitle, nSdStartCopy );
              SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );          return nId;  return nResult;
     end;
    ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // Function: DialogShowSdFinishReboot                                        //
    //                                                                           //
    //  Purpose: This function will show the last dialog of the product.         //
    //           It will allow the user to reboot and/or show some readme text.  //
    //                                                                           //
    ///////////////////////////////////////////////////////////////////////////////
    function DialogShowSdFinishReboot()
        NUMBER nResult, nDefOptions;
        STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
        NUMBER bOpt1, bOpt2;
        STRING  szDlg, szTemp;
              INT     nId, list, nType, nOS;
              HWND    hwndDlg, hwndRbut, hwndFbut;
              BOOL    bWin16, bDone;
     begin  if (!BATCH_INSTALL) then
          bOpt1 = FALSE;
          bOpt2 = FALSE;
          szMsg1 = "安装程序已完成了瑞软表单2.4(中文版)的安装.";
          szMsg2 = "单击\"完成\"结束安装程序";
          szOption1 = "";
          szOption2 = "";       szDlg     = SD_DLG_FINISH;
           nSdDialog = SD_NDLG_FINISH;          // determine OS to be used for restarting
              bWin16 = FALSE;          // record data produced by this dialog
              if (MODE=SILENTMODE) then
                SdMakeName( szAppKey, szDlg, szTitle, nSdFinish );
                SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
                if ((nId != BACK) && (nId != CANCEL)) then
                   SilentReadData( szAppKey, "bOpt1", DATA_NUMBER, szTemp, bOpt1 );
                   SilentReadData( szAppKey, "bOpt2", DATA_NUMBER, szTemp, bOpt2 );
                endif;
                return nId;
              endif;          // ensure general initialization is complete
              if (!bSdInit) then
                 SdInit();
              endif;          if (EzDefineDialog( szDlg, "", "", SD_NDLG_FINISH) = DLG_ERR) then
                 return -1;
              endif;          // Loop in dialog until the user selects a standard button
              Disable( BACKBUTTON );
              bDone = FALSE;          while (!bDone)             nId = WaitOnDialog( szDlg );             switch (nId)
                 case DLG_INIT:
                      hwndDlg = CmdGetHwndDlg( szDlg );                  if(szMsg1 != "") then
                          SdSetStatic( szDlg, SD_STA_MSG1, szMsg1 );
                      endif;                  if(szMsg2 != "") then
                          SdSetStatic( szDlg, SD_STA_MSG2, szMsg2 );
                      endif;
                      SdSetStatic(szDlg, 12, "<上一步");
                      SdSetStatic(szDlg, 1, "完成");
                      // set or hide radiobutton information
                      if (szOption1 != "") then
                          CtrlSetText( szDlg, SD_RBUT_LAUNCHREADME, szOption1 );
                      else
                          hwndRbut = GetDlgItem( hwndDlg, SD_RBUT_LAUNCHREADME );
                          ShowWindow( hwndRbut, SW_HIDE );
                          bOpt1 = FALSE;
                      endif;                  if (szOption2 != "") then
                          CtrlSetText( szDlg, SD_RBUT_LAUNCHAPP, szOption2 );
                      else
                          hwndRbut = GetDlgItem( hwndDlg, SD_RBUT_LAUNCHAPP );
                          ShowWindow( hwndRbut, SW_HIDE );
                          bOpt2 = FALSE;
                      endif;                  // general initialization
                      SdGeneralInit( szDlg, hwndDlg, 0, szSdProduct );                  if(szTitle != "") then
                          SetWindowText( hwndDlg, szTitle );
                      endif;                  // set radiobuttons
                      if (bOpt1) then
                        CtrlSetState( szDlg, SD_RBUT_LAUNCHREADME, BUTTON_CHECKED );
                      endif;                  if (bOpt2) then
                        CtrlSetState( szDlg, SD_RBUT_LAUNCHAPP, BUTTON_CHECKED );
                      endif;                  if ((szOption1 = "") && (szOption2 = "")) then
                         hwndFbut = GetDlgItem( hwndDlg, SD_PBUT_CONTINUE );
                         SetFocus( hwndFbut );
                      else
                         // force product name in radiobuttons
                         SdPlugInProductName( szDlg, hwndDlg, szSdProduct, SD_RBUT_LAUNCHREADME, 2 );
                      endif;             case SD_PBUT_CONTINUE:     // Finish button
                      nId   = NEXT;
                      bDone = TRUE;                  bOpt1 = FALSE; bOpt2 = FALSE;
                      if (CtrlGetState( szDlg, SD_RBUT_LAUNCHREADME) = BUTTON_CHECKED) then
                        bOpt1 = TRUE;
                      endif;                  if (CtrlGetState( szDlg, SD_RBUT_LAUNCHAPP) = BUTTON_CHECKED) then
                        bOpt2 = TRUE;
                      endif;             case BACK:
                      nId = BACK; // should be disabled             case DLG_ERR:
                      SdError( -1, szDlg );
                      nId   = -1;
                      bDone = TRUE;             case DLG_CLOSE:
                      SdCloseDlg( hwndDlg, nId, bDone );             default:
                      // check standard handling
                      if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
                          bDone = TRUE;
                      endif;
                 endswitch;          endwhile;          EndDialog( szDlg );
              ReleaseDialog( szDlg );          SdUnInit();
              Enable( BACKBUTTON );          // record data produced by this dialog
              SdMakeName( szAppKey, szDlg, szTitle, nSdFinish );
              SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );
              SilentWriteData( szAppKey, "bOpt1", DATA_NUMBER, "", bOpt1 );
              SilentWriteData( szAppKey, "bOpt2", DATA_NUMBER, "", bOpt2 );          return nId;  endif;
      return nResult;
     end;具体效果可参见:
    http://www.readsoft.com.cn/chinese/download/RsfrmCH.exe