充分利用Windows API擴充套件Delphi函式 (轉)

worldblog發表於2007-12-03
充分利用Windows API擴充套件Delphi函式 (轉)[@more@]

充分利用 擴充套件
  袁衛國



  Borland Delphi是與相似的視覺化開發工具,但其功能比VB更加強大。
例如,Delphi支援語言和指標操作、全面支援Windows API函式及外部DLL的使
用,使得它具有更廣泛的應用範圍。即使用於編制一些較小的應用,Delphi與VB
相比看來不相上下, 但由於Delphi是編譯型的語言,其編譯後的EXE可以真正脫
離Delphi的環境獨立執行,而生成的EXE檔案離開了VB包的一大堆DLL、
VBX等檔案可能會無法。而更重要的是,一般往往並不真正知道自己開發
的VB程式到底使用了哪些DLL一類的檔案,為了保證程式的正常執行,可能在最後的
盤中包含了不少其實並不需要的檔案。所以,一般使用者用VB很難開發出真正實
用的軟體,難怪有人說VB是"先甜後苦"。Delphi實際上可以看作是VP(Visual Pascal),所
以它的易學性也可與VB媲美。今年釋出的Delphi2.0可以為Windows 95、Window s NT
開發32位程式,使得VB 4.0的優勢也不復存在。看來,在今後一段時間內,將會有更多
的人使用Delphi開發Windows應用程式。在DOS下開發過軟體的人都知道int 2lh的重要。
與此類似,Windows應用程式也是離不開Windows API的,許多較底層的操作必須透過
API函式來實現。為此,無論是C++、VB還是Delp hi都無一例外地支援API函式的調
用,只是VB由於自身的特點所限制,僅支援部分API函式,而C++、Delphi則全面地支援
API函式。相比之下,Delphi對API函式的最簡捷,達到了與自身的內部函式幾乎
不分彼此的程度(只要求在interfaces中的user段中加上Windows即可,而這一步Delphi
會自動為您做到),VB則相當繁瑣。以呼叫獲得Windows子目錄的API函式為例
,我們來看一下二者有什麼不同:API函式格式的描述: GetSystemDirectory(lpBuffer,
nSize)
  VB 4.0呼叫時首先要做如下申明:
  Declare Function GetSystemDirectory Lib"kernel32"(ByVal
lpBuffer As String, ByValnSize As Long)As Long
  然後才能使用:
  Dim lpBuffer As String *255
  Size&=GetSystemDirectory(lpBuffer,255)
  而Delphi只需像呼叫內部函式那樣:
  var lpBuffer:PChar;{API函式必須使用null結尾的字串}
  Size:WORD;{返回的系統子目錄字串實際長度}
  begin lpBuffer:=StrAlloc(255);{預留字串長度}
  Size:=GetSystemDirectory(lpBuffer,255);end;
  由此可見,Delphi是可以充分利用Windows API來擴充套件其自身功能的。當然,在大
多數情況下,Delphi本身的函式功能已經足夠使用了。但是,在有些情況下,需要使
用API函式來實現一些特殊的功能或完善Delphi的一些功能。下面提供兩個例項
來說明這一點。
  一、資訊框函式MsgBox
  資訊框是Windows應用程式中使用得較多的一種對話機制,它被廣泛地用於提
示、選擇程式走向,是一個重要的程式控制手段。Delphi提供的資訊框函式MessageDlg
功能比較強,其最大優點是可以任意設定資訊框的按鈕(使用了集合型別),但其缺
點也是很明顯的,主要表現在標題字串不能由使用者自己設定;視窗彈出時寂靜無聲
;按鈕不能隨著Windows的不同語言的版本顯示不同的文字(例如無論在哪種語言版
本下都只能顯示"OK"、"Yes"等英文字元)。這些優點和缺點都是由於它是Delphi
自己實現的,而不是透過呼叫系統API函式實現的,故不能使用系統的語言環境、
多等資源。這樣,所開發的程式在中文版中顯示資訊框時與周圍的視窗顯得
極不協調。而VB在這方面卻做得較好,所以我們按照VB的格式自定義一個資訊
框函式MsgBox。下面的函式都假定是在TForml中定義的。為了使用方便,我們首
先在Interfaces段中定義一些符號常量:
  const
  {第一組:按鈕內容選擇}
  OKOnly=0;{僅顯示"確定"按鈕}
  OKCancel=1;{顯示"確定"和"取消"按鈕}
  AbortRetryIgnore=2;{"中止""重試""放棄"}
  YesNoCancel=3;{"是""否""取消"}
  YesNo=4;{"是"和"否"}
  RetryCancel=5;{"重試""取消"}
  {第二組:顯示圖示選擇}
  Critical=16;{"STOP"圖示}
  Question=32;{"?"圖示}
  Excalamation=48;{"!"圖示}
  Information=64;{"i"圖示}
  {第三組:預設指標位置(啟用狀態)}
  DefaultButton1=0;{第一按鈕}
  DefaultButton2=256{第二按鈕}
  DefaultButton3=512{第三按鈕}
  {第四組:資訊框方式}
  ApplicationModal=0;{應用方式}
  SystemModal=4096;{系統方式}
  然後,建立函式MsgBox,由於API函式中使用的字串必須以mull結尾,所以使用了另
