分享
 
 
 

充分利用Windows API扩展Delphi函数

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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

调试通过)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有