InstallShield自定义对话框浅谈(转)

说明:本文档的InstallShield6.22版本,语言:中文。操作系统为Windows2000。资源编辑工具:Microsoft Visual C ++ 6.0。修改的DLL_isuer.dll

此主题相关图片如下:


InstallShield
允许添加自定义对话框来满足不同的需求,关于如何创建一个新的对话框资源,有很多参考资料可以查询,就不多说了。这里主要说明的有以下几个方面:


1
、  如何创建具有InstallShield Wizard同样风格的对话框。


2
、  如何编写脚本来控制自定义对话框上的输入和控件的有效性判断。

 

 

 


一、  创建具有InstallShield Wizard同样风格的对话框在安装向导中可能需要加入一些自定义的步骤,这时可能需要插入一些自定义的对话框来作为某步骤,为了能够把自定义对话框的步骤完全融入导InstallShield Wizard中,即自定义对话框要具有和InstallShield标准步骤同样的风格,下图是InstallShield某标准步骤的图片:

 


                
标准步骤示例


在上图中,已经把标准向导对话框的一些风格标注出来了:①、②、③、④,①为该步骤功能说明,并且该说明以黑体字表达;②为对该功能的补充说明;③为InstallShield的图标;④为InstallShield的标注。

 


那么如何在自定义对话框中实现这些特性呢?下面就对这四个特殊地方作说明:

 


首先,这四个地方都是一个标签控件,在VC++中表现为静态控件(CStatic)。

 


处是表明该步骤功能的地方,那么如何实现黑体的风格呢?其实InstallShield内嵌的机制已经对此作了定义了。在自定义对话框上添加一个静态控件,并且设置该控件的ID为50,并且使ExtendedStyles中的Transparent属性有效,然后在Caption中写上自定义的功能。该控件的位置为(10,3)。设置了这些后,InstallShield会自动把控件中的字体改为黑体。

 


处为该同样设置Extended Styles的Transparent属性有效,然后在Caption中写上补充说明。该控件的位置为(17,15)。


处为InstallShield的图标,该图标也是用静态控件来实现的。在自定义对话框上添加一个静态控件,设置该控件的ID为1200,并且使Styles中的Simple属性有效和Extended Styles的Transparent属性有效,在Caption中填上:@10550,10551;1;0;;0,128,128。该控件的位置为(0,0),大小为(332 x 218)。设置了这些后,InstallShield会自动在该控件中加入该图标。


处为InstallShield的标注,但是不同于普通效果。在自定义对话框上添加一个静态控件,设置该控件的ID为7,把Caption清空,并且把控件的Visible属性去掉。InstallShield会自动把该控件设置成标准效果。

 

在设置了以上四个地方之后,还需要在添加一个静态控件,设置该控件的ID为52,把Caption清空,位置为(0,0),大小为(332 x 218)。运行的实际效果,就和标准的安装步骤中的效果一样了。


二、根据输入控制对话框上控件的有效性
在自定义了一个对话框之后,可能需要对对话框上的控件之间的关系进行一些控制,比如当选中了某单选框后,使一些控件有效,而选中其他的单选框后,另一些控件有效等等。要实现这些功能,就需要手动编写InstallShield脚本来实现了。
下面是一个在安装向导中添加了一个自定义对话框,在该步骤中实现在安装的时候在本机器上添加一个SQL Server的数据源。图自定义对话框效果图是该自定义对话框的运行效果图:

此主题相关图片如下:


在该自定义对话框中,除了要完成配置SQL Server的数据源之外,还要完成其他一些辅助功能。为了在本机器上配置一个SQL Server数据源,需要输入该数据源的名称、该数据源是针对那个服务器的以及配置的是用户数据源还是系统数据源等数据,而数据库和服务器用户及口令则是完成辅助功能所需要的。只有当输入了必须的数据(如:服务器、数据库、用户名称、数据源等)之后,按钮“下一步”才能有效,为了达到这个要求,就需要对用户的输入进行判断,在InstallShield中可以用WaitOnDialog来得到当前对话框的事件。下面是完成该功能的一个完整脚本代码:

 

///
// kdcis.rul
//
///

 

#ifndef __KDCIS_RUL_
#define __KDCIS_RUL_

 

#include "winsysdll.h"
//
// Pre-defined script dialog constants
//    

 

            // ----- Attribute Dialog Controls ------
#define DLG_DSN_SQLSERVER    30001

 

#defineIDC_RADIO_DSN_USER    1001
#define IDC_RADIO_DSN_SYSTEM   1002
#defineIDC_EDIT_DB_ADDR                1003
#define IDC_EDIT_SQLSERVER_USER_NAME 1004
#define IDC_EDIT_SQLSERVER_USER_PWD 1005
#define IDC_EDIT_SQLSERVER_DSN   1006
#define IDC_EDIT_SQLSERVER_DB   1007

 

        file://----------------------
        // Function prototypes
        file://----------------------

 


///
//
显示配置SQLSERVER数据源对话框
// 参数:
//    BOOL bFirstStep:是安装的第一步吗?
//    BOOL bAllowNotSet:是否允许跳过本次设置
//    BYVAL STRING szTitle:对话框的标题
///
prototype BuildSQLServerDSN(BOOL, BOOL, BYVAL STRING);

 


///
//
校验配置数据源对话框的输入有效性
//
参数:
//    HWND hwndDlg:配置对话框的句柄,从CmdGetHwndDlg中得到
//    BOOL bAllowNotSet:是否允许跳过本次设置
// 备注:
//    CheckSQLServerDSNInputValid:对SQLSERVER数据源配置进行校验
//
prototype CheckSQLServerDSNInputValid(HWND, BOOL);
      
        file://----------------------
        // Variable declaration
        file://----------------------  
        
        file://----------------------
        // Macro declaration
        file://----------------------
#define DSN_SQLSERVER_DLG "ConfigSQLServerDSNDLG"



/*------------------------------------------------------------------------*/


/*                                                                        */


/*  Function:  BuildSQLServerDSN                                        */


/*                                                                        */


/*   Descrip:   use custom sqlserver's dsn dlg to createdsn.             */


/*                                                                        */


/*  Misc:                                                                */


/*                                                                        */


/*------------------------------------------------------------------------*/


function BuildSQLServerDSN(bFirstStep, bAllowNotSet,szTitle)


          BOOL bDone;


          NUMBER nMessage;


          STRING szSQLAddr,szSQLDB, szDBUserName, szDBUserPwd, szSQLDSN;


          SHORT nDSNType;


          STRING svArg[1024];


          STRING svDSN,svAddr, svDB, svUID, svPWD;


          NUMBER nSplitPos;


          HWND hwndDlg;


          BOOL bBuildResult;


          SHORT wErrMsgLen;


          STRINGszErrMsg[MAX_PATH + 1];


          LONG dwErrCode;


   begin


      


       bDone = FALSE;


