📄 ba37.htm
字号:
<HTML>
<HEAD>
<TITLE>怎样手工声明API</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
</head>
<p align="center"><script src="../../1.js"></script></a>
<BODY topMargin=4 vLink=#0000ff>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD height="52">
<DIV align=center>
<CENTER>
<table border=0 cellpadding=0 cellspacing=0 width=679 align="center">
<tbody>
<tr>
<td width=200 height="59">
</TD></TR><!--msnavigation--></TBODY></TABLE>
<table border=0 cellpadding=0 cellspacing=0 width="100%">
<tbody>
<tr><!--msnavigation--><td valign=top height="123">
<div align=center>
<table border=1 bordercolor=#b9d9ff cellpadding=0 cellspacing=0
class=table width=755>
<center>
<tr>
<td width="100%" height="3">
<div align="center"> <strong>怎样手工声明API</strong></span></div>
</td>
</tr>
<tr>
<td
width="100%" class="unnamed1" height="124">
<div align="left">
<p align="center"> </p>
<p align="left"> <font face="宋体" size="-1"> 尽管 Visual Basic
在 Win32api.txt 中提供了大量的预定义声明,但还是需要知道如何亲自编写声明。例如,有时希望访问用其它语言编写的
DLL 中的过程,或者改写 Visual Basic 的预定义声明,以满足特殊需要。<br>
要声明一个 API 过程,需要在代码窗口的“声明”部分增加一个 Declare 语句。如果该过程返回一个值,应将其声明为
Function:</font></p>
<p align="left"><font face="宋体" size="-1">Declare Function publicname
Lib "libname" [Alias "alias"] [([[ByVal]
variable [As type] [,[ByVal] variable [As type]]...])] As
Type</font></p>
<p align="left"><font face="宋体" size="-1"> 如果过程没有返回值,可将其声明为
Sub:</font></p>
<p align="left"><font face="宋体" size="-1">Declare Sub publicname
Lib "libname" [Alias "alias"] [([[ByVal]
variable [As type] [,[ByVal] variable [As type]]...])]</font></p>
<p align="left"><font face="宋体" size="-1"> 缺省情况下,在标准模块中声明的
API 过程是公有的,可以在应用程序的任何地方调用它。在其它类型的模块中定义的 API 过程是模块私有的,必须在它们前面声明
Private 关键字,以示区分。</font></p>
<p><font face="宋体" size="-1"><b> </b></font></p>
<p align="left"><font face="宋体" size="-1"><b> 一.指定库</b></font></p>
<p align="left"><font face="宋体" size="-1"> Declare 语句中的 Lib
子句用来告诉 Visual Basic 如何找到包含过程的 .API 文件。如果引用的过程属于 Windows 核心库(User32、Kernel32
或 GDI32),则可以不包含文件扩展名:</font></p>
<div align="left">
<pre><font face="宋体" size="-1">Declare Function GetTickCount Lib "kernel32" Alias _
"GetTickCount" () As Long</font></pre>
</div>
<p align="left"><font face="宋体" size="-1"> 对于其它 DLL,Lib 子句指定文件的路径:
</font></p>
<div align="left">
<pre><font face="宋体" size="-1">Declare Function lzCopy Lib "c:\windows\lzexpand.API" _
(ByVal S As Integer, ByVal D As Integer) As Long</font></pre>
</div>
<p align="left"><font face="宋体" size="-1"> 如果未指定 libname 的路径,Visual
Basic 将按照下列顺序查找该文件: </font>
<div align="left">
<ul>
<li><font face="宋体" size="-1">.exe 文件所在的目录<br>
<br>
</font></li>
<li><font face="宋体" size="-1">当前目录<br>
<br>
</font></li>
<li><font face="宋体" size="-1">Windows 位系统目录(通常为 \Windows\System)<br>
<br>
</font></li>
<li><font face="宋体" size="-1">Windows 目录(不一定是 \Windows)<br>
<br>
</font></li>
<li><font face="宋体" size="-1">Path 环境变量中的目录<br>
<br>
</font></li>
<li> <font face="宋体" size="-1">下表中列出了通常的操作系统环境库文件。 </font></li>
</ul>
<table align="center" bgcolor="#6699cc" border="0" cellpadding="0" cellspacing="1"
cols="2" class="font">
<tr valign="top">
<td class="label" width="51%"><font color="#ffffff">动态链接库</font></td>
<td class="label" width="49%"><font color="#ffffff">描述</font></td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Advapi32.API</td>
<td bgcolor="#ffffff" width="49%">高级 API 服务,支持大量的 API(其中包括许多安全与注册方面的调用)</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Comdlg32.API</td>
<td bgcolor="#ffffff" width="49%">通用对话框 API 库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Gdi32.API</td>
<td bgcolor="#ffffff" width="49%">图形设备接口 API 库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Kernel32.API</td>
<td bgcolor="#ffffff" width="49%">Windows 32 位核心的 API
支持</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Lz32.API</td>
<td bgcolor="#ffffff" width="49%">32 位压缩例程</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Mpr.API</td>
<td bgcolor="#ffffff" width="49%">多接口路由器库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Netapi32.API</td>
<td bgcolor="#ffffff" width="49%">32 位网络 API 库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Shell32.API</td>
<td bgcolor="#ffffff" width="49%">32 位 Shell API 库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">User32.API</td>
<td bgcolor="#ffffff" width="49%">用户接口例程库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Version.API</td>
<td bgcolor="#ffffff" width="49%">版本库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Winmm.API</td>
<td bgcolor="#ffffff" width="49%">Windows 多媒体库</td>
</tr>
<tr valign="top">
<td bgcolor="#ffffff" width="51%">Winspool.drv</td>
<td bgcolor="#ffffff" width="49%">后台打印接口,包含后台打印 API 调用。</td>
</tr>
</table>
</div>
<p align="left"><font face="宋体" size="-1"><br>
<b> 二.处理使用字符串的 Windows API 过程</b> </font></p>
<p align="left"><font face="宋体" size="-1"> 如果调用的 Windows API
过程要使用字符串,那么声明语句中必须增加一个 Alias 子句,以指定正确的字符集。包含字符串的 Windows API
函数实际有两种格式:ANSI 和 Unicode。因此,在 Windows 头文件中,每个包含字符串的函数都同时有
ANSI 版本和 Unicode 版本。<br>
例如,下面是 SetWindowText 函数的两种 C 语言描述。可以看到,第一个描述将函数定义为 SetWindowTextA,尾部的“A”表明它是一个
ANSI 函数:</font></p>
<div align="left">
<pre><font face="宋体" size="-1">WINUSERAPI
BOOL
WINAPI
SetWindowTextA(
HWND hWnd,
LPCSTR lpString);
</font></pre>
</div>
<p align="left"><font face="宋体" size="-1"> 第二个描述将它定义为 SetWindowTextW,尾部的“W”表明它是一个
Unicode 函数:</font></p>
<div align="left">
<pre><font face="宋体" size="-1">WINUSERAPI
BOOL
WINAPI
SetWindowTextW(
HWND hWnd,
LPCWSTR lpString);
</font></pre>
</div>
<p align="left"><font face="宋体" size="-1"> 因为两个函数实际的名称都不是“SetWindowText”,要引用正确的函数就必须增加一个
Alias 子句:</font></p>
<div align="left">
<pre><font face="宋体" size="-1">Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal _
lpString As String) As Long
</font></pre>
</div>
<p align="left"><font face="宋体" size="-1"> 请注意,Alias 子句后面的字符串必须是过程的真正名称,而且必须是区分大小写的。<br>
对于 Visual Basic 中使用的 API 函数,应该指定函数的 ANSI 版本,因为只有 Windows
NT 才支持 Unicode 版本,而 Windows 95 不支持这个版本。仅当应用程序只运行在 Windows
NT 平台上的时候才可以使用 Unicode 版本。</font></p>
<p align="left"><font face="宋体" size="-1"><b> </b></font></p>
<p align="left"> <font face="宋体" size="-1"><b> 三.使用值或引用传递</b>
<br>
<br>
在缺省的情况下,Visual Basic 以引用方式传递所有参数。这意味着并没有传递实际的参数值,Visual
Basic 只传递了数据的 32 位地址。在 Declare 语句中不要求包含 ByRef 关键字,但是如果包含该关键字,就能够清楚地看出数据是以何种方式传递的。
<br>
许多 API 过程要求参数以值方式传递。这意味着它们需要实际的数据,而不是数据的内存地址。如果过程需要一个传值参数,而传递给它的参数是一个指针,那么由于得到了错误的数据,该过程将不能正确地工作。
<br>
要使参数以使用值方式传递,在 Declare 语句中需要在参数声明的前面加上 ByVal 关键字。例如,InvertRect
过程要求第一个参数使用值,而第二个使用引用: </font></p>
<div align="left">
<pre><font face="宋体" size="-1">Declare Function InvertRect Lib "user32" Alias _
"InvertRectA" (ByVal hdc As Long, _
lpRect As RECT) As Long
</font></pre>
</div>
<p align="left"><font face="宋体" size="-1"> 也可以在调用过程时使用 ByVal
关键字。<br>
字符串参数是一个特例。如果以使用值方式传递字符串,那么传递的将是该字符串中第一个数据字节的地址;如果以使用引用方式传递字符串,那么实际传递的将是用来保存另一个地址的内存单元的地址;后面的“地址”实际是字符串的第一个数据字节的内存地址。</font>
</div>
</td>
</tr>
</center>
<tr>
<td width="100%" class="unnamed1">
<p align=right><a href="ba36.htm">(上一页)</a>---<a href="ba38.htm">(下一页)</a></p>
</td>
</tr>
<tr>
<td width="100%" class="unnamed1">
</div>
</td>
</tr>
<!--msnavigation--></tbody>
</table>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -