首页 API函数快速入门API函数简介

API函数快速入门API函数简介

举报
开通vip

API函数快速入门API函数简介API函数快速入门API函数简介      作为一个编程初学者来说,API函数也许是一个时常耳闻却感觉有些神秘的东西。单看它的复杂语法,就足令人望而生畏,但是任何事物在我们深入了解它之前,总是会有这种感觉的。我们这篇API入门教程的目的,就是要把API函数的来龙去脉告诉大家,破除对API函数的畏惧,使它成为我们编程的好助手。 大家可能在许多书上看到过API的英文全称(ApplicationProgrammingInterface),WIN32API也就是MicrosoftWindows32位平台的应用程序编...

API函数快速入门API函数简介
API函数快速入门API函数简介      作为一个编程初学者来说,API函数也许是一个时常耳闻却感觉有些神秘的东西。单看它的复杂语法,就足令人望而生畏,但是任何事物在我们深入了解它之前,总是会有这种感觉的。我们这篇API入门教程的目的,就是要把API函数的来龙去脉告诉大家,破除对API函数的畏惧,使它成为我们编程的好助手。 大家可能在许多书上看到过API的英文全称(ApplicationProgrammingInterface),WIN32API也就是MicrosoftWindows32位平台的应用程序编程接口。对这个定义的理解,需要追溯到操作系统的发展历史上,当WINDOWS操作系统开始占据主导地位的时候,开发WINDOWS平台下的应用程序成为人们的需要。而在WINDOWS程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 领域处于发展的初期,WINDOWS程序员所能使用的编程工具唯有API函数,这些函数是WINDOWS提供给应用程序与操作系统的接口,他们犹如“积木块”一样,可以搭建出各种界面丰富,功能灵活的应用程序。 所以可以认为API函数是构筑整个WINDOWS框架的基石,在它的下面是WINDOWS的操作系统核心,而它的上面则是所有的华丽的WINDOWS应用程序。 但是,那时的WINDOWS程序开发还是比较复杂的工作,程序员必须熟记一大堆常用的API函数,而且还得对WINDOWS操作系统有深入的了解。然而随着软件技术的不断发展,在WINDOWS平台上出现了很多优秀的可视化编程环境,程序员可以采用“即见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。 这些优秀可视化编程环境操作简单、界面友好(诸如VB、VC++、DELPHI等),在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能,事实上这些类库和控件都是构架在WIN32API函数基础之上的,是封装了的API函数的集合。它们把常用的API函数的组合在一起成为一个控件或类库,并赋予其方便的使用方法,所以极大的加速了WINDOWS应用程序开发的过程。有了这些控件和类库,程序员便可以把主要精力放在程序整体功能的设计上,而不必过于关注技术细节。 实际上如果我们要开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数,虽然类库和控件使应用程序的开发简单的多,但它们只提供WINDOWS的一般功能,对于比较复杂和特殊的功能来说,使用类库和控件是非常难以实现的,这时就需要采用API函数来实现。这也是API函数使用的场合,所以我们对待API函数不必刻来研究每一个函数的用法,那也是不现实的(能用的到 的API函数有几千个呢)。正如某位大虾所说:API不要去学,在需要的时候去查API帮助就足够了 API函数在VB中的应用 所谓API就是“应用程序接口”(ApplicationProgramingInterface),是一些用C语言编写,由操作系统自身调用的函数。WindowsAPI函数由许多“动态链接库”或DLL组成。在32位Windows中,核心的WindowsAPIDLL有如下一些: gdi32.dll----图形显示界面的API。 kernel32.dll----处理低级任务(比如内存和任务管理)的API。 user32.d11----处理窗口和消息(VisualBasic程序员能把其中一些当作事件访问)的API。 还不断有新的API出现,处理新的操作系统扩展,比如E-MAIL、联网和新的外设。 由于WindowsAPI函数不是VisualBasic的内部函数,所以在使用它们之前必须显式地加以声明。要想得到正确格式化的函数声明,可以访问WINAPI目录下的文件WIN32API.TXT。 本文只对Win95系统的API函数加以说明并调用Win95的内置功能。 重新启动计算机的实现 在Windows下安装过程序的用户可能都有这样的体会,当安装完某些应用程序后,安装程序会要求重新启动计算机以使设置生效。那么,如果要用VB程序重新启动计算机该如何实现呢?其实利用ExitWindowsEx函数即可。 程序的编写 1.首先运行VB,然后新建一个工程(工程类型为标准EXE),然后双击Form1窗体,进入代码(Code)输入框, 在其中输入: Private Declare Function ExitWindowsEx Lib "user32"(ByVal uFlags As Long,ByVal dwReserved As Long) As Long 2.点击“工具箱”中的commandbutton(命令按钮)工具,即可在窗体Form1中加入一个命令按钮,然后将该按钮属性中的Caption值定义为“重新启动”。完成之后双击该按钮,进入代码(code)输入框输入以下代码: Private Sub Command1_Click() ExitWindowsEx&H43,0 EndSub 程序的执行 程序输入完成后,点击VB“运行”菜单中的“启动”或“全面编译”命令,然后点击“重新启动”按钮,即可重新启动计算机。 磁盘格式化 在Windows9X中,当用鼠标右键单击“我的电脑”中的“3.5软盘A”然后在出现的右键菜单中选择“格式化”选项,就将弹出标准的“磁盘格式化”窗口。下面我们来看看如何在应用程序中利用函数轻松调用Windows95标准的“磁盘格式化”窗口,实现对磁盘相应的操作功能。 程序的编写 1.与上例相同,首先运行VB,新建一个标准工程,然后利用“工具箱”在Form1窗体中加入一个命令按钮对象,将该命令按钮属性中的Caption值定义为“软盘格式化”。完成之后双击该按钮,在代码输入框中输入以下代码: Private Sub Command1_Click() Call FormatFloppy'调用FormatFloppy过程 EndSub 2.然后用鼠标右击窗体,选择右键菜单中的“添加/添加模块”选项,然后在出现的选择框中选择“模块”类型,接着在出现的模块代码输入框中加入以下代码:(注:模块是指一组声明的集合,其后为过程) '通用声明 Public Const WM_CLOSE=&H10 Declare Function FindWindow Lib "user32" Alias "FindWindowA"(ByVal lpClassName As Any,ByVal lpWindowNameAsAny)AsLong DelareFunctionGetWindowsDirectoryLib"kernel32"Alias"GetWindowsDirectoryA"(ByVallpBuffer As String,ByVal nSize As Long) As Long Declare Function SetWindowPos Lib "user32"(BvVal hwnd As Long ByVal hWndInsertAfter As Long, ByVal X As long,ByVal y As Long,ByVal cx As Long,ByVal cy As Long,ByVal wFlags As Long) As Long Declare Function GetDesktopWindow Lib "user32"() As Long Declare Function LockWindowUpdate Lib "user32"(ByVal hwndLock As Long) As Long Declare Function GetWindowRect Lib "user32"(ByVayhwnd As Long,lpRect As RECT) As Long Declare Sub Sleep Lib "kernel32"(ByVal dwMilliseconds As Long) Type RECT Left As Long Top As Long Right As Long Bottom As Long EndType Type POINTAPI X As Long y As Long EndType Const SWP_NOSIZE=&H1 Const SWP_NOZORDER=&H4 'FormatFloppy()过程声明 Public Sub FormatFloppy() Dim sBuffer As String,Windir As String,Procs As String,X Dim lResult As Long sBuffer=String$(255,0) lResult=GetWindowsDirectory(sBuffer,Len(sBuffer)) Windir=Trim(sBuffer) Procs=Left(Windir,lResult)&"\rundll32.exeshell32.dll,SHFormatDrive" CallCenterDialog("Format-3?Floppy(A:)") X=Shell(Procs,1) CallCenterDialog("Format-3?Floppy(A:)") k=LockWindowUpdate(0) EndSub 'CenterDialog过程声明 Public Sub CenterDialog(WinText As String) Do Events On Error Resume Next Dim D3 As Long D3=LockWindowUpdate(GetDesktopWindow()) Dim wdth% Dim hght% Dim Scrwdth% Dim Scrhght% Dim lpDlgRect As RECT Dim lpdskrect As RECT Dim hTaskBar As Long hTaskBar=FindWindow(0&,WinText) Call GetWindowRect(hTaskBar,lpDlgRect) wdth%=lpDlgRect.Right-lpDlgRect.Left hght%=lpDlgRect.Bottom-lpDlgRect.Top CallGetWindowRect(GetDesktopWindow(),lpdskrect) Scrwdth%=lpdskrect.Right-lpdskrect.Left Scrhght%=lpdskrect.Bottom-lpdskrect.Top X%=(Scrwdth%-wdth%)/2 y%=(Scrhght%-hght%)/2 Call SetWindowPos(hTaskBar,0,X%,y%,0,0,SWP_NOZORDEROrSWP_NOSIZE) Do Events EndSub 程序的执行 程序输入完成后,点击VB“运行”菜单中的“启动”或“全面编译”命令,点击“软盘格式化”按钮后选择要 格式化的容量,即可对3.5英寸盘进行格式化操作。 调用版本信息框 在Windows程序中,点击“帮助”菜单中的“关于XXX”选项后,就会弹出该程序的版本信息框。其实,在VB中,调用shellAbout函数不但可以实现标准的软件版本信息框,还可以随意更改其中的内容呢! 程序的编写 1.与前面类似,首先运行VB并新建一个标准工程,然后双击Form1窗口,在代码输入框中输入ShellAbout过 程代码: Private Declare Function ShellAbout Lib "shell32.dlI" Alias "ShellAboutA"(ByVal hWnd As Long,ByVal szApp As String,ByVal szOtherStuff As String,ByVal hIcon As Long) As Long 其中ShellAbout声明如下: HWnd设置窗口句柄,szApp设置窗口的“Caption”,szOtherStuff在“版权所有”和“使用权”之间的空白 处增加额外说明。 2.然后利用“工具箱”在Form1窗体中加入一个命令按钮对象,将该命令按钮属性中的Caption值定义为“版 本信息框”。完成之后双击该按钮,在代码输入框输入以下代码: Private Sub Command1_Click() Call ShellAbeut(hWnd,"何发武天使工作室!","版本信息框"&VbCrLf&"上帝与你同在!阿弥陀佛!",0) EndSub 程序的执行 程序输入完成后,点击VB“运行”菜单中的“启动”或“全面编译”命令,点击“版本信息框”按钮,即可查看当前软件的版本信息。 在Windows9X中,增加了一个全新的概念--“属性”,每个对象都拥有自己的“属性”,在“属性”窗口里是 关于对象的详细描述,并且不同的对象“属性”窗口的说明是不同的。我们可以用ShellExecuteEX函数直接调 用“属性”标准窗口。下面的程序功能相当于用鼠标右键单击根目录下的“Autoexec.bat”并选择“属性”时, 弹出的标准“属性”窗口。 程序的编写 1.首先运行VB,然后新建一个标准工程,然后利用“工具箱”在Form1窗体中加入一个命令按钮对象,将该命令 按钮属性中的Caption值定义为“属性按钮”。完成之后双击该按钮,在代码输入框中输入以下代码: Private Sub Command1_Click() Dim r As Long Dim FileName As String FileName="c:\autoexec.bat" r=ShowProperties(FileName,Me.hwnd) If r<=32 Then MsgBox"Error!NOc:\autoexec.batFile" EndSuB 2.然后用鼠标右击窗体,选择右键菜单中的“添加/添加模块”选项,然后在出现的选择框中选择“模块”类型,接着在出现的模块代码输入框中加入以下代码: '通用声明 Option Explicit Type SHELLEXECUTEINFO cbSize As long Fmask As Long hwnd As Long lpVerb As String lpFile As String lpParameters As String lpDirectory As String nShow As Long hInstApp As Long lpIDList As Long lpClass As String hkeyClass As Long dwHotKey As Long hIcon As Long hProcess As Long EndType Public Const SEE_MASK_INVOKEIDLIST=&HC Public Const SESE_MASK_NOCLOSEPROCESS=&H40 Public Const SEE_MASK_FLAG_NO_UI=&H400 Declare Function ShellExecuteEX Lib "shell32.dll" Alias "ShellExecuteEx"(SEI As SHELLEXECUTEINFO) As Long 'ShowProperties过程 Public Function ShowProperties(FileName As String,OwnerhWnd As Long) As Long Dim SEIASSHELLEXECUTEINFO Dim r As Long With SEI .cbSize=Len(SEI) .fMask=SEE_MASK_NOCLOSEPROCESSOrSEE_MASK_INVOKEIDLISTOrSEE_MASK_FLAG_NO_UI .hwnd=OwnerhWnd .lpVerb="properties" .lpFile=FileName .lpParameters=vbNullChar .lpDirectory=vbNullChar .nShow=0 .hInstApp=0 .lpIDList=0 EndWith r=ShellExecuteEX(SEI) ShowProperties=SEI.hInstApp EndFunction 程序的执行 程序输入完成后,点击VB“运行”菜单中的“启动”或“全面编译”命令,点击“属性按钮”按钮,即可查看C:\AUTOEXEC.BAT的属性 API函数快速入门怎样在VB中声明和使用API函数 一、在VB中声明API函数有两种方法:如果我们只在某个窗体中使用API函数,我们可以在窗体代码的General部分声明它: 声明的语法是: Private Declare Function... Private Declare Sub..... 这里必须采用Private声明,因为这个API函数只能被一个窗体内的程序所调用。如果我们的程序有多个窗体构成,而且我们需要在多个窗体中使用同一个API函数,就需要在模块中声明了。 先添加一个模块,然后采用如下语法声明: Public Declare Function.... Public Declare Sub.... Public声明的含义是把API函数作为一个公共函数或过程,在一个工程中的任何位置(包括所有的窗体和模块)都能直接调用它。声明完毕我们就能在程序中使用此API函数了。 二、可采用以下几种方式使用API函数,以SetWindowPos函数为例: (1)忽略函数返回值的调用: SetWindowPosForm1.hWnd,-2,0,0,0,0,3 注意此时函数的参数是不加括号的。 (2)Call方法调用: Call SetWindowPos(Form1.hWnd,-2,0,0,0,3) 注意这里需要加上括号,但我们不取回函数的返回值。 (3)取得函数返回值的调用: MyLng=SetWindowPos(Form1.hWnd,-2,0,0,0,3) 此时需要加上括号,而且我们必须事先定义一个变量(变量的类型与函数返回值类型相同)来存储API函数的返回值。 三、几个问题的说明: (1)声明中的Lib和Alias是怎么回事 一般情况下WIN32API函数总是包含在WINDOWS系统自带的或是其它公司提供的动态连接库DLL中,而Declare语句中的Lib关键字就用来指定DLL(动态连接库)文件的路径,这样VB才能找到这个DLL文件,然后才能使用其中的API函数。如果我们只是列出DLL文件名而不指出其完整的路径的话,VB会自动到.EXE文件所在目录、当前工作目录、WINDOWS\SYSTEM目录、WINDOWS目录下搜寻这个DLL文件。所以如果所要使用DLL文件不在上述几个目录下的话,我们应该指明其完整路径。 Alias用于指定API函数的别名,如果我们调用的API函数要使用字符串(参数中包含String型)的话,Alias关键字是必须的。这是因为在ANSI和Unicode字符集中同一API函数的名称可能是不一样的,为了保证不出现声明错误,我们使用Alias关键字指出API函数的别名,一般来说在WIN9X平台下我们把API函数名后加一个大写A作为别名即可。 (2)常见的API参数类型的说明 API函数的参数中最常见的是长整Long型数据类型,例如API中的句柄、一些特定的常量、函数的返回值都是此类型的值;另外几种常见的参数类型有:整型Integer、Byte型、String型等。 (3)声明中的ByVal是作什么用的 这跟VB的参数传递方式有关,在默认情况下VB是通过地址传递方式传递函数的参数、而有些API函数要求必须采用传值方式来传递函数参数(这两种参数传递方式是不同的,前者传递的是一个指针,而后者要求是参数真实的值)。这样就会发生错误,解决的办法是在API函数参数声明的前面加上ByVal关键字,这样VB就采用传值方式传递参数了。 (4)怎样得到完整的API函数声明 VB自带了API文本查看器APITEXTVIEWER,我们可以在其中找到API函数的完整声明,然后把它粘贴到程序中即可 API函数在VB开发中的应用     VB作为快速开发Windows下的编程工具,已经为越来越多的开发者采用。但如果要开发出专业的Windows软件,还需采用大量的API函数,以下结合笔者开发管理软件的经验谈几点体会。 程序中判定Windows的版本 众所周知,Windows3.x各版本或多或少会有些差别,为了使开发程序避免出现莫名其妙的错误,最好在程序运行前自动判定Windows的版本。采用API提供的函数getversion很容易实现这一点。函数声明如下: Declare Function GetVersion Lib "Kernel"() As Integer 此函数没有参数,返回值为Windows的版本号,其中版本号的低位字节为Windows的主版本号,版本号的高位字节返回Windows的次版本号。判别过程如下: Private Sub Form_Load() Dim ver As Integer Dim major As Integer Dim minor As Integer Ver=GetVersion() major=verAnd&HFF minor=(verAnd&HFF00)\256 Ifmajor<>3Andminor<>10Then MsgBox"版本不正确!" ExitSub EndIf EndSub 程序中判断Windows的安装目录 一般VB开发出来的程序包含vbrun300.dll等辅助文件和.vbx文件,它们均需安装到Windows目录(c:\windows)或Windows的系统目录(c:\windows\system)下,但因为用户安装Windows时可能会改变Windows的目录名(如c:\windows),使用安装软件后,不能正确运行.API中提供的GetwinDowsdirectory或GetSystemDirectory较好地解决了这个问题。函数声明如下: Declare Function GetSystemDirectory Lib "Kernel"(ByVal lpBuffer As String,ByVal nSize As Integer) As Integer 其中参数lpbuffer为字串变量,将返回实际Windows目录或Windows的系统目录,nsize为lpbuffer的字串变量的大小,函数返回值均为实际目录的长度。检查函数如下: Function checkdir() As Boolean Dim windir As String*200 Dim winsys As String*200 Dim winl As Integer Dim wins AsInteger Dim s1 As String Dim s2 As String winl=GetWindowsDirectory(windir,200) winl=GetSystemDirectory(winsys,200) s1=Mid$(windir,1,winl) s2=Mid$(winsys,1,wins) If Wins=0 Or wins=0 Then checkdir=False Exit Function EndIf Ifs1<>"C:\WINDOWS"Ors2<>"C:\WINDOWS\SYSTEM"Then checkdir=False ExitFunction EndIf checkdir=True EndFunction shell出现的问题 通常编程时要调用外部程序,VB提供了shell()函数,但是如果shell调用的外部程序找不到,则运行的程序失去控制,VB给出提示"filenotfound",改变这种现象,要在程序中加入onerrorgoto,比较麻烦,API函数中的winexec很好地解决了这个问题。函数声明如下: Declare FunctionWinExec Lib "Kernel"(ByVal lpCmdLine As String, ByVal nCmdShow As Integer) As Integer 其中lpCmdline为调用的外部文件名,NcmdShow为外部程序的运行状态,如隐藏窗口、最小化窗口等等。如返回值大于32 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示执行功能,否则返回错误码。例程如下: subcommand1_click dsiasinteger i=winexec("notepad.exe","c:\wst.txt",9) '参数9即SW_RESTORE,也就是激活并显示窗口 if i>32 then msgbox"调用正确!!" else msgbox"调用错误!!" endif endsub VB中访问API函数之防错技巧     功能强大的API(应用程序接口)函数对于VB程序员来说,不愧是很好的编程工具,然而使用API函数的程序员也许都遇到这样的现象。在VB集成环境下,程序运行后,出现一错误信息对话框,按确定键后系统自动退出VB集成环境,此时如果你的程序尚未存盘,那末很遗憾挽回损失已回天乏力。最后一次存盘之后的程序都不复存在。这是你对API函数使用不当引起的一般保护故障(GPF)。    当一个GPF错发生时,你应允许Windows关闭你的应用。有些情况下你可能需要退出Windows或者重新引导系统。出错程度视哪里内存被破坏而定。DLL(动态链接库)函数中的类型不一致等错误是GPF错的主要原因。这些错误会导致GPF甚至使Windows系统完全崩溃(需要重新引导系统)。下面谈避免GPF的一些技巧。 用别名来提供强类型检查是避免GPF的有效措施之一。有些情况下,DLL函数可以接受多种类型,LoadCursor函数就是这样一个例子,其定义如下: HCursorLoadCursor(hInstance,lpCursorName) 这里HCursor是一个指向光标对象的16位句柄,hInstance是一个16位实例句柄,lpCursorName是光标的名字或者是光标资源的32位整数ID。为了支持两种类型的lpCursorName参数。VB有必要包含如下两个声明: Declare Function LoadCursor Lib "USER"(ByVal hInstance As Integer,ByVal lpCursorName As String)As Integer 和 Declare Function LoadCursor Lib "USER"(ByVal hInstance As Integer,ByVal lpCursorName As Long)As Integer 但是,这两个声明不能在一个程序中同时存在,因为VisualBasic会报重复声明错。我们知道,AsAny声明可使得任何参数都可以传递给DLL函数,因此可以如下声明: Declare Function LoadCursor Lib "USER"(ByVal hInstance As Integer,ByVal lpCursorName As Any)As Integer 上述声明意味着VisualBasic能支持一个参数可接受多种类型的DLL函数,然而这就可能带来各种灾难性的后果,每当偶然情况下用不正确的参数调用该函数时,都可以引发一个GPF,我们可以这样进行严格的类型检查并且帮助防止这类问题。这种方法就是在函数的声明中使用Alias技巧,看看下面的两个声明: Declare Function LoadCursorByName Lib "USER" Alias "LoadCursor"(ByVal hInstance As Integer,ByVal lpCursorName As String)As Integer Declare Function LoadCursorByID Lib "USER" Alias "LoadCursor"(ByVal hInstance As Integer,ByVal lpCursorName As Long)As Integer LoadCursorByName用字符串做lpCursorName参数访问DLL函数LoadCursor,而LoadCursorByID访问同样的DLL函数LoadCursor,但是用长整型做lpCursorName参数,这两个函数都对lpCursorName参数进行严格的类型检查,使VisualBasic能在调用DLL函数之前识别出不正确的变量类型,最大限度地减少引起GPF或者导致系统崩溃的机会。 除此之外,使用API函数时运行之前最好先存盘,仔细检查调用API函数的参数与声明的类型是否一致,以及严格检查参数是否有效都能减少引发GPF或者系统崩溃 VB中调用Windows API的注意事项 VisualBasic(VB)作为一种高效编程环境,它封装了部分WindowsAPI函数,但也牺牲了一些API的功能。调用API时稍有不慎就可能导致API编程错误,出现难于捕获或间歇性错误,甚至出现程序崩溃。要减少API编程错误,提高VB调用API时的安全性,应重点注意下列八个问题: (1)指定“OptionExplicit” 编程前最好将VB编程环境中的“RequireVariableDeclaration(要求变量申明)项选中。如果该项未被指定,任何简单的录入错误都可能会产生一个“Variant”变量,在调用API时,VB对该变量进行强制转换以避免冲突,这样一来,VB就会为字符串、长整数、整数、浮点数等各种类型传递NULL值,导致程序无法正常运行。 (2)注意VB整数和Win32整数的区别 在VB环境下,涉及到的所有integer(整型数),都是16位,而一旦涉及C/C++Win32文档时,则是32位,阅读与WindowsAPI函数或与32位动态链接库有关的资料或应用程序时,尤其要注意 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 理解环境背景,以利于分清数据类型和数据结构,正确地声明API函数。 (3)减少和避免使用AsAny 虽然用AsAny的方法声明库,可使WindowsAPI函数能接受多种类型的参数,但更严重的是,即使是一个很小的错误,比如遗漏类型标识符或错误地使用了ByVal关键字,都可能导致系统崩溃或很难发现的其他数据错误。 (4)注意检查参数类型 API错误中,除了因遗漏ByVal关键字导致的错误外,大约有50%是因为声明中有不正确的参数类型。在Win32环境下,无论是8位、16位,还是32位数值变量都是以32位传递,如果同时使用,则很难发现其中错误。如果声明的参数类型不同,被VB视为Variant传递给API函数,会出现“错误的DLL调用规范”的消息。 (5)勿忘ByVal,确保函数声明的完整性 ByVal是“按值”调用,参数传递时,不将指向DLL的指针传递给参数变量本身,而是将传递参数值的一份拷贝传递给DLL。比如传递字符串参数时,VB与DLL之间的接口支持两种类型的字符串,如未使用ByVal关键字,VB将指向DLL的函数指针传递给一个OLE2.0字符串(即BSTR数据类型),而WindowsAPI函数往往不支持这种数据类型,导致错误。而使用ByVal关键字后VB将字符串转变换成C语言格式的“空终止”串,被API正确使用。 (6)重新检查函数名 在Win16环境下,API函数的名字不要求区分大小写,而在Win32环境下,则有此要求。在一个DLL函数里找不到声明的函数时,有必要检查一下函数名,对于管理字符串的函数,是否遗漏了A和W前缀。 (7)预先初始化字符串,以免造成冲突 如果API函数要求一个指向缓冲区的指针,以便从中载入数据,而此时传递的是字符串变量,应该先初始化字符串长度。因为API无法知道字符串的长度——API默认已为其分配有足够的长度。没有初始化字符串,分配给字符串的缓冲区有可能会不足,API函数将有可能在缓冲区末尾反复改写,内存里字符串后面的内容将会改写得一塌糊涂。程序表现为突然终止或间歇性错误。 (8)跟踪检查参数、返回类型和返回值 VB具有立即模式和单步调试功能,利用这个优势,确保函数声明的类型明确(API不返回Variant类型),通过跟踪和检查参数的来源及类型,可以排除参数的错误传递。许多API函数都有返回结果,指出自己是否执行成功。你若要对返回结果进行测试,用VB的Err对象的LastDllError方法可查阅这些信息,对错误可针对API函数调用,取回API函数GetlastError的结果,以修改声明,达到正确调用API函数之目的 VB6.0与Windows API 间的呼叫技巧 WIN32API 一、VB5.0与WindowsAPI间的呼叫技巧 一般会使用WINDOWAPI的情况,实在是因为VB本身不提供某些功能,但是,程式所需又不得不然,例如:读取Registry内的资料,VB只提供SaveSetting、Getsetting等系列的指令,但是它只能读取特定地区的值,要读、删、更动其他区域的值时,就无法使用。再如:仔细看一看ComboBox的Events,其中没有MouseMove,但这是我们经常用上的一个Event,那该如何呢?是的,那只有透过WinodowAPI。而VB呼叫WindowAPI一般不都使用API检视员,直接将相对应的APICOPY到我们的程式中就好,那还用什麽技巧吗? 其实不然,因为VB资料格式的问题,又加上VB本身没有指标,在许多地方需要一些小技巧才能解决,而且我们经常因应不同的需求,将API检视员的宣告COPY过来後再做一些修改,最重要的,如果有一个.DLL档,它不在API检视员中定义,那时,就只有自己想办法啦。 一、整数参数 WindowsAPI32位元VB Int,INTByValLong UNIT,DWORDByValLong BOOLByValLongture时为1 WPARAM,LPARAM,LRESULTByValLong Handle(如HKEY)ByValLong WORD,ATOM,SHORTByValInteger BYTE,CHARByValByte WindowsAPI宣告 SHORTGetKeyState(intnVirtKey) 对应的VB宣告 Declare Function GetKeyState Lib "user32"(ByVal nVirtKey As Long) As Integer ----------------------------------------------------------------------------- 这个API可用来检视某些KEY(如Insert键、NumLock、CapsLock等)是on/off。程式如下:这个例子应该可十分楚的看到各个整数间的宣告对应。 ----------------------------------------------------------------------------- Dim InsertMode as Integer InsertMode=GetKeyState(vbKeyInsert)AndvbShiftMask If InsertMode=1 then    Debug.print"表示InsertMode" Else    Debug.print"表示OverWriteMode" EndIf ----------------------------------------------------------------------------- 二、指向整数的指标 WindowsAPI32位元VB LPINT(ByRef)Long LPUNIT(ByRef)Long LPBOOL(ByRef)Long LPDWORD(ByRef)Long LPHANDLE(如:PHKEY)(ByRef)Long LPWORD(ByRef)Integer LPSHORT(ByRef)Integer LPBYTE(ByRef)Byte    VB内定是使用传址呼叫,所以ByRef可以省略,也就是说Func(ByRefparam1astype)与 Func(param1astype)是相同的,使用传址呼叫的方式,不外??想将参数传给API後将结果传回来。然而LONG型态的传址呼叫在VB中又占了相当大的份量,因为32位元的指标都是LONG的型态,而字串、自定型态的Structure在WindowsAPI中是以指标来传递的,而指标的传递事实上也是Long值的传递,只不过传过去的LONG值,於WINAPI中会将之当成Address,而再配合指标运作而得指标所指的内容,这个观念在後面会很重要。 例如:----------------------------------------------------------------------------- LONGRegOpenKeyEx( HKEYhKey,//handleofopenkey LPCTSTRlpszSubKey,//addressofnameofsubkeytoopen DWORDdwReserved,//reserved REGSAMsamDesired,//securityaccessmask PHKEYphkResult//addressofhandleofopenkey ); 相对应的VB宣告 Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA"_ (ByVal hKey As Long,_ ByVal lpSubKey As String,_ ByVal ulOptions As Long,_ ByVal samDesired As Long,_ phkResult As Long) As Long'//最後一个参数是ByRef之宣告 ----------------------------------------------------------------------------- 我们经常会想要用程式来读取Registry中的资料,例如:我们想得知Win95的ProductID该如何做呢?这里有几个观念要先清楚:首先:ProductId在何处呢?在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVerson下的ProductId。 我们要取得的便是KEY为HKEY_LOCAL_MACHINE SUBKEY为SOFTWARE\Microsoft\Windows\CurrentVerson ValueName为ProductId的value 然而要取得ProductId的value可没那麽直接,要先取得SubKey的KeyHandle,而KeyHandle的取得便是利用RegQueryKeyEx的API。程式部份在介绍WinAPI字串传递时再一并介绍。 三、字串参数 凡是所有字串参数指标都以ByVal参数名称AsString传。如RegOpenKeyEx()的第二参数ByVallpSubKeyAsString,便是一例。或许会问,这个例子是把subkey值传给WinAPI所以用ByVal,没什麽大不了,其实不然,要WinAPI传回字串时,也一定要用ByVal的宣告。这是VB5字串格式(BSTR)与WINAPI标准字串格式(LPSTR)不同的因素。LPSTR字串格式是NULLTerminate的字串,若有一字串"HaHa!OK!",则格式如下: ----------------------------------------------------------------------------- Address0123456789 -------------------- 内容HaHa!OK!\0 而BSTR则在字串的前面还有一个LONG值存字串长度,格式如下: Address0..345678910111213 -------------------------- 内容9HaHa!OK!\0 ----------------------------------------------------------------------------- 所以了字串以ByVal的方式来传像不像指到BSTR中第4个位置,如此一来,不就和LPSTR可以相容了吗?我想也正因为如此以ByVal的方式来传String可以取得WinAPI的传回值,(就算不是如此,至少这麽想比较记得住String要用ByVal的方式传)。现在又有一个问题,Window95API的字串使用的是ASCIICode但VB是用Unicode,Unicode占两个位元组,那麽能和WinAPI的字串相?所幸我们可以先不用管它,因为vb本身做了转换,即vb传给api时,转了一次,传回时又转回Unicode,所以如果我们用的是ByteArray来传字串,也可以但是要自己去转码。。 然而32位元的VB中,字串有种格式,一个是BSTR,另一个是HLSTR,如果我们宣告的串是非固定长度者,就会是BSTR,反之则为HLSTR。 DIM BSTR5 AS STRING劤BSTR DIMHLSTR5 AS STRING(255)劤HLSTR VB5中WIN32API的呼叫请多多使用BSTR,因为使用HLSTR的结果是,VB还得做HLSTR->BSTR的转换来呼叫WINAPI,若有传回STRING,而後再做BSTR->HLSTR的工作。然而使用BSTR来工作时,若处理有传回值的STRING参数,则还要有额外的动作: 1.先给定字串的初值,且字串的长度要够放传回值。 2.传回後,去除传回值中多馀的字元。 或 例如: ----------------------------------------------------------------------------- intGetWindowText( HWNDhWnd,//handleofwindoworcontrolwithtext LPTSTRlpString,//addressofbufferfortext intnMaxCount//maximumnumberofcharacterstocopy ); 该API取得WINDOWTitleBar的文字,而传回值是放入lpString的character个数。 VB的宣告如下: Declare Function GetWindowTextLib"user32"Alias"GetWindowTextA"_ (ByValhwnd As Long,_ ByVallpString As String,_ ByValcchAsLong) As Long 范例一 ***************************************************************************** Dim CharCnt As Long Dim lpString As String Dim tmpstr As String Dim NullPos As Long Form1.Caption="这是一个test" lpString=String(255,0)'设定初值 CharCnt=GetWindowText(Me.hwnd,lpString,256)'CharCnt=12 tmpstr=Left(lpString,CharCnt)'如此做会有一些问题 Debug.PrintLen(tmpstr)'得12 Label1.Caption=Left(lpString,CharCnt) Debug.PrintLen(Label1.Caption)'得8 ***************************************************************************** 以范例一的例子来看,设定lpString=String(255,0)的目的,是设定255个字元的空间给lpString(加上最後的null一共256),CharCnt的值是12,明眼者可看到len("这是一个test")会是8,但CharCnt是12,所以直接使用Left()函数来取得子字串会有问题,这是UniCode与ANSIString间的关系,所以了,当您看到有些书的范例用这种方法取子字串,是不太完善的,所以改用范例二的方式,比较正确。 范例二 ***************************************************************************** Form1.Caption="这是一个test" lpString=String(255,0)'设定初值 CharCnt=GetWindowText(Me.hwnd,lpString,256)'CharCnt=12 NullPos=InStr(1,lpString,Chr(0),vbBinaryCompare) tmpstr=Left(lpString,NullPos-1) lable1.Caption=tmpstr ***************************************************************************** 四、Null值的传递 我们再回到求ProductId的问题,我们已知使用RegOpenKeyEx()来取得subkey的Handle值,紧接着便是用RegQueryValueEx()来取值。 ----------------------------------------------------------------------------- LONGRegQueryValueEx( HKEYhKey,//handleofkeytoquery LPTSTRlpszValueName,//addressofnameofvaluetoquery LPDWORDlpdwReserved,//reserved LPDWORDlpdwType,//addressofbufferforvaluetype LPBYTElpbData,//addressofdatabuffer LPDWORDlpcbData//addressofdatabuffersize ); VB的宣告(由API检视员中Copy下来者) Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA"_ (ByVal hKey As Long,_ ByVal lpValueName As String,_ ByVal lpReserved As Long,_ lpType As Long,_ lpData As Any,_ lpcbData As Long) As Long ----------------------------------------------------------------------------- 仔细看一下第三个参数,WINAPI中是LPDWORD可是VB中麽会是用ByVal的方式传递呢?原因在於lpReserved一定要传Null进去,VB在呼叫时便在这参数的位置上填0(见范例三)。 为何传Null就得这做?我们可以这麽想,我们在程式中下指令,告诉VB要以ByVal的方式传0出去,而WINAPI里,它可不管VB是ByVal或ByRef,API认定我们传进来的就是它需要的,所以了,第三个参数在API中认定我们传进的是一个Address,而VB传0进去,那代表API若去取得它的内容,便会取得Addr
本文档为【API函数快速入门API函数简介】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_142125
暂无简介~
格式:doc
大小:208KB
软件:Word
页数:34
分类:生活休闲
上传时间:2010-05-14
浏览量:22