大家知道,在一个大型复杂的系统中,有时会调用一些外部程序来帮助我们完成某些特定功能。然而,如何打开并关闭这些外部程序呢?也许,这是一个老生常谈的话题,但笔者仍要继续讨论这个问题,原因有二:一是解决这个问题的方法很重要,并经常会遇到;二是大多数参考书提及的解决办法不全面,仍有很多朋友有疑问。下面,我将详细地阐述这个问题(提供的源代码均在WinNT/Delphi4.0环境下运行通过)。
一、如何打开一个外部程序:
我们常用的函数有两个,WinExec,ShellExecute,因为ShellExecute函数主要用于Win32下,功能也强大一些,故而本文只对后者进行讨论。
首先,我们粗略地研究一下ShellExecute的几个参数:
hwnd:窗体的句柄;
lpOperation:打开程序执行的操作,共预留有"open","explore","print"三种方式,此参数可以省略,此时将依据打开的文件(lpFile)的类型执行相应的操作,比如:如果lpFile为一文本文件,那么将会在与该文件相关联的程序中打开它;
lpFile:文件名;
lpParamerters:打开文件时所需的参数;
lpDirectory:文件名所在的路径,当然,一般来说,在Windows中登
"记记"过的程序(如WinWord)不必提供此参数;
nShowCmd:打开文件后程序窗体如何显示。
该函数的详细文档请读者朋友参阅相应帮助。
其次,我们来举一个例子(以"记事本"为例):
procedure TForm1.OpenBtnClick(Sender:TObject);
begin
ShellExecute(handle,'open','notepad.exe',nil,nil,SW_ShowNormal);
end;
读者朋友可以在你的Delphi环境下试试这段代码,当然,由于使用Windows的API函数,请加上ShellAPI单元。
二、如何关闭打开的外部程序:
要关闭一个外部程序,只需向他发送一条消息就行了,比如,SendMessage(ExeHandle,WM_Close,0,0);其中ExeHandle是程序窗体的句柄,但如何得到窗体句柄呢?这是最为关键的地方,幸好Windows提供了FindWindow()函数,它能够解决这个问题,它有两个参数:lpClassName:程序的类名;lpWindowName:程序窗体的标题。
第一种情况也是最简单情况的就是提供确定的[*"确定的"加着重号*]
"lpWindowName"参数,如下例:
procedure TForm1.CloseAppClick(Sender: TObject);//确定标题
var
Exehandle:Thandle;
begin
//获得句柄-->标题确定
ExeHandle:=findWindow(nil,'文件管理器');//返回句柄
//关闭程序
if ExeHandle<>0 then
SendMessage(ExeHandle,WM_Close,0,0)
Else
Application.MessageBox('没有打开"文件管理器"!','提示',
MB_IconInformation+MB_OK);
end;
另一种情况是程序窗体没有确定的[*"没有确定的"加着重号*]标题,这就是很多朋友出现疑问的地方,也是几乎所有参考书均不涉及的地方。比如打开"写字板"程序,它的标题会随着文本文件名的不同而不同,此时,你要关闭它,就不得不提供程序的类名,但是如何获得程序的类名呢?笔者在这里向大家介绍一个可行的办法:首先打开程序(此处以"记事本"为例),然后,运行WinSight32(Delphi自带)或Spy++(VC自带),找到程序( "记事本")的运行状态,即可找到我们需要的类名(两者均为"Class Name"项)。参考一个例子:
procedure TForm1.CloseVAppClick(Sender: TObject);//标题不确定
var
var
ExeHandle:Thandle;
Begin
//获得句柄-->标题不确定
ExeHandle:=FindWindow('notepad',nil);//'');//返回句柄
//关闭程序
if ExeHandle<>0 then
SendMessage(ExeHandle,WM_Close,0,0)
Else
Application.MessageBox('没有打开"记事本"程序!','提示',
MB_IconInformation+MB_OK);
end;
当然,既能提供程序的类名又能提供程序窗体的标题自然就没有讨论的必要了。这样,我们就可以在自己的程序中打开并关闭任意的外部程序了。另外,笔者在这里罗嗦一句:上文提到的ShellExeCute()还有有相当"豪华" 的用处!细心的读者可能注意到有的作者的程序里提供了一些广告他们的连接,这其实就是ShellExeCute()的运用之一,略举一例:
procedure TForm1.HttpClick(Sender: TObject);
begin
ShellExecute(handle,'open','http://liangming.163.net',
nil,nil,SW_ShowNormal);
end;