|
问:什么是API
答:API是Windows提供的一系列很复杂的函数。在Win32中,系统提供的函数
大概有1000个左右,这些输出的函数可以被诸如VB、VC、VF、DELPHI、C++
Builder等很多编程编程软件所使用。
这些函数包括以下几大类:Windows控制类:包括窗口(在这里包括普通窗口
、按钮、菜单等)操作、DDE(动态数据交换)操作、Windows消息操作等,这些操
作包含在User32.dll中;
GDI(图形设备接口)类操作,包含图形设备操作,画笔、字体、位图操作以
及打印机操作等,这些操作包含在GDI32.dll中;系统类:包括内存操作、文件(
这里的文件是广义的,并不单指保存到磁盘上的文件)操作等,这些操作包含在
Kernel32.dll中;多媒体类,包含音频、MIDI、AVI视频、游戏杆支持等,这些函
数包含在Winmm.dll中。以及Windows外壳扩。
展类(包含在Shell32.dll中)。利用Visual Basic提供的API函数支持功能,
可以让开发者像使用标准的VB函数那样使用API函数,这样可以大大地扩展VB应用
程序的功能。
问:怎样使用API的一个API函数
答:在VB中的定义一般是这样的:
Declare Function TextOut Lib “gdi32" Alias “TextOutA" ( _
ByVal hdc As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal lpString As String, _
ByVal nCount As Long) As Long
这个函数很像一个VB中的普通函数定义,但是还是有一点不同,下面给大家做
一个说明。
其中TextOut是在VB中使用的函数名,lib “gdi32"表明API函数包含在
gdi32.dll动态连接库中,alias表明前面的TextOut是别名,而被调用的函数在
gdi32.dll中的名称是后面的TextOutA。
下面来一个范例:
首先在VB中建立一个新的工程文件,在Form1中加入以下代码:
'由于是在Form中的定义,所以要在Declare前加Private
Private Declare Function TextOut Lib “gdi32" Alias“TextOutA" ( _
ByVal hdc As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal lpString As String, _
ByVal nCount As Long) As Long
Private Sub Form_Load()
Dim astr As String
Form1.AutoRedraw = True
astr =“This is my first API sample"
TextOut Form1.hdc, 20, 20, astr, Len(astr)
End Sub
运行程序,看看Form上的输出结果,用API编程是不是很简单?但是如何掌握
如此繁复的API函数呢?那就要通过不断的编程来慢慢学习了。另外我建议你手边
准备一些编程工具:Microsoft的MSDN库光盘,其中包含了所有公开(公开的?对
,可恶的微软将API函数分为公开的和未公开的,很多有用以及有趣的功能都在未
公开函数中,而这些函数你在几乎所有的帮助文档中都找不到)的API函数的定义和说明;Visual Basic的API Viewer,这个小程序是VB附带的,利用它可以查找绝大部分的Windows函数的VB定义。
问:API函数定义中的Byval是什么东东?
答:在VB调用外部函数的参数传递中,默认的传递方式是传地址方式,而如果
要直接将数值传递给外部函数,就要在参数前加上Byval以传值方式传递参数,例
如上面的TextOUt函数,如果不在参数hdc前加ByVal,传递给函数的就将是hdc在内
存中的指针,这当然会导致程序出错。
问:怎样传递数组以及结构给API函数
答:在Windows中几乎所有的结构以及数组都是通过指针来处理的,看到上面
一个问题,你可能已经想到了,对于结构类型数据一般只要不在参数前添加Byval
就可以了:例如下面的函数定义:
GetWindowRect在Windows API中的定义:
BOOL GetWindowRect(
HWND hWnd, // handle of window
LPRECT lpRect // address of structure for window coordinates
);
GetWindowRect在VB中的定义:
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public Declare Function GetWindowRect Lib “user32" (ByVal hwnd As
Long, lpRect As RECT) As Long
对于数组类型的参数,只要在函数的定义中将参数类型定义为数组中的数据类
型,同时在函数使用时在相应的位置添上数组中第一个数据就可以了,例如函数
GetSystemPaletteEntries要使用到一个 PALETTEENTRY 类型的数组,在函数的定
义中就要这样定义:
Public Type PALETTEENTRY
peRed As Byte
peGreen As Byte
peBlue As Byte
peFlags As Byte
End Type
Public Declare Function GetSystemPaletteEntries Lib “gdi32"
(ByVal hdc As Long, _
ByVal wStartIndex As Long, ByVal wNumEntries As Long, _
lpPaletteEntries As PALETTEENTRY) As Long
而函数是这样使用的:
Private Sub Form_Load()
Dim x(1 To 256) As PALETTEENTRY
GetSystemPaletteEntries(Form1.hdc, 1, 256, x(1))
End Sub
由于数组在VB中是按顺序紧密存放的,所以只要在函数调用时将数组中第一个
数据按传地址方式传递过去,API函数就能按顺序访问数组中的其他数据了。
问:怎样使用回调函数?
答:回调函数功能是Windows动态连接库的一种功能,通过它,动态连接库种
的函数可以调用调用该动态连接库的程序中定义好的函数,我们称程序中的函数为
回调函数。下面是一个使用回调函数的范例:
首先建立一个新的工程文件,在工程中加入一个Module,然后在Module中加入
以下代码:
Public Declare Function EnumWindows Lib “user32" (ByVal
lpEnumFunc _
As Long, ByVal lParam As Long) As Long
Public Declare Function GetClassName Lib “user32" Alias“
GetClassNameA" _
(ByVal hwnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Public Declare Function GetWindowText Lib “user32" Alias “
GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long
Function EnumWindowsProc(ByVal hwnd As Long, ByVal parma As Long) As
Long
Dim astr As String * 256
Dim bstr As String
Dim x As Integer
GetClassName hwnd, astr, Len(astr)
If InStr(astr,“CabinetWClass") Then
GetWindowText hwnd, astr, Len(astr)
x = InStr(astr, Chr(0))
bstr = Left$(astr, x)
Form1.List1.AddItem bstr
End If
EnumWindowsProc = True
End Function
在Form1中加入一个CommandButton和一个ListBox,在Command1的Click事件中
加入以下代码:
Private Sub Command1_Click()
List1.Clear
EnumWindows AddressOf EnumWindowsProc, 0
End Sub
运行程序,在Windows桌面上打开几个Explore窗口或者IE窗口,点击
Command1,打开的窗口的标题就会列在List1中。
通过程序可以看到,EnumWindows函数是一个枚举系统中窗口的函数,其中的
参数lpEnumFunc定义指向一个回调函数,当EnumWindows查找到一个窗口时,就会
调用回调函数,同时将窗口的句柄传递给回调函数,在编程时在回调函数中加入相
应的代码。就可以处理这些窗口了。在上面的程序中EnumWindowsProc就是一个回
调函数,注意其中的参数hwnd和param前都有ByVal,这个问题大家可以参考前面的
问答思考一下。
上面回答了常见的一些关于API开发的一些基础问题,感觉还是挂一漏万。总之,
只要多写程序,多学习,API编程是一件非常有趣的事情(当然并不简单,特别是
当你深入API编程后)。 |
|