一個自定義的函式StrToPch來將Pascal型別字串轉換成為以mull結尾的字串。參
數說明 msg為資訊框標題變數; mbType為規定資訊框型別的變數,使用方式是"mbType=
按鈕內容+圖示+預設指標+資訊框方式"。便如您想得到一個含"確定"和"取消"兩個按
鈕、帶"?"圖示、預設指標指向第二個按鈕(即"取消")的資訊框,那麼就該這樣設定:
mbType:=OKCancel+Question+DefaultButton2;
  title為資訊框中顯示文字的變數。
  MsgBox的返回值與MessageDlg函式的返回值完全一樣,例如返回mrYes表示"Yes"或
"是" 按鈕被按下,mrNo表示"No"或"否"按鈕被按下等等。可參考MessageDlg函式的說
明。下面即是在Delphi中透過呼叫Windows API的GetActive Windows函式和MessageBox
函式來實現MsgBox函式的程式碼:{資訊框函式}
  function TForm1.MsgBox(msg:string;mbType:Word;title:stri
ng):Word;
  var hWnd:HWND;
  1pText,!pCaption:Pchar;
  begin
  1pText:=StrToPch(title);
  1pCaption=StrToPch(msg);
  hWnd:=GetActiveWindow();
  MsgBox:=MessageBox(hWnd,1pText,1pCaption,mbType);
  end;
  {將Pascal字串轉換成null結尾字串函式}
  function TForm1.StrToPch(Str:string):PChar;
  var
  a:PChar;
  begin
  a:=StrAlloc(Length(Str)+1);
  StrPCopy(a,Str);
  StrToPch:=a;
  end;

  二、檔案複製函式CopyFDelphi提供了一組比較完整的檔案操作函式,用它們可以完
成幾乎全部的檔案操作,但恰恰缺少複製檔案的函式。而檔案複製的使用應該說是比
較常用的,因此,筆者利用幾個API函式定義了一個功能很強的檔案複製函式CopyF。
該函式程式碼如下(請注意:該函式中呼叫了上述的MsgBox函式):
  {檔案複製函式}
  function TForm1.CopyF(var ExistingFileName:string;const
NewFileName:string; var Mode:Integer):Boolean;
  var
  EFile,NFile:PChar;
  CpFlag,FailIfExists:Boolean;
  msg:string;
  ErrID,mbType:integer;
  begin
  EFile:=StrToPch(ExistingFileName);
  NFile:=StrToPch(NewFileName);
  if (Mode=1) or (Mode=3) then FailIfExists:=True
  else FailIfExists:=False;
  CpFlag:=CopyFile(EFile,NFile,FailIfExists);
  if not CpFlag then
  begin
  ErrID:=GetLastError();
  ExistingFileName:=SysErrorMessage(ErrID);
  if Mode<2 then
  begin
  msg:='CopyFile Error!';
  mbType:=OKOnly+Excalamation;
  MsgBox(msg,mbType,ExistingFileName);
  end;
  Mode:=ErrID;
  end;
  CopyF:=CpFlag;
  end;
  CopyF函式引數說明如下:
  若複製操作成功,函式CopyF返回True,失敗函式CopyF返回False。
  ExistingFileName是字元變數,輸入時代表原始檔名。若操作失敗,則返回錯誤資訊字元
串(由於呼叫了API函式,在中文Windows下該資訊當然就是中文)。 NewFileName是字元
常量,代表目標檔名。
  Mode是整數變數,輸入時代表複製的方式:
  0表示如果目標檔案存在,將覆蓋它,操作失敗,將顯示具有出錯信
息的資訊框;
  1表示如果目標檔案存在,不覆蓋它,操作失敗,顯示具有出錯資訊
的資訊框;
  2表示如果目標檔案存在,將覆蓋它,操作失敗,不顯示資訊框;
  3表示如果目標檔案存在,不覆蓋它,操作失敗,不顯示資訊框;
  當複製操作失敗時,Mode將返回出錯程式碼。
  總之,靈活應用API函式可以使您的應用程式的介面與您使用的Windows的語言環境相
當和諧地融為一體,擺脫掉Delphi的痕跡,使您的程式給人以相當"專業"的感覺。最後說明
一點,如果要使這些自定義的函式成為"全域性"的,在其它單元中也能夠使用,需將函式標題
複製到Unitl單元interfaces的type段中(應刪除"TForml."幾個字元);然後在呼叫函式的其他單
元implementation中的user段中加入Unitl;在函式名前要加上"Form1."幾個字元,如在Unit2單
元中呼叫MsgBox就應寫成Form1.MsgBox。
  (以上所有函式均在Windows 95中文版使用Delphi Desktop V2.0
透過)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987686/,如需轉載,請註明出處,否則將追究法律責任。

相關文章