如何在自己的系統中打開(kāi)并關(guān)閉外部程序
大家知道,在一個(gè)大型復雜的系統中,有時(shí)會(huì )調用一些外部程序來(lái)幫助我們完成某些特定功能。
然而,如何打開(kāi)并關(guān)閉這些外部程序呢?也許,這是一個(gè)老生常談的話(huà)題,但筆者仍要繼續討論這個(gè)問(wèn)題,原因有二:一是解決這個(gè)問(wèn)題的方法很重要,并經(jīng)常會(huì )遇到;二是大多數參考書(shū)提及的解決辦法不全面,仍有很多朋友有疑問(wèn)。下面,我將詳細地闡述這個(gè)問(wèn)題(提供的源代碼均在WinNT/Delphi4.0環(huán)境下運行通過(guò))。
一、如何打開(kāi)一個(gè)外部程序:
我們常用的函數有兩個(gè),WinExec(),ShellExecute(),因為ShellExecute()函數主要用于Win32下,功能也強大一些,故而本文只對后者進(jìn)行討論。
首先,我們粗略地研究一下ShellExecute()的幾個(gè)參數:
hwnd:窗體的句柄;
lpOperation:打開(kāi)程序執行的操作,共預留有“open”、“explore”、“print”三種方式,此參數可以省略,此時(shí)將依據打開(kāi)的文件(lpFile)的類(lèi)型執行相應的操作,比如:如果lpFile為一文本文件,那么將會(huì )在與該文件相關(guān)聯(lián)的程序中打開(kāi)它;
lpFile:文件名;
lpParamerters:打開(kāi)文件時(shí)所需的參數;
lpDirectory:文件名所在的路徑,當然,一般來(lái)說(shuō),在Windows中登“記記”過(guò)的程序(如WinWord)不必提供此參數;
nShowCmd:打開(kāi)文件后程序窗體如何顯示。
該函數的詳細文檔請讀者朋友參閱相應幫助。
其次,我們來(lái)舉一個(gè)例子(以“記事本”為例):
procedure TForm1.OpenBtnClick(Sender:TObject);
begin
ShellExecute(handle,'open','notepad.exe',nil,nil,SW_ShowNormal);
end;
讀者朋友可以在你的Delphi環(huán)境下試試這段代碼,當然,由于使用Windows的API函數,請加上ShellAPI單元。
二、如何關(guān)閉打開(kāi)的外部程序:
要關(guān)閉一個(gè)外部程序,只需向他發(fā)送一條消息就行了,比如,SendMessage(ExeHandle,WM_Close,0,0);
其中ExeHandle是程序窗體的句柄,但如何得到窗體句柄呢?這是最為關(guān)鍵的地方,幸好Windows提供
了FindWindow()函數,它能夠解決這個(gè)問(wèn)題,它有兩個(gè)參數:
lpClassName:程序的類(lèi)名;
lpWindowName:程序窗體的標題。
第一種情況也是最簡(jiǎn)單情況的就是提供確定的[*“確定的”加著(zhù)重號*]“lpWindowName”參數,如下例:
procedure TForm1.CloseAppClick(Sender: TObject);//確定標題
var Exehandle:Thandle;
begin
//獲得句柄-->標題確定
ExeHandle:=findWindow(nil,'文件管理器');//返回句柄
//關(guān)閉程序
if ExeHandle<>0 then
SendMessage(ExeHandle,WM_Close,0,0)
else
Application.MessageBox('沒(méi)有打開(kāi)“文件管理器”!','提示', MB_IconInformation+MB_OK);
end;
另一種情況是程序窗體沒(méi)有確定的[*“沒(méi)有確定的”加著(zhù)重號*]標題,這就是很多朋友出現疑問(wèn)的地方,也是幾乎所有參考書(shū)均不涉及的地方。比如打開(kāi)“寫(xiě)字板”程序,它的標題會(huì )隨著(zhù)文本文件名的不同而不同,此時(shí),你要關(guān)閉它,就不得不提供程序的類(lèi)名,但是如何獲得程序的類(lèi)名呢?筆者在這里向大家介紹一個(gè)可行的辦法:首先打開(kāi)程序(此處以“記事本”為例),然后,運行WinSight32(Delphi自帶)或Spy++(VC自帶),找到程序(“記事本”)的運行狀態(tài),即可找到我們需要的類(lèi)名(兩者均為“Class Name”項)。參考一個(gè)例子:
procedure TForm1.CloseVAppClick(Sender: TObject);//標題不確定
var ExeHandle:Thandle;
begin
//獲得句柄-->標題不確定
ExeHandle:=FindWindow('notepad',nil);//'');//返回句柄
//關(guān)閉程序
if ExeHandle<>0 then
SendMessage(ExeHandle,WM_Close,0,0)
else
Application.MessageBox('沒(méi)有打開(kāi)“記事本”程序!','提示', MB_IconInformation+MB_OK);
end;
當然,既能提供程序的類(lèi)名又能提供程序窗體的標題自然就沒(méi)有討論的必要了。
這樣,我們就可以在自己的程序中打開(kāi)并關(guān)閉任意的外部程序了。
另外,筆者在這里羅嗦一句:上文提到的ShellExeCute()還有有相當“豪華”的用處!細心的讀者可能注意到有的作者的程序里提供了一些廣告他們的連接,這其實(shí)就是ShellExeCute()的運用之一,略舉一例:
procedure TForm1.HttpClick(Sender: TObject);
begin
ShellExecute(handle,'open','http://liangming.163.net',
nil,nil,SW_ShowNormal);
end;