如何改进Shell函数 作者: ZDNet China

 本文译自Builder.com,未经许可请勿转载 当你使用Shell函数的时候,在VB程序里运行另一个可执行程序是很容易的。在本篇文章里,我将向你演示如何通过一种简单的方式来改进Shell的功能。

Shell接受两个自变量。第一个是将要运行的EXE文件的名称,包括其路径。第二个自变量用来指定程序的窗口样式。这个自变量是可选的;如果省略掉的话,程序就会以最小化的形式运行。这里所展现的技术在工作的时候不会理会程序的窗口样式,甚至程序没有窗口都可以。(关于窗口样式自变量的更多信息,请参考VB的帮助。)

Click here to find out more!

Shell会异步地运行目标程序,这就意味着执行可以在第二个程序执行完之前就返回VB程序。在很多情况下,这没有问题;但是在有的情况下,这可能就是问题了。一个例子是,当你的VB程序在某种程度上要依靠外壳程序完成其操作的结果。在这种情况下,你就需要某种方式来暂停VB程序,直到另一个程序结束。

第一步是取得外壳程序的句柄。Shell函数会返回其程序的ID,或者PID。一旦有了这个,你就可以使用OpenProcess API函数来取得句柄:

Public Declare Function OpenProcess Lib "kernel32" _
  (ByValdwDesiredAccess As Long, _
  ByValbInheritHandle As Long, _
  ByValdwProcessId As Long) As Long

将&H100000(通常由常量SYNCHRONIZE来表示)这个值传递给第一个自变量,将0(作为一个长型)传递给第二个自变量。第三个自变量是Shell函数返回的PID。函数所返回的值是代表外壳程序的Windows进程的句柄。有了这个句柄,你可以使用WaitForSingleObject API函数来暂停VB程序,直到外壳程序被终止。声明是:

Private Declare Function WaitForSingleObject Lib _
  "kernel32" (ByValhHandle As Long, _
  ByValdwMilliseconds As Long) As Long

第一个自变量是程序所等待的句柄,它从OpenProcess函数获得。第二个自变量是等待时间。如果你传递了一个毫秒值,那么函数就会在外壳程序结束的时候,或者在指定的时间间隔用完的时候返回,这取决于哪一种情况先发生。如果你想要函数一直等到外壳程序结束,那么就要传递&HFFFF(常常由常数INFINITE表示)这个值。

下面的示例代码显示了如何使用这些API来给程序设定外壳,并等待其完成。

Const SYNCHRONIZE = &H100000
Const INFINITE = &HFFFF

Private Sub ShellProgramAndWait(ProgramName As String)

Dim hHandle As Long, pid As Long
txtStatus.Text = "Processing"
txtStatus.Refresh
pid = Shell(ProgramName, vbNormalFocus)
If pid <> 0 Then
    hHandle = OpenProcess(SYNCHRONIZE, 0&, pid)
    WaitForSingleObjecthHandle, INFINITE
    txtStatus.Text = "Finished"
Else
    txtStatus.Text = "Error shelling " & ProgramName
End If

End Sub

WaitForSingleObject函数会有效地冻结你的VB程序,这是你需要注意的事情,这样用户就不会认为出了问题。例如在这段代码里,一个Text Box(文本框)控件向用户显示了一条消息。要注意,Refresh(刷新)方法的使用确保了该消息在程序进入等待状态之前被显示出来。然后,当外壳程序终止的时候,一个“已完成(Finished)”的消息就显示出来了。


本文作者Peter Aitken:自从Visual Basic 1.0版以来,Peter Aitken就一直使用VB编程。他已经编写过很多关于VisualBasic以及其 他计算机和编程的书以及杂志文章了。

posted on 2005-12-29 14:54  爱你一万年123  阅读(107)  评论(0编辑  收藏  举报

导航