充分利用Windows API扩展Delphi函数

充分利用Windows API扩展Delphi函数
                      袁卫国



    Borland Delphi是与Visual Basic相似的可视化开发工具,但其功能比VB更加强大。
例如,Delphi支持汇编语言和指针操作、全面支持Windows API函数及外部DLL的使
用,使得它具有更广泛的应用范围。即使用于编制一些较小的应用程序,Delphi与VB
相比看来不相上下,
但由于Delphi是编译型的语言,其编译后的EXE文件可以真正脱
离Delphi的环境独立运行,而VB 生成的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函数格式的描述:WORD 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
调试通过)

Creating Windows CreateMDIWindow CreateWindow CreateWindowEx RegisterClass RegisterClassEx UnregisterClass Message Processing BroadcastSystemMessage CallNextHookEx CallWindowProc DefFrameProc DefMDIChildProc DefWindowProc DispatchMessage GetMessage GetMessageExtraInfo GetMessagePos GetMessageTime GetQueueStatus InSendMessage PeekMessage PostMessage PostQuitMessage PostThreadMessage RegisterWindowMessage ReplyMessage SendMessage SendMessageCallback SendMessageTimeout SendNotifyMessage SetMessageExtraInfo SetWindowsHookEx TranslateMessage UnhookWindowsHookEx WaitMessage Window Information AnyPopup ChildWindowFromPoint ChildWindowFromPointEx EnableWindow EnumChildWindows EnumPropsEx EnumThreadWindows EnumWindows FindWindow FindWindowEx GetClassInfoEx GetClassLong GetClassName GetClientRect GetDesktopWindow GetFocus GetForegroundWindow GetNextWindow GetParent GetProp GetTopWindow GetWindow GetWindowLong GetWindowRect GetWindowText GetWindowTextLength IsChild IsIconic IsWindow IsWindowEnabled IsWindowUnicode IsWindowVisible IsZoomed RemoveProp SetActiveWindow SetClassLong SetFocus SetForegroundWindow SetParent SetProp SetWindowLong SetWindowText WindowFromPoint Processes and Threads CreateEvent CreateMutex CreateProcess CreateSemaphore CreateThread DeleteCriticalSection DuplicateHandle EnterCriticalSection ExitProcess ExitThread GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetExitCodeProcess GetExitCodeThread GetPriorityClass GetThreadPriority GetWindowThreadProcessId InitializeCriticalSection InterlockedDecrement InterlockedExchange InterlockedIncrement LeaveCriticalSection OpenEvent OpenMutex OpenProcess OpenSemaphore PulseEvent ReleaseMutex ReleaseSemaphore ResetEvent ResumeThread SetEvent SetPr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值