- 浏览: 213553 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
kris_zhang:
Derby 使用的怎么样?
沉浮于各种文件型数据库 hsqldb h2 还是derby -
di1984HIT:
学习了~~。。
【阅读笔记】jvm性能工具-jstat解决100%CPU占用率分析 -
qiuyi:
兄弟,GOOD!
ubuntu 14.04 sunpinyin的双拼下ue和iong的韵母问题 -
RYANaaa:
博主你好,请问你是怎么在sun的java源码里设置端点的啊?我 ...
理解JComboBox原理——鼠标点击ComboBox之外的区域,下拉列表如何自动隐藏 -
tag13346:
H2必建索引,否则就是个悲剧
沉浮于各种文件型数据库 hsqldb h2 还是derby
原始发表时间:2009-06-27
本文学习过程如下图示(下图为整个工作思维导图的一部分):
开发环境:
JDK 1.5 (编译的目标版本为1.4)
JNA
3.0.9(开发时的版本,将会切换为3.1.0)
做了几个月的Swing,恼人的问题一个接一个的出现了。
因为项目需要,得重新定制界面风格,继承可怕的UI接口,去实现ButtonUI、MenuUI等等等等,图片显示、组件定位都得自己来。经搜索,发现网上也有现成的工具类,乍一看感觉真好啊,突然觉得春光明媚,希望之星冉冉升起,心说“Swing社区也很有活力嘛”,定睛一看,才知道都是收费的……随便一个项目的工具包都是几百美金……好了不扯这茬,总之是没戏了……自己写吧……(这里犯了一个错误,其实SUN的官方有一个项目叫做SwingX,在swing
lab管理下,里面有不少扩展过的控件,应该说功能已经十分强大,而且参考其源代码也能受益匪浅,结果overlook之后,偶开始硬着头皮写自己的扩展……)
本来不需要用JNA,也不需要Win32API(小用一下并不复杂,看到此文的读者如果还不会,可以大胆尝试使用,控制windows的窗口很有趣……),结果因为用户的一个很合理的需求,不得不用了。
定制的界面中,标题栏已经被干掉,最小化、最大化、关闭按钮都替换成了自己写的图形化按钮(如下图)
因为界面去掉了系统默认的外框,而用自己改造过的图形化标题栏,所以这些按钮的最小化、最大化功能必须自己编写。
之前最小化没有能够实现,因为为了实现标题栏自定义,应用中的导航界面设置了
setUndecorated(true),即去除了操作系统对于窗口的标题栏特性的支持,所以最小化功能无法使用JFrame中的 void
setExtendedState(int state) 来实现。
这时很自然地会想到Win32API来获取窗口句柄,设置窗口显示状态。
于是想起了之前使用JNA项目(也是使用JNA才实现了上图中右上角的圆角特效),仔细查看官方文档(一开始没有看完官方文档,导致浪费了2个多小时在捣腾
FindWindow 和 GetWindowText 函数),有段参考代码如下:
user32.EnumWindows(new
WNDENUMPROC() {
int count;
public boolean callback(Pointer hWnd,
Pointer userData) {
System.out.println("Found window " + hWnd + ",
total " + ++count);
return true;
}
}, null);
这段代码的启示意义很重要,虽然这段代码在JNA 3.0.9和3.1.0 已经改变了 callback
方法的参数列表,还是让我写出了以下代码:
final User32 user32 =
User32.INSTANCE;
user32.EnumWindows(new WNDENUMPROC() {
int count;
public boolean callback(HWND wnd, Pointer
data) {
System.out.println("Found window " + wnd + ", total "
+ ++count);
int buflen = 150;
byte[]
lpString = new byte[300];
user32.GetWindowText(wnd, lpString,
buflen);
System.out.println("lpString: " +
Native.toString(lpString));
return true;
}
}, null);
虽然上面的代码没有正确完成打印所有窗口标题的意图(打印出乱码),但是它确实列举了系统当前的各个窗口句柄的信息。其中黑体字太重要了,一开始依葫芦画瓢,竟然错写成return
false,结果每次都只能打印一个窗口的句柄信息,好生苦恼……
通过网上搜索 FindWindow
的用法,其函数原型:
HWND
FindWindow
(
LPCTSTR lpClassName,
LPCTSTR
lpWindowName
);
理解之后,写出如下代码,用于搜索客户端程序的窗口句柄
static HWND getUnitFrameWnd(){
HWND hwnd =
User32.INSTANCE.FindWindow(null, "XXX系统功能导航(客户端)");
if (unitFrameWnd
== null) {
unitFrameWnd = hwnd;
}
return
unitFrameWnd;
}
应用程序的导航界面
是整个应用所有窗口的父窗口,所以它的title
(这里标题取值为“XXX系统功能导航(客户端)”)就可以作为 FindWindow
的参数 lpWindowName
,至于Java的JFrame程序对应于参数
lpClassName
的取值为“SunAwtFrame
”(猜猜我是怎么知道的,用了VS
2008里附带的Spy++,专门用于查询窗口句柄的信息,装一下VC++好像就会附带了,不一定要VS这个庞然大物……)
----------------------------
注:这边有个教训,一开始以为参数为空,就觉得传内容为空的字符串也可以,结果发现返回句柄信息总是为空,比如
User32.INSTANCE.FindWindow("",
"XXX系统功能导航(客户端)");
就无法找到我们需要的窗口句柄,如果我们无法给出某个参数的值,就必须将该参数设置为null(这里参数
lpClassName
应该
置为null)
----------------------------
后来查询到Win32API中,控制窗口最小化、最大化比较好的函数是 ShowWindow
,因为它在修改窗口状态的同时,立即应用效果。但是遍寻JNA 3.0.9里的 User32
接口也没有找到 ShowWindow
的影子,怎么办呢?
查询MSDN文档,发现 ShowWindow
函数说明如下:
BOOL
ShowWindow(HWND hWnd,int nCmdShow)
另外关于参数 nCmdShow
,找到几个可用的常量值分别如下:
int SW_MAXIMIZE
= 0x03;
int SW_MINIMIZE
= 0x06;
int SW_RESTORE
= 0x09;
看字面意思就知道是我们正在寻求的东东。好吧,学习 JNA 源代码
中 User32
来写一个接口 Win32API
,将本地方法映射到Java的源代码,可以写出下面的代码:
public
interface Win32API extends User32 {
/**
* 最大化窗口
*/
public static int SW_MAXIMIZE = 0x03;
/**
* 最小化窗口
*/
public static int SW_MINIMIZE = 0x06;
/**
*
恢复窗口
*/
public static int SW_RESTORE = 0x09;
Win32API
INSTANCE = (Win32API) Native.loadLibrary("user32", Win32API.class,
DEFAULT_OPTIONS);
/**
* Updated at 下午03:44:53, on
2009-6-26<br>
* 获取桌面句柄
*
* @return
*
@author Caesar
*/
public HWND GetDesktopWindow();
/**
* Updated at 下午03:44:59, on 2009-6-26<br>
*
设置窗口句柄的显示状态
*
* @param wnd
* @param nCmdShow
* 可选值为SW_MINIMIZE - 最小化, SW_MAXIMIZE - 最大化
* @return
* @author Caesar
* @see #SW_MINIMIZE
* @see #SW_MAXIMIZE
*/
public boolean ShowWindow(HWND wnd,
int nCmdShow);
}
我们需要的工具已经收入囊中,接下来就是在最小化按钮的事件处理上做点工作就OK了。
WindowButton btnWinMin =
new WindowButton(winMinIcon, parent) {
private static final long
serialVersionUID = 1L;
protected void actionPerformed(Container
frame) {
HWND mainFrame = getUnitFrameWnd
(); //
这个函数的代码在前面已有提供,获取客户端主界面的窗口句柄
Win32API.INSTANCE.ShowWindow(mainFrame, Win32API.SW_MINIMIZE);
}
};
类 WindowButton 继承自JButton,通过提供的图标对象 winMinIcon
来显示定制的最小化按钮效果,其代码如下:
public class WindowButton extends
RolloverBrighterButton implements ActionListener {
private static final
long serialVersionUID = 1L;
private Container parentComponent;
public WindowButton() {
super();
}
public
WindowButton(Icon icon, Container parentComponent) {
super(icon);
this.parentComponent = parentComponent;
addActionListener(this);
}
public void
actionPerformed(ActionEvent e) {
actionPerformed(parentComponent);
}
protected void
actionPerformed(Container frame) {
}
}
至此,通过Win32API的调用,实现了定制的最小化按钮的功能。
后记:
朋友问:
http://www.blogjava.net/javagui/archive/2007/11/03/157948.html
可以看下这篇文章..
因为我使用的L&F是windows look & feel,项目没有给我大量的时间重新开发一套L&F,另外我当时没有来得及仔细的学习OpenSwing,所以在界面外观上想了点偷懒的办法,就是主界面使用自制的风格,按美工给的图片来确定整体风格,一些小的对话窗口、录入框之类的就直接沿用windows L&F
但是使用Windows L&F有个麻烦,就是翻阅源码的时候,发现L&F中各个类基本上是在进行底层的调用(可能直接调用某些C函数库,现在也没有去深究,只是猜测),一看头大了,就想了个歪招,把JFrame和JDialog的外框给去掉了,套上自己画的,然后通过JNA调用Win32实现了窗口最大化、最小化等功能……
原因如上。 :-)
发表评论
-
读了一篇访谈《Philippe Kruchten谈论架构和技术债务》
2011-11-28 17:33 955看了InfoQ中的一篇访谈《Philippe Kruchten ... -
开发单元测试脚手架 - 第一篇 - 需求分析
2011-07-28 23:02 1884文档计划(暂定) 文档名称 计划完成时间 完成 ... -
最近在忙什么呢?
2011-07-21 22:57 1078这段时间分享激情被工作淡了 2011年上半年盘点 ... -
【阅读笔记】jvm性能工具-jstat解决100%CPU占用率分析
2011-05-08 13:17 6403阅读文章:http://www.theserverside.c ... -
(读书)实现模式 第三章 一种编程理论
2010-12-02 13:15 994全书内容导游图 ... -
(读书)实现模式 前言
2010-12-02 12:56 1015突然发现自己什么都不懂了,有时候又觉得自己无所不知道一 ... -
华表Cell文件导入导出
2010-03-21 11:39 6466在福州出差ing…… ... -
commons net 下的FTPClient使用时的一些小问题
2010-03-20 01:28 4814原始发表时间:2009-08-20 FTPCl ... -
JNA映射自己编写的DLL
2010-03-20 01:19 3615原始发表时间:2009-07-03 学习过程 - 思维 ... -
解决tomcat窗口启动时因为某些错误而一闪而过
2010-03-19 23:49 2566原始发表时间:2009-04-20 参考文章http: ... -
使用JMeter做压力测试-对数据库
2010-03-19 23:00 9896最早发表时间:2009-04-06 ... -
使用Java正则表达式硬编码实现有限层的嵌套匹配
2010-03-19 22:28 4106原始发表时间:2009-04-05 今天遇到 ... -
用Java没有好的方法生成大数据量的Excel
2010-03-19 21:47 2957最早发表时间:2009-01-13 ... -
使用Spring动态修改DataSource
2010-03-19 21:45 11321最早发表时间:2008-12-03 我们现在在 ... -
JUnit 使用小问题,浪费了一个钟头……
2010-03-19 21:38 1049在Eclipse3.4当中写一个测试用例的时候,继承了 ... -
利用Eclipse Birt 2.2 的 Chart 标签库打造网页图表
2010-03-19 21:19 3053Eclipse Birt 2.2 的发布,着实让我吓了 ...
相关推荐
总的来说,通过Java和JNA的结合,我们可以实现对操作系统窗口的控制,这在需要进行桌面自动化、测试脚本编写或系统集成等场景时非常有用。JNA简化了与本机代码的交互,让Java开发者可以利用Java的强大功能同时享受...
本话题将详细介绍如何使用JNA获取窗口句柄并发送消息,以及在CS(Client-Server)架构中实现SSO(Single Sign-On)。 首先,让我们深入理解JNA的工作原理。JNA允许Java程序直接调用系统函数库中的函数,通过映射...
jna 实现回调函数 code.zip jna 实现回调函数 code.zip jna 实现回调函数 code.zip jna 实现回调函数 code.zip jna 实现回调函数 code.zip jna 实现回调函数 code.zip jna 实现回调函数 code.zip
在“JNA实现回调及其他”这个主题中,我们将深入探讨JNA如何实现回调函数以及其在实际应用中的其他关键特性。 ### 1. JNA的基本原理 JNA的核心在于其“结构体-接口”映射机制。Java中定义的接口会被映射为C/C++的...
JNA通过动态链接库(DLLs on Windows,shared libraries on Unix/Linux)实现了这一点,极大地简化了Java应用程序与本地资源的交互。`jna.jar`文件是JNA库的核心组件,包含了所有必要的类和资源,使得开发者可以在...
标题中的“jna控制键盘”指的是使用Java Native Access (JNA) 库来实现对键盘输入的控制。JNA是Java平台上的一个开源库,它允许Java代码与本机库进行交互,无需编写C/C++的JNI代码。通过JNA,开发者可以直接调用操作...
总的来说,JNA作为一个强大的库,简化了Java与本地库交互的过程,使得开发者可以在Java环境中充分利用系统资源,实现更丰富的功能。在使用过程中,需要注意版本间的差异,以及正确配置和管理本地库的依赖。同时,...
总结,jna-example.jar是Java开发者实现高级图形界面功能的有力工具,通过JNA库,我们可以轻松地利用操作系统底层API,实现窗口透明和不规则形状显示,从而打造出更具吸引力和个性化的应用程序。同时,掌握JNA的使用...
本教程将详细讲解如何在Android Studio中使用JNA来实现本地库的调用。 1. **JNA简介** - JNA是一种轻量级的框架,通过动态映射本地函数到Java方法,使得Java可以直接调用C/C++等本地库。 - 它通过提供一个接口...
标题"jna jar实现java调用dll"指的是使用JNA库来在Java程序中调用Windows平台上的动态链接库(DLL)文件。JNA通过jar包的形式提供服务,使得Java开发者可以方便地将DLL的功能集成到Java应用中。 描述中提到...
2. 不规则形状JFrame:JNA可以调用GDI32库中的函数,配合Shape类来实现自定义窗口形状。例如,使用CreateRoundRectRgn创建一个矩形区域,并设置为窗口的形状。 ```java public static HRGN createRoundRectRgn(int ...
jna-4.5.1 , jna-4.5.1-sources , jna-platform-4.5.1 jar包 JNA全称Java Native Access,是一个...开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。
JNA通过映射Java方法到本地函数,实现了Java与操作系统底层功能的交互,极大地简化了在Java应用中使用系统API或DLL库的过程。在这个场景中,我们有两个文件:`jna-3.3.0.jar`和`jna-3.3.0-platform.jar`,它们分别是...
例如,通过JNA,你可以调用Windows API中的`GetWindowText`函数来获取窗口的标题,或者在Unix系统中使用`read`函数读取文件内容。 `jna-platform.jar` 是JNA的平台特定库,包含了针对特定操作系统的一些预定义接口...
不规则形状的 JFrame 则可能涉及到了图形绘制和剪裁,JNA 可以调用图形库函数来实现非矩形窗口。 总之,JNA 是 Java 平台上一个强大的本地访问工具,通过它可以轻松地将 Java 应用程序与操作系统底层功能相结合,而...
1. `jna-5.8.0.jar`:这是JNA的核心库文件,包含了JNA框架的类和接口,以及用于与本地平台交互的实现。通过导入这个库,Java项目就可以使用JNA提供的服务,如加载本地库、调用本地函数等。 2. `jna-platform-5.8.0....
解压这个文件后,用户可以查看JNA的源代码,了解其内部实现机制,进行定制化开发或者为项目贡献代码。源码可能包括JNA库本身、示例、文档以及其他辅助工具。通过研究源码,开发者可以更好地理解JNA如何处理内存管理...
JNA通过反射机制实现了对本地库的动态调用,并且支持Windows下的.dll文件以及其他平台上的共享库。 #### 二、JNA实例分析 根据题目提供的信息,本节将详细解析一个JNA的应用实例。首先,我们将介绍C语言源代码部分...
在JNA中,本地函数的调用是通过定义一个接口并使用`native`关键字来实现的。这个接口将被JNA用来动态加载和调用对应的本地库函数。例如,如果要调用Windows API中的`FindWindow`函数来获取窗口句柄,可以这样定义: ...