API 函数都写成对应Java 形式。微软考虑到了这个问题,发行了一个Java 包,可通过 J/Direct 将 Win32
API 映射成 Java 类。这个包的名字叫作 。ms。win32。安装Java SDK 2。0 时,若在安装选项中进行了相应
的设置,这个包就会安装到我们的类路径中。这个包由大量Java 类构成,它们完整再现了 Win32 API 的常
数、数据类型以及函数。包容能力最大的三个类是 User32。class,Kernel。class 以及Gdi32。class。它们包
含的是Win32 API 的核心内容。为使用它们,只需在自己的 Java 代码里导入即可。前面的ShowMsgBox 示例
可用。ms。win32 改写成下面这个样子(这里也考虑到了用更恰当的方式使用UnsatisfiedLinkError):
import 。ms。win32。*;
657
…………………………………………………………Page 659……………………………………………………………
public class UseWin32Package {
public static void main(String args'') {
try {
User32。MessageBeep(
winm。MB_ICONEXCLAMATION);
User32。MessageBox(0;
〃Created by the MessageBox() Win32 func〃;
〃Thinking in Java〃;
winm。MB_OKCANCEL |
winm。MB_ICONEXCLAMATION);
} catch(UnsatisfiedLinkError e) {
System。out。println(〃Can’t link Win32 API〃);
System。out。println(e);
}
}
}
Java 包是在第一行导入的。现在,可在不进行其他声明的前提下调用MessageBeep()和 MessageBox()函数。
在MessageBeep()里,我们可看到包导入时也声明了 Win32 常数。这些常数是在大量Java 接口里定义的,全
部命名为winx (x 代表欲使用之常数的首字母)。
写作本书时,。ms。win32 包的开发仍未正式完成,但已可堪使用。
A。3。3 汇集
“汇集”(Marshaling)是指将一个函数自变量从它原始的二进制形式转换成与语言无关的某种形式,再将
这种通用形式转换成适合调用函数采用的二进制格式。在前面的例子中,我们调用了MessageBox()函数,并
向它传递了两个字串。MessageBox()是个C 函数,而且 Java 字串的二进制布局与C 字串并不相同。但尽管如
此,自变量仍获得了正确的传递。这是由于在调用 C 代码前,J/Direct 已帮我们考虑到了将Java 字串转换
成C 字串的问题。这种情况适合所有标准的Java 类型。下面这张表格总结了简单数据类型的默认对应关系:
Java C
byte BYTE 或CHAR
short SHORT或 WORD
int INT,UINT ,LONG,ULONG 或 DWORD
char TCHAR
long __int64
float Float
double Double
boolean BOOL
String LPCTSTR (只允许在OLE 模式中作为返回值)
byte'' BYTE *
short'' WORD *
char'' TCHAR *
int'' DWORD *
这个列表还可继续下去,但已很能说明问题了。大多数情况下,我们不必关心与简单数据类型之间的转换问
题。但一旦必须传递用户自定义类型的自变量,情况就立即变得不同了。例如,可能需要传递一个结构化
的、用户自定义的数据类型,或者需要把一个指针传给原始内存区域。在这些情况下,有一些特殊的编译引
导命令标记一个Java 类,使其能作为一个指针传给结构(@dll。struct 引导命令)。欲知使用这些关键字的
细节,请参考产品文档。
658
…………………………………………………………Page 660……………………………………………………………
A。3。4 编写回调函数
有些Win32 API 函数要求将一个函数指针作为自己的参数使用。Windows API 函数随后就可以调用自变量函
数(通常是在以后发生特定的事件时)。这一技术就叫作“回调函数”。回调函数的例子包括窗口进程以及
我们在打印过程中设置的回调(为后台打印程序提供回调函数的地址,使其能更新状态,并在必要的时候中
止打印)。
另一个例子是API 函数EnumWindows() ,它能枚举目前系统内所有顶级窗口。EnumWindows()要求获取一个函
数指针作为自己的参数,然后搜索由Windows 内部维护的一个列表。对于列表内的每个窗口,它都会调用回
调函数,将窗口句柄作为一个自变量传给回调。
为了在Java 里达到同样的目的,必须使用 。ms。dll 包里的 Callback 类。我们从 Callback 里继承,并取
消callback()。这个方法只能接近int 参数,并会返回 int或void。方法签名和具体的实施取决于使用这个
回调的Windows API 函数。
现在,我们要进行的全部工作就是创建这个Callback 衍生类的一个实例,并将其作为函数指针传递给API 函
数。随后,J/Direct 会帮助我们自动完成剩余的工作。
下面这个例子调用了Win32 API 函数EnumWindows() ;EnumWindowsProc 类里的 callback()方法会获取每个
顶级窗口的句柄,获取标题文字,并将其打印到控制台窗口。
import 。ms。dll。*;
import 。ms。win32。*;
class EnumWindowsProc extends Callback {
public boolean callback(int hwnd; int lparam) {
StringBuffer text = new StringBuffer(50);
User32。GetWindowText(
hwnd; text; text。capacity()+1);
if(text。length() != 0)
System。out。println(text);
return true; // to continue enumeration。
}
}
public class ShowCallback {
public static void main(String args'')
throws InterruptedException {
boolean ok = User32。EnumWindows(
new EnumWindowsProc(); 0);
if(!ok)
System。err。println(〃EnumWindows failed。〃);
Thread。currentThread()。sleep(3000);
}
}
对 sleep()的调用允许窗口进程在main()退出前完成。
A。3。5 其他 J/Direct 特性
通过@dll。import 引导命令内的修改符(标记),还可用到 J/Direct 的另两项特性。第一项是对OLE 函数的
简化访问,第二项是选择API 函数的ANSI 及 Unicode 版本。
根据约定,所有OLE 函数都会返回类型为HRESULT 的一个值,它是由 定义的一个结构化整数值。若在
那一级编写程序,并希望从一个OLE 函数里返回某些不同的东西,就必须将一个特殊的指针传递给它—
—该指针指向函数即将在其中填充数据的那个内存区域。但在 Java 中,我们没有指针可用;此外,这种方法
并不简练。利用J/Direct,我们可在@dll。import 引导命令里使用ole 修改符,从而方便地调用OLE 函数。
标记为 ole 函数的一个固有方法会从Java 形式的方法签名(通过它决定返回类型)自动转换成 形式的函
659
…………………………………………………………Page 661……………………………………………………………
数。
第二项特性是选择ANSI 或者 Unicode 字串控制方法。对字串进行控制的大多数 Win32 API 函数都提供了两个
版本。例如,假设我们观察由 USER32。DLL 导出的符号,那么不会找到一个MessageBox()函数,相反会看到
MessageBoxA()和MessageBoxW() 函数——分别是该函数的ANSI 和 Unicode 版本。如果在@dll。import 引导命
令里不规定想调用哪个版本,JVM 就会试着自行判断。?
小说推荐
- 软件工程实践者的思想(PDF格式)
- -Page 1-大 道 至 简—软件工程实践者的思想周爱民(Aimingoo 著-Page 2-序2004 年 11 月初爱民(Aimingoo)第一次把他的书稿给我,我翻看了一下,第一反应讲的是感想。这不错,在技
- 最新章:第26章
- 深入浅出MFC第2版(PDF格式)
- -Page 1-Page 2-山高月小山高月小 水落石出水落石出山高月小山高月小 水落石出水落石出-Page 3-深入淺出MFC(第版 使用Visual C 5.0 MFC 4.2)Dissecting MFC(Second Edition Using Visual C 5.0 MFC 4.2)侯俊
- 最新章:第309章
- VB2008从入门到精通(PDF格式英文版)
- -Page 1(R)The eXperT’s Voice inBeginningVB 2008From Novice to ProfessionalChristian Gross-Page 2-Page 3-Beginning VB 2008From Novice to Professional■C
- 最新章:第214章
- C语言游戏编程从入门到精通(PDF格式)
- -Page 1-Page 2-Page 3-Page 4-Page 5-Page 6-Page 7-Page 8-Page 9-Page 10-Page 11-Page 12-Page 13-Page 14
- 最新章:第4章
- JMS简明教程(PDF格式)
- -Page 1-JMS1.1规范中文版卫建军2007‐11‐22-Page 2
- 最新章:第28章
- C语言实例教程(PDF格式)
- -Page 1-前 言Visual C+是开发运行于Windows 95和Windows NT环境下的Win32应用程序的可视化编程工具中最重要的成员之一,它为软件开发人员提供了完整的编辑、编译和调试工具和建立于Win32 API(ApplicationProgramming Interface)基
- 最新章:第143章
- 神祗之眼 (正式版)第7卷(全文完)作者:百里芜虚
- 第五十一章离12月25日的圣诞节还有两天,纽约已经换上了节日的盛装,几天前的一场大雪令整个城市一片银白。人们笑逐颜开,都纷纷开始为节日做准备,商家为了在节日打开销路纷纷推出各种优惠促销手段,纽约的大街小巷全都这样热闹。依沙那被老婆打发出来买过节要用的杂货,而女儿则和凯妮一起到百货商场去买衣服去了。对
- 最新章:第23章
- SQL语言艺术(PDF格式)
- -Page 1-SQLSSQQLL语言艺术内容介绍本书分为12章,每一章包含许多原则或准则,并通过举例的方式对原则进行解释说明。这些例子大多来自于实际案例,对九种SQL经典查询场景以及其性能影响讨论,非常便于实践,为你数据库应用维护人员阅读。资深 SQL 专家 Stéphane Faroult倾力打
- 最新章:第27章
- php程序设计简明教程(DOC格式)
- -Page 1-PHP 程序设计简明教程PHP 讲义 第 1 页 共 90 页-Page 2-目录序 4第一章 PHP 简介 6
- 最新章:第31章