摘 要 本文介绍了在Visual FoxPro环境的软件设计中如何激活外部应用程序的方法。特别是利用Visual FoxPro的动态链接库和Windows API函数,从注册表中获取启动外部应用程序信息,从而激活应用程序。这一方法不受软件安装时是否选择缺省路径的影响,因而具有与设备无关的特点。
关键词 Visual FoxPro, 注册表,动态链接库,Windows API 函数,参数传递
Visual FoxPro 是一个功能很强的可视化数据库管理信息系统的开发平台,用它开发中、小型数据库管理系统是简单易行的。但是在管理系统软件的开发和设计中,常常要激活Windows系统程序或在Windows系统下安装的外部应用程序(以下统称外部应用程序),在Visual FoxPro环境下实现这一功能有以下几种方法。
一、使用RUN 或!命令
RUN或!命令是从DBase—FoxBase—FoxPro—Visual FoxPro 一直保留下来的一个执行外部程序的命令。在Visual FoxPro环境下,使用该命令时可以加一个参数 /n (NOWAIT),从而可以避免在调用另一个窗口程序时会短暂出现黑屏的DOS窗口,该命令使用比较简便,但必须明确外部应用程序的具体路径,且不能省略应用程序的扩展名。例如,要激活Word2000程序,且已知它被安装在C:\Program Files\Microsoft Office\Office下,可在表单上添加一个标题为“用RUN或!激活WORD2000”的命令按钮,它的name属性为 RunCmd,那么在RunCmd.Click事件中可以输入下面的程序代码来实现:
local PathName
PathName=" C:\Program Files\Microsoft Office\Office\winword.exe"
if file(PathName)
Run /n &PathName
else
messagebox("找不到该程序",32,"提示")
endif
二、使用外壳程序
Visual FoxPro 提供了_Shell Execute类,使用该类的ShellExecute方法程序可以从当前的VFP应用程序窗口激活另一个外部应用程序,使用该类的方法是:
在表单控件工具栏上按“查看类”,选择“添加”,在出现的“打开”对话框中选择文件位置,假如VFP缺省安装在C:\Program Files下,则文件位置在C:\Program Files\Microsoft Visual Studio\vfp98\ffc,在文件列表框中选择类库文件 _environ.vcx,按“打开”命令,在表单控件工具栏上就会出现_ShellExecute控件,将其添加到表单上即可。
另一种方法是从VFP的主菜单的“工具”菜单出发,选择“组件管理库”,在出现的组件管理库的浏览界面,选择 Visual FoxPro Catalog\Foundation Classes\Utilities\中的 Shell Execute类,右击之,在快捷菜单中选择“添加至表单”或直接从浏览窗口拖至表单。
设一个表单上已有_ShellExecute控件,名称为_ShellExecute1,另有一个激活外部应用程序的命令按钮,其名称为ShellCmd,标题属性(Caption)为“用外壳程序激活WORD2000”,则在cmd的click事件中加入如下语句来实现1.中对WORD2000程序的激活:
local PathName
PathName=" C:\Program Files\Microsoft Office\Office\winword.exe"
If file(PathName)
This.parent._ShellExecute1.ShellExecute(PathName)
Else
messagebox("找不到该程序",32,"提示")
endif
以上两种方法最大的优点是比较简便,但是有一个最大的缺点,那就是对机器的依赖性很强,它受机器的软件安装路径所限制,在不同的机器上运行这些程序都要明确指出外部应用程序的路径。绝大多数的应用软件都允许用户不使用默认安装路径,用户可以自由选择新的安装路径,这样,同一个应用程序在不同的机器上安装路径不尽相同,用以上两种方法编制的程序就不可能具有通用性。为此,作者在实践中分析了Windows系统的注册表,通过注册表可以获取激活外部应用程序的信息。
三、用注册表激活外部应用程序
在Windows系统的注册表中,应用程序及Windows系统程序的设置都在根键 HKEY_LOCAL_MACHINE中。每一个安装的程序都有一个固定的启动子键,尽管在不同的机器上可以选择不同的安装路径,但此子键名是不变的(例如 WORD2000的子键名为“software\clssses\word.backup.8\shell\open\command”),而键值则随机器上应用程序安装的路径有所不同。程序的启动路径就在其键值中,只要能从中提取键值,就能获取启动路径及程序的完整文件名和扩展名,从而实现在Visual FoxPro开发环境下可靠、安全地激活已正确安装的外部应用程序。
Windows系统的动态连接库(DLLs)提供了大量的API(Application Programming Interface)函数,这就使我们有可能利用其中有关注册表的一些函数,获取外部应用程序的启动路径及程序的文件名和扩展名,实现对应用程序的激活,下面以Visual FoxPro环境下激活WORD2000为例,说明如何使用这些API函数和注册表。
在Visual FoxPro界面创建一个表单,表单上创建一个命令按钮,其name 属性为 RegCmd,caption 属性为“用注册表激活WORD2000”;并在表单上按2.的方法添加一个name 属性为_ShellExecute1的ShellExecute类控件。在cmd.click()事件中编写如下程序代码:
#define KEY_QUERY_VALUE 1 &&定义保留参数,1表示允许查询子键数据
#define HKEY_LOCAL_MACHINE 8*16^7+2 &&定义保留参数,根键的值为80000002H
#define ERROR_SUCCESS 0 &&定义保留参数,函数返回值0表示成功
Declare integer RegQueryValue in advapi32.dll integer hKey, String lpSubKey, String @lpValue , integer @lpcbValue &&注册RegQueryValue函数,取键值
Declare integer RegOpenKeyExin advapi32.dll integer hKey, String lpSubKey, integer ulOptions ,integer samDesired ,integer @phkResult &&注册RegOpenKeyEx函数,打开子键,取得句柄
Declare integer RegCloseKey in advapi32.dll integer hKey &&注册RegCloseKey函数,释放句柄
RegPath = "software\classes\word.backup.8\shell\open\command" &&安装Word2000的子键名
lnresult = 0 &&句柄变量,接受打开的句柄,按引用传递
lcbuffer = Space(128) &&接受键值的缓冲区指针变量,按引用传递
lnbuffersize = Len(lcbuffer) &&子键长度变量
lnerror=RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegPath,0,KEY_QUERY_VALUE,@lnresult ) &&打开由变量RegPath指定的子键
If lnerror = ERROR_SUCCESS Then &&判断打开子键是否成功
lnerror = RegQueryValue(lnresult,"",@lcbuffer, @lnbuffersize) &&获取子键的值在lcbuffere中
If lnerror = ERROR_SUCCESS Then &&判断是否取得子键的值
loca=atc(".exe",lcbuffer) &&从缓冲区中分离出启动路径及文件名、扩展名
PathName=alltrim(substr(lcbuffer,1,loca+4))
If PathName == "" Then
= MessageBox ("确认是否正确安装该程序?", 32, "启动失败提示!")
Else
THIS.Parent._ShellExecute1.ShellExecute(PathName) &&或用run /n &PathName激活程序
EndIf
EndIf
Else
= MessageBox ("确认是否正确安装该程序?", 32, "启动失败提示!")
EndIf
rc = RegCloseKey(lnresult) &&释放指定的子键的句柄
以上程序在外部应用程序具有不同安装路径的计算机上,无论是Windows XP,Windows ME ,Windows 2000 或 Windows98平台,在Visual FoxPro 环境下都成功地激活了各种外部应用程序。只要改变程序中已安装的外部应用程序的子键名,即变量RegPath的值就可以激活相应的外部应用程序。至于外部应用程序启动路径所在的子键名,可在注册表编辑器(运行Regedit.exe)中通过查找的方法来寻找,可能找到的子键名不止一处,可以选择其中一处,但要求启动路径一定为该子键的默认值。附表是部分常用程序启动路径所在的子键,供参考。
关于WindowsAPI函数的使用,作者结合这一应用总结了在VFP环境中使用时,特别是VFP中参数传递要注意地方,供大家参考。
⑴ VFP中并没有提供这些函数的帮助信息,这可能与VFP不是微软的主流产品有关,但可以借助Visual Basic的“API文本浏览器”找到这些函数以及这些函数保留参数的具体信息。
⑵ Visual Basic的“API文本浏览器”中所提供的有关API函数信息可在VB环境中直接使用,但在VFP中使用这些函数前必须重新定义保留参数的值并注册DLL函数,这不仅仅是定义和注册的语法与Visual Basic不同,更重要的是注册语句(Declare)中对参数的传递方式必须在分析了各个参数的意义和作用后,作出对参数传递方式的正确判断,而不能沿用VB中的参数传递方式。例如 RegQueryValue() 函数中的 lpValue参数是指向一个缓冲区的指针,在VB环境中以传值方式传递,但在VFP环境中就不能以传值方式传递,而必须以按引用方式传递。注意,按引用方式传递的参数,无论在 API函数的注册语句中,还是在API 函数的调用语句中,在参数的前面都要加上 @ 符号。
⑶ 本例中使用了Advapi32.dll 动态链接库,实际上可以用 WIN32API 作为链接的库名称,如果这样,Visual FoxPro 将在 Kernel.dll、Gdi32.dll、User32.dll、Mpr.dll 和 Advapi32.dll中去查找被调用的32位 Windows API 函数,用户就不必关心某一函数到底属于那一个动态链接库。
附表:部分常用应用程序在注册表中含启动信息的参考子键名
程序名 |
子键名(在根键HKEY_LOCAL_MACHINE中) |
Access2000 |
\software\classes\Access.Application.9\shell\open\command |
Execl2000 |
\software\classes\Excel.Backup\shell\open\command |
Outlook200 |
\software\classes\Outlook\shell\open\command |
Powerpoint2000 |
\software\classes\Powerpoint.addin.8\shell\open\command |
Word2000 |
\software\classes\Word.Backuo.8\shell\open\command |
FrontPage2000 |
\software\classes\FrontPage.Editor.Document.4.0\shell\open\command |
IE6.0 |
\software\classes\ftp\shell\open\command |
Photoshop6.0 |
\software\classes\Photoshop.Image.6\shell\open\command |
资源管理器 |
\software\classes\fndFile\shell\open\command |
参考文献:
[1]电子工业出版社编写组,新编Windows API 参考大全,北京:电子工业出版社,2000.
[2]任杰主编,Visual FoxPro 6.0 中文版实用编程技术,北京:中国水利电力出版社,1999
|