您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 国内外标准规范 > 经典Win32 API讲座
Win32API讲座第一课∶认识API一、什么是API首先,有必要向大家讲一讲,什么是API。所谓API本来是为C和C++程序员写的。API说来说去,就是一种函数,他们包含在一个附加名为DLL的动态连接库文件中。用标准的定义来讲,API就是Windows的32位应用程序编程接口,是一系列很复杂的函数,消息和结构,它使编程人员可以用不同类型的编程语言编制出的运行在Windows95和WindowsNT操作系统上的应用程序。可以说,如果你曾经学过VC,那么API对你来说不是什么问题。但是如果你没有学过VC,或者你对Windows95的结构体系不熟悉,那么可以说,学习API将是一件很辛苦的事情。如果你打开WINDOWS的SYSTEM文件夹,你可以发现其中有很多附加名为DLL的文件。一个DLL中包含的API函数并不只是一个,数十个,甚至是数百个。我们能都掌握它嘛?回答是否定的∶不可能掌握。但实际上,我们真的没必要都掌握,只要重点掌握Windos系统本身自带的API函数就可以了。但,在其中还应当抛开掉同VB本身自有的函数重复的函数。如,VB的etAttr命令可以获得文件属性,SetAttr可以设置文件属性。对API来讲也有对应的函数GetFileAttributes和SetFileAttributes,性能都差不多。如此地一算,剩下来的也就5、600个。是的,也不少。但,我可以敢跟你说,只要你熟悉地掌握100个,那么你的编程水平比现在高出至少要两倍。尽管人们说VB和WINDOWS具有密切的关系,但我认为,API更接近WINDOWS。如果你学会了API,首要的收获便是对WINDOWS体系结构的认识。这个收获是来自不易的。如果你不依靠API会怎么样?我可以跟你说,绝大多是高级编程书本(当然这不是书的名程叫高级而高级的,而是在一开始的《本书内容》中指明《本书的阅读对象是具有一定VB基础的读者》的那些书),首先提的问题一般大都是从API开始。因此可以说,你不学API,你大概将停留在初级水平,无法往上攀登。唯一的途径也许就是向别人求救∶我快死了,快来救救我呀,这个怎么办,那个怎么办?烦不烦呢?当然,现在网上好人太多(包括我在内,嘻嘻),但,你应当明白,通过此途径,你的手中出不了好的作品。这是因为缺乏这些知识你的脑子里根本行不成一种总体的设计构思。二、API文本游览器。很多API函数都是很长很长的。想看什么样子吗?如下就是作为例子的APIDdeClientTransaction函数∶DeclareFunctionDdeClientTransactionLibuser32(pDataAsByte,ByValcbDataAsLong,ByValhConvAsLong,ByValhszItemAsLong,ByValwFmtAsLong,ByValwTypeAsLong,ByValdwTimeoutAsLong,pdwResultAsLong)AsLong哇!这么长?如果你从来没有接触过API,我想你肯定被吓住了。你也许考虑,该不该继续学下去。不过不要担心,幸运的是Microsoft的设计家们为我们提供了有用的工具,这便是API文本查看器。通过API文本查看器,我们可以方便地查找程序所需要的函数声明、结构类型和常数,然后将它复制到剪贴板,最后再粘贴到VB程序的代码段中。在大多数情况下,只要我们确定了程序所需要的函数、结构和常数这三个方面后,就可以通过对API文本游览器的以上操作将他们加入到程序段中,从而程序中可以使用这些函数了。这些是学习API最基本的常识问题,它远远占不到API的庞大的体系内容。今后我们把精力浪费(这绝不是浪费)在哪里呢?那就是∶什么时候使用什么函数,什么时候使用什么结构类型,什么时候使用什么常数。三、API函数声明。让我们回想一下。在VB中,如何声明函数呢?我想,如果你正在看此文,那么你绝对能够回答得出这个问题。以下便是你应该很熟悉的函数声明∶FunctionSetFocus(ByValhwndAsLong)AsLong即,这行代码定义了名为SetFocus的函数,此函数具有一个Long型数据类型的参数,并按值传递(ByVal),函数执行后将返回一个Long型数据。API函数的声明也很类似,如,API中的SetFocus函数是这样写的∶DeclareFunctionSetFocusLibuser32AliasSetFocus(ByValhwndAsLong)AsLong有点复杂了一些。是的,是复杂了点。但我可以告诉你,除了这些多出来的部分,其他部分还是和你以前学到的东西是一样的。函数在程序中的调用也是一样。如:DimdlAsLongdl&=SetFoucs(Form1.Hwnd)但,一点是清楚的。它不象你自己写的程序那样能够看到里面的运行机理,也不像VB自带的函数那样,能够从VB的联机帮助中查到其用法。唯一的方法就是去学、查VB以外的资料。Declare语句用于在模块级别中声明对动态链接库(DLL)中外部过程的引用。对此,你只要记住任何API函数声明都必须写这个语句就可以了。Iib指明包含所声明过程或函数的动态链接库或代码资源。也就是说,它说明的是,函数或过程从何而来的问题。如在上例中,SetFocusLibuser32说明函数SetFocus来自user32.dll文件。主要的dll动态连接库文件有∶user32.dllWindows管理。生成和管理应用程序的用户接口。GDI32.dll图形设备接口。产生Windows设备的图形输出Kernel32.dll系统服务。访问操作系统的计算机资源。注意,当DLL文件不在Windows或System文件夹中的时候,必须在函数中说明其出处(路径)。如,SetFocusLibc:\Mydll\user32函数声明中的Alias是可选的。表示将被调用的过程在动态链接库(DLL)中还有另外的名称(别名)。如,AliasSetFocus,说明SetFocus函数在User32.dll中的另外一个名称是,SetFocus。怎么两个名都一样呢?当然,也可以是不同的。在很多情况下,Alias说明的函数名,即别名最后一个字符经常是字符A,如SetWindowsText函数的另一个名称是SetWindowsTextA,表示为AliasSetWindowsTextA。这个A只不过是设计家们的习惯的命名约定,表示函数属于ANSI版本。那么,别名究竟有什么用途呢?从理论上讲,别名提供了用另一个名子调用API的函数方法。如果你指明了别名,那么尽管我们按Declare语句后面的函数来调用该函数,但在函数的实际调用上是以别名作为首要选择的。如,以下两个函数(Function,ABCD)声明都是有效的,他们调用的是同一个SetFocus函数∶DeclareFunctionSetFocusLibuser32SetFocus(ByValhwndAsLong)AsLongDeclareABCDSetFocusLibuser32AliasSetFocus(ByValhwndAsLong)AsLong需要注意的是,选用Alias的时候,应注意别名的大小写;如果不选用Alias时的时候,函数名必须注意大小写,而且不能改动。当然,在很多情况下,由于函数声明是直接从API文本游览器中拷贝过来的,所以这种错误的发生机会是很少的,但您有必要知道这一点。最后提醒你一句,API声明(包括结构、常数)必须放在窗体或模块的通用(GeneralDeclarations)段。四、数据类型与类型安全API函数中使用的数据类型基本上和VB中的一样。但作为WIN32的API函数中,不存在Integer数据类型。另外一点是在API函数中看不到Boolean数据类型。Variant数据类型在API函数中是以Any的形式出现,如DataAsAny。尽管其含义是允许任意参数类型作为一个该API函数的参数传递,但这样做存在一定的缺点。其原因是,这将会使得对目标参数的所有类型检查都会被关闭。这自然会给各种类型的参数调用带来了产生错误的机会。为了强制执行严格的类型检查,并避免上面提到的问题,一个办法是在函数里使用上面提到到Alias技术。如对API函数GetDIBits可进行另外一种声明方法。如下∶GetDIBits函数的原型∶PublicDeclareFunctionGetDIBitsLibgdi32AliasGetDIBits(ByValaHDCAsLong,ByValhBitmapAsLong,ByValnStartScanAsLong,ByValnNumScansAsLong,lpBitsAsAny,lpBIAsBITMAPINFO,ByValwUsageAsLong)AsLongGetDIBits函数的改型∶PublicDeclareFunctionGetDIBitsLongLibgdi32AliasGetDIBits(ByValaHDCAsLong,ByValhBitmapAsLong,ByValnStartScanAsLong,ByValnNumScansAsLong,lpBitsAsLong,lpBIAsBITMAPINFO,ByValwUsageAsLong)AsLong通过本课程前面所学到的知识,我们已经可以得知原型GetDIBits函数也好,改型GetDIBitsLong函数也好,实际将调用的都是Alias所指定的GetDIBits原函数。但你应当看到,两者的区别在于,我们在改型的函数中强制指定lpBits参数为Long形。这样就会使得函数调用中发生的错误机率减少到了最小。这种方法叫做安全类型声明。API函数中经常看到的数据类型有∶Long,String,Byte,Any....(也就这些吧。)五、常数对于API常数来讲,没有什么太特别的学问。请看VB中的以下代码∶Msg=MsgBox(您好,vbOKCancel)我们知道,vbOKCancel这个常数的值等于1。对上面的代码我们完全可以这样写,而不会影响代码的功能∶Msg=MsgBox(您好,1)但你大概不太愿意选择后一种,因为这会使得看懂代码费劲起来。这种方法也被API采取了。只是API常数必须在事情之前做好初始化声明VB本身是看不懂的。其内容仍然来自与API文本游览器。具体形式如下等等∶PublicConstABM_ACTIVATE=&H6PublicConstRIGHT_CTRL_PRESSED=&H4PublicConstRPC_E_SERVER_DIED=&H80010007PrivateConstRPC_S_CALL_FAILED_DNE=1727&在常数的初始化中,有些程序使用Global,如GlobalConstABM_ACTIVATE=&H6,但我认为Public完全可以代替它。过去我也用过Global,但现在不大用了。一会儿用这个,一会儿用那个,各程序之间不能保持一致性了,起码看起来别扭。六、结构结构是C和C++语言中的说法。在VB中一般称为自定义数据类型。想必很多朋友都已经认识它。在API领域里,我更喜欢把它叫做结构,因为API各种结构类型根本不是我定义(自定义)的。在VB中,API结构同样由TYPE.......ENDTYPE语句来定义。如,在API中,点(Point)结构的定义方法如下:PublicTypePOINTAPIXAsLong'点在X坐标(横坐标)上的坐标值YAsLong'点在Y坐标(纵坐标)上的坐标值EndType又如,API中矩形(Rect)结构的定义如下∶PublicTypeRECTLeftAsLong'矩形左上角的X坐标TopAsLong'矩形左上角的Y坐标RightAsLong'矩形右下角的X坐标BottomAsLong'矩形右下角的Y坐标EndType这些内容同样可以从API文本游览器中拷贝过来。这些结构中的变量名可随意改动,而不会影响结构本身。也就是说,这些成员变量都是虚拟的。如,POINTAPI结构可改为如下∶PublicTypePO
本文标题:经典Win32 API讲座
链接地址:https://www.777doc.com/doc-1085313 .html