频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

通过Function类来实现Win32 API

来源:天极网 作者:来自网络 出处:巧巧读书 2008-05-13 进入讨论组

  在SWT Extension中,引入了Function这个类。基本上所有的Win32 JNI库都有这个类,用来直接操纵Win32 的部分API。有了这个Class,我们不用编写JNI,就可以实现某些简单的,甚至是较复杂的Win32 API。这里我们就以EnumWindows这个API举例,看看怎么Java来执行这个Win32 API。


  private static final String FUNTION_ENUMWINDOWS = "EnumWindows";
  private static final String USER32_LIB = "user32";
  private static List windowsList = new ArrayList();
  public static int[] enumWindows()
  {
  windowsList.clear();
  Callback callback = new Callback(Windows.class, "enumWindowsProc", 2);
  int address = callback.getAddress();
  if (address != 0)
  {
  try
  {
  Function function = new Function(USER32_LIB, FUNTION_ENUMWINDOWS);
  function.invoke_I(address, 0);
  function.close();
  } catch (Exception e)
  {
  SWT.error(SWT.ERROR_INVALID_ARGUMENT);
  }
  callback.dispose();
  }
  int[] handles = new int[windowsList.size()];
  for (int i = 0; i < windowsList.size(); i++)
  handles[i] = ((LONG) windowsList.get(i)).value;
  return handles;
  }
  private static int enumWindowsProc(int hwnd, int lParam)
  {
  windowsList.add(new LONG(hwnd));
  return 1;
  }

  EnumWindows是用来遍历Windows窗口的API,它需要传入一个返回boolean值的callback的地址作为参数。实际上在C里面,一个boolean值无非就是是否非0,如果为0,则为false,不为0,则为true。我们只需要new 一个function实例,传入这个API所在的Lib和API名字,然后执行invoke方法就OK了,在Function里面,可以最多执行含有4个简单类型参数的API。

  让我们再来看看FindWindowEx这个API,它需要传入2个int变量和2个字符串指针,根据SWT的设计,我们是可以将Java的字符串转换为指针的,因此通过Function我们也可以实现这个API:


  private static final String FUNTION_FINDWINDOWEX = Extension.IsUnicode ? "FindWindowExW"
  : "FindWindowExA";
  private static final String USER32_LIB = "user32";
  public static int findWindowEx(int parent, int hwndChildAfter, String className,
  String windowName)
  {
  int result = 0;
  int lpClassName = 0;
  int lpWindowName = 0;
  int hHeap = Extension.GetProcessHeap();
  if (className != null)
  {
  TCHAR buffer = new TCHAR(0, className, true);
  int byteCount = buffer.length() * TCHAR.sizeof;
  lpClassName = Extension.HeapAlloc(hHeap, Extension.HEAP_ZERO_MEMORY, byteCount);
  Extension.MoveMemory(lpClassName, buffer, byteCount);
  }
  if (windowName != null)
  {
  TCHAR buffer = new TCHAR(0, windowName, true);
  int byteCount = buffer.length() * TCHAR.sizeof;
  lpWindowName = Extension.HeapAlloc(hHeap, Extension.HEAP_ZERO_MEMORY, byteCount);
  Extension.MoveMemory(lpWindowName, buffer, byteCount);
  }
  try
  {
  Function function = new Function(USER32_LIB, FUNTION_FINDWINDOWEX);
  result = function.invoke_I(parent, hwndChildAfter, lpClassName, lpWindowName);
  function.close();
  } catch (Exception e)
  {
  SWT.error(SWT.ERROR_INVALID_ARGUMENT);
  }
  if (lpClassName != 0) Extension.HeapFree(hHeap, 0, lpClassName);
  if (lpWindowName != 0) Extension.HeapFree(hHeap, 0, lpWindowName);
  return result;
  }

    其实像这种简单参数类型的API,Win32 里还有很多,我们完全不必为其专门编写JNI,只需使用熟悉的Java即可。虽然不是调用全部的API,但大部分常用的API都是没有问题的,关键是如何灵活运用。现在的大型商业RCP应用中,其实多多少少都参和了JNI,用于提升对用户的友好性和软件的执行性能,毕竟Java天生就是客户端开发的矮子。对于JNI,我们既不能一味排斥,也不能滥用,要把握一个平衡点,使之成为Java客户端开发的利器。

进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章