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