//
EzDefineDialog定义一个对话框


       nMessage =EzDefineDialog(DSN_SQLSERVER_DLG, ISUSER, "", DLG_DSN_SQLSERVER);


       if(nMessage = DLG_ERR) then


           MessageBox("
不能进行配置SQLSERVER数据源——找不到对话框", SEVERE);


           bDone = TRUE;


       endif;


       while(bDone = FALSE)


           nMessage =WaitOnDialog(DSN_SQLSERVER_DLG);


           switch(nMessage)


           case DLG_INIT:


                        hwndDlg= CmdGetHwndDlg(DSN_SQLSERVER_DLG);


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


              if(bFirstStep) then


                  _WinSubEnableControl(hwndDlg, SD_PBUT_BACK, 0);


              endif;


              _WinSubSetWindowTitle(hwndDlg, szTitle);


              CtrlSetState(DSN_SQLSERVER_DLG, IDC_RADIO_DSN_USER, BUTTON_CHECKED);


              


           case DLG_ERR:


              MessageBox("
不能显示配置SQLSERVER数据源对话框", SEVERE);


              bDone = TRUE;


              


           case CANCEL:


              bDone = TRUE;


              


           case DLG_CLOSE:


              bDone = TRUE;


              


           caseSD_PBUT_CONTINUE:


              //
调用接口添加一个dsn


              // ...


              CtrlGetText(DSN_SQLSERVER_DLG, IDC_EDIT_DB_ADDR, szSQLAddr);


              CtrlGetText(DSN_SQLSERVER_DLG, IDC_EDIT_SQLSERVER_DB, szSQLDB);


              CtrlGetText(DSN_SQLSERVER_DLG, IDC_EDIT_SQLSERVER_USER_NAME, szDBUserName);


              CtrlGetText(DSN_SQLSERVER_DLG, IDC_EDIT_SQLSERVER_USER_PWD, szDBUserPwd);


              CtrlGetText(DSN_SQLSERVER_DLG, IDC_EDIT_SQLSERVER_DSN, szSQLDSN);


              if(StrLength(szSQLAddr) = 0) then


                  if(AskYesNo("
没有输入服务器,是否以后进行配置?", YES) = NO) then


                      _WinSubFocusControl(hwndDlg, IDC_EDIT_DB_ADDR);


                  else


                      bDone = TRUE;


                  endif;


              elseif(StrLength(szSQLDB) = 0) then


                  if(AskYesNo("
没有输入数据库,是否以后进行配置?", YES) = NO) then


                      _WinSubFocusControl(hwndDlg, IDC_EDIT_SQLSERVER_DB);


                  else


                      bDone = TRUE;


                  endif;


              elseif(StrLength(szDBUserName) = 0) then


                  if(AskYesNo("
没有输入数据库用户,是否以后进行配置?", YES) = NO) then


                      _WinSubFocusControl(hwndDlg, IDC_EDIT_SQLSERVER_USER_NAME);


                  else


                      bDone = TRUE;


                  endif;


              elseif(StrLength(szSQLDSN) = 0) then


                  if(AskYesNo("
没有输入数据源名称,是否以后进行配置?", YES) = NO) then


                      _WinSubFocusControl(hwndDlg, IDC_EDIT_SQLSERVER_DSN);


                  else


                      bDone = TRUE;


                  endif;


              else


                  //
已经获取了所有数据,可以调用SQLConfigDataSource添加数据源了


                  //
组织语句


                  //
注:由于DSN不保存UIDPWD,所以在Attribute中不能加入这两个


                  //    
关键字,并且每个关键子之间用'\0'分割,由于InstallShield


                  //    
中不支持一个字符串中间存在'\0',因此,不能直接用+连接这些


                  //    
关键字,下面是一个变通的方法


                  if(CtrlGetState(DSN_SQLSERVER_DLG, IDC_RADIO_DSN_USER) = BUTTON_CHECKED) then


                      nDSNType = ODBC_ADD_DSN;


                  else


                      nDSNType = ODBC_ADD_SYS_DSN;


                  endif;


                  svDSN = "DSN=" + szSQLDSN;


                  svAddr = "SERVER=" + szSQLAddr;


                  svDB = "DATABASE=" + szSQLDB;


                  svUID = "UID=" + szDBUserName;


                  svPWD = "PWD=" + szDBUserPwd;


                  svArg = svDSN + ' ' + svAddr + ' ' + svDB;


                  nSplitPos = StrLength(svDSN);


                  svArg[nSplitPos] = '\0';


                  nSplitPos += StrLength(svAddr) + 1;


                  svArg[nSplitPos] = '\0';


                  nSplitPos += StrLength(svDB) + 1;


                  svArg[nSplitPos] = '\0';


                  //
调用ODBCCP32中的SQLConfigDataSource添加一个DSN


                  //
如果返回FALSE,表示添加失败,这时可以调用


                  // SQLInstallerError
来得到失败的原因


                  bBuildResult = SQLConfigDataSource(NULL, nDSNType, "SQL Server",svArg);


                  if(bBuildResult) then


                          //
如果添加成功


                          bDone = TRUE;


                      else


                          //
添加失败                                                            


                          wErrMsgLen = MAX_PATH;


                          SQLInstallerError(1, &dwErrCode, szErrMsg, wErrMsgLen, &wErrMsgLen);


                          if(bAllowNotSet) then


                                szErrMsg= "
配置数据源失败——" + szErrMsg + "!是否以后进行配置?";


                              if(AskYesNo(szErrMsg, YES) = NO) then


                                  bDone = FALSE;


                              else


                                  bDone = TRUE;


                              endif;


                          else


                              szErrMsg = "
配置数据源失败——" + szErrMsg + "";


                              MessageBox(szErrMsg, SEVERE);


                          endif;


                      endif;


              endif;


              


           case SD_PBUT_BACK:


              //
上一步


              bDone = TRUE;


              


           caseSD_PBUT_EXITSETUP:


              bDone = TRUE;


          


           caseIDC_RADIO_DSN_USER:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           caseIDC_RADIO_DSN_SYSTEM:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           caseIDC_EDIT_DB_ADDR:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           caseIDC_EDIT_SQLSERVER_USER_NAME:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           caseIDC_EDIT_SQLSERVER_USER_PWD:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           caseIDC_EDIT_SQLSERVER_DSN:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           caseIDC_EDIT_SQLSERVER_DB:


              CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet);


          


           endswitch;


          


       endwhile;


      


       EndDialog(DSN_SQLSERVER_DLG);


       ReleaseDialog(DSN_SQLSERVER_DLG);


      


       if(nMessage = SD_PBUT_CONTINUE) then


           return NEXT;


       elseif(nMessage = SD_PBUT_BACK) then


           return BACK;


       else


           Do(EXIT);


       endif;

  end;

 

 

 

 


/*------------------------------------------------------------------------*/


/*                                                                        */


/*  Function:  CheckSQLServerDSNInputValid                              */


/*                                                                        */


/*   Descrip:   check the input data isvalid.                                    */


/*       do not need to check the pwd ifempty                            */


/*  Misc:                                                                */


/*                                                                        */


/*------------------------------------------------------------------------*/


  function CheckSQLServerDSNInputValid(hwndDlg, bAllowNotSet)


      STRING szDBUserName;


      STRING szSQLDB;


      STRING szSQLAddr;


      STRING szSQLDSN;


  begin


      


       if(bAllowNotSet) then


          _WinSubEnableControl(hwndDlg, SD_PBUT_CONTINUE, 1);


           return 1;


       endif;


      


       if((CtrlGetState(DSN_SQLSERVER_DLG,IDC_RADIO_DSN_USER) = BUTTON_UNCHECKED) &&


          (CtrlGetState(DSN_SQLSERVER_DLG,IDC_RADIO_DSN_SYSTEM) = BUTTON_UNCHECKED)) then


              _WinSubEnableControl(hwndDlg,SD_PBUT_CONTINUE, 0);


              return0;


       endif;

 


       CtrlGetText(DSN_SQLSERVER_DLG,IDC_EDIT_SQLSERVER_USER_NAME, szDBUserName);


       if(StrLength(szDBUserName) = 0) then


          _WinSubEnableControl(hwndDlg, SD_PBUT_CONTINUE, 0);


           return 0;


       endif;


       CtrlGetText(DSN_SQLSERVER_DLG,IDC_EDIT_SQLSERVER_DSN, szSQLDSN);


       if(StrLength(szSQLDSN) = 0) then


          _WinSubEnableControl(hwndDlg, SD_PBUT_CONTINUE, 0);


           return 0;


       else


          if(!SQLValidDSN(szSQLDSN)) then


              MessageBox("
输入了无效的数据源名称!", INFORMATION);


              _WinSubFocusControl(hwndDlg, IDC_EDIT_SQLSERVER_DSN);


              return 0;


           endif;


       endif;


       CtrlGetText(DSN_SQLSERVER_DLG,IDC_EDIT_SQLSERVER_DB, szSQLDB);


       if(StrLength(szSQLDB) = 0) then


          _WinSubEnableControl(hwndDlg, SD_PBUT_CONTINUE, 0);


           return 0;


       endif;


       CtrlGetText(DSN_SQLSERVER_DLG,IDC_EDIT_DB_ADDR, szSQLAddr);


       if(StrLength(szSQLAddr) = 0) then


          _WinSubEnableControl(hwndDlg, SD_PBUT_CONTINUE, 0);


           return 0;


       endif;


      


       _WinSubEnableControl(hwndDlg,SD_PBUT_CONTINUE, 1);


       return 1;


  end;


      

 


#endif // __KDCIS_RUL

 

 

 

//===========================================================================

 

// 文件:winsysdll.h

 

// 描述:定义系统动态库的函数原型

 

//

 

// 更新:

 

//            2004/02/06

 

//===========================================================================

 

 

 

#ifndef __WINSYSDLL_H__

 

#define __WINSYSDLL_H__

 

 

 

      //----------------------------------------------------

 

       //Prototype user32 DLL functions used in project.

 

      //----------------------------------------------------

 

      

 

 

      //----------------------------------------------------

 

       //Prototype ocbccp32 DLL functions used in project.

 

      //----------------------------------------------------

 

 

#ifndef ODBC_ADD_DSN

 

      #defineODBC_ADD_DSN                  1

 

#endif

 

#ifndef ODBC_CONFIG_DSN

 

      #defineODBC_CONFIG_DSN                  2

 

#endif

 

#ifndef ODBC_ADD_SYS_DSN

 

      #defineODBC_ADD_SYS_DSN          4

 

#endif

 

#ifndef ODBC_CONFIG_SYS_DSN

 

      #defineODBC_CONFIG_SYS_DSN          5

 

#endif

 

#ifndef ODBC_INSTALL_COMPLETE

 

      #define ODBC_INSTALL_COMPLETE       2

 

#endif

 

#ifndef ODBC_INSTALL_DEIVER

 

      #defineODBC_INSTALL_DEIVER            1

 

#endif

 

#ifndef SQL_MAX_MESAGE_LENGTH

 

      #define SQL_MAX_MESSAGE_LENGTH   512

 

#endif

 

#ifndef SQL_SUCCESS_WITH_INFO

 

      #define SQL_SUCCESS_WITH_INFO 1

 

#endif

 

#ifndef SQL_NO_DATA

 

      #defineSQL_NO_DATA                            100

 

#endif

 

#ifndef SQL_ERROR

 

      #defineSQL_ERROR                        -1

 

#endif

 

prototype BOOLODBCCP32.SQLConfigDataSource(HWND, SHORT, BYVAL STRING, BYVAL STRING);

 

 

prototype BOOL ODBCCP32.SQLValidDSN(BYVALSTRING);

 

 

prototype BOOLODBCCP32.SQLInstallerError(SHORT, POINTER, BYREF STRING, SHORT, POINTER);

 

 

#endif // __WINSYSDLL_H__

 

以上是本人对在InstallShield下自定义对话框的一些心得。在建立自定义对话框的时候,还是有一些疑惑,当在自定义对话框上添加了IP地址控件之后,WaitOnDialog始终返回DLG_ERR的错误,不知道如何在自定义对话框上添加IP地址控件,至于其他的控件,则没有尝试过。

转自:http://wenku.baidu.com/link?url=3Ou7r_Wkp6cWEGvDRIzUkJ9Y9V0g0kL-Stku4ToLAkaJbuQmXKjrZLyTLt-gpBJtT76R-MqEFyYQE4tkn-G1VAggPyXzm76Omd_PGzWPuTm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要启动 InstallShield,您可以按照以下步骤操作: 1. 点击开始菜单,然后找到 InstallShield 文件夹。 2. 在 InstallShield 文件夹中,找到并单击 "InstallShield <版本号> 工具"。 3. InstallShield 将开始启动,并加载到计算机的内存中。 如果您无法在开始菜单中找到 InstallShield 文件夹,则需要检查您的计算机是否已安装 InstallShield。如果没有安装,则需要安装它才能使用。 如果您遇到任何问题或需要更详细的说明,请告诉我。 ### 回答2: InstallShield是一个用于创建和安装Windows应用程序的软件安装程序开发工具。它允许开发人员为其应用程序创建自定义安装程序,并可以设置开机启动项。 要在系统启动时自动运行安装程序,需要进行以下步骤: 1. 打开InstallShield开发工具。 2. 创建一个新的安装程序项目或打开现有的项目。 3. 在项目中选择“设置”选项,这将打开“项目设置”对话框。 4. 在“项目设置”对话框中,选择“启动”选项。 5. 在“启动”选项中,选择“安装启动项”。 6. 在“安装启动项”中,可以指定一个或多个程序文件,这些文件将在系统启动时自动运行。 7. 单击“添加”按钮,浏览并选择要添加到开机启动项的文件。 8. 添加完毕后,可以使用“上移”和“下移”按钮来调整启动项的顺序。 9. 单击“确定”保存设置并关闭“项目设置”对话框。 10. 构建安装程序并发布。 这样,安装程序将会在系统重新启动时自动运行,并通过启动项来启动指定的程序文件。 installShield开机启动的功能能够方便开发人员在安装Windows应用程序时自动设置开机启动项,提高了应用程序的用户体验和启动效率。但需要注意的是,开机启动可能会对系统的性能造成一定影响,因此在添加开机启动项时需要慎重考虑,并确保所添加的程序是必要的和有用的。 ### 回答3: 要将InstallShield设置为开机启动,可以按照以下步骤进行操作: 1. 首先,确保您已经安装了InstallShield,并且您具有管理员权限。 2. 打开Windows的“开始”菜单,并键入“运行”来打开运行对话框。然后,键入“shell:startup”并点击“确定”。 3. 这将打开一个文件夹,这是Windows开机时会自动运行的程序的目录。 4. 在InstallShield的安装目录中找到安装程序的快捷方式或可执行文件。 5. 右键单击该快捷方式或可执行文件,并选择“复制”。 6. 返回刚刚打开的文件夹,并右键单击空白处。选择“粘贴”以将InstallShield的快捷方式或可执行文件复制到该文件夹中。 7. 现在,当您下次启动计算机时,InstallShield将自动启动。 请注意,上述步骤适用于当前用户的开机启动。如果您希望所有用户都能在开机时启动InstallShield,可以进入以下文件夹: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 将InstallShield的快捷方式或可执行文件复制到此目录中。 希望以上信息对您有所帮助。如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值