精华内容
下载资源
问答
  • jna

    2020-05-12 19:42:21
  • JNA

    2016-06-07 10:52:00
    1.下载jna.jar https://github.com/java-native-access/jna 2.安装 将jna.jar文件移动到JDK的安装目录的子目录,我的是:/opt/java/jdk1.7.0/lib。这个jna.jar文件也可以放在任何目录,比如你正在开发的Java工程...

    1.下载jna.jar

    https://github.com/java-native-access/jna

    2.安装

    将jna.jar文件移动到JDK的安装目录的子目录,我的是:/opt/java/jdk1.7.0/lib。这个jna.jar文件也可以放在任何目录,比如你正在开发的Java工程目录。

    3.官方文档

     

     

    http://java-native-access.github.io/jna/4.2.1

     

    转载于:https://www.cnblogs.com/chensheng-zhou/p/5566236.html

    展开全文
  • JNA

    2011-03-23 13:39:00
    JNA 文章分类:Java编程... <br />JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架。 <br />JNA项目地址:https://jn

    JNA

    文章分类:Java编程

    http://hi.baidu.com/dflgq/blog/item/b199cc5246f680561138c263.html


    介绍
    给大家介绍一个最新的访问本机代码的Java框架—JNA。

    JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架。

    JNA项目地址:https://jna.dev.java.net/


    非常强大、易用,功能上类似与.NET的P/Invoke。




    不堪回首的JNI
    我们知道,使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的。

    如果有一个现有的.dll/.so文件,如果使用JNI技术调用,我们首先需要另外使用C语言写一个.dll/.so共享库,使用SUN规定的数据结构替代C语言的数据结构,调用已有的 dll/so中公布的函数。

    然后再在Java中载入这个适配器dll/so,再编写Java   native函数作为dll中函数的代理。

    经过2个繁琐的步骤才能在Java中调用本地代码。

    因此,很少有Java程序员愿意编写调用dll/.so库中的原生函数的java程序。这也使Java语言在客户端上乏善可陈。可以说JNI是Java的一大弱点!


    .NET平台上强大的P/Invoke
    而在.NET平台上,强大的P/Invoke技术使我们Java程序员非常羡慕。使用P/Invoke技术,只需要使用编写一个.NET函数,再加上一个声明的标注,就可以直接调用dll中的函数。

    不需要你再使用C语言编写dll来适配。



    不逊于P/Invoke的JNA
    现在,不需要再羡慕.NET的P/Invoke机制了。JNA把对dll/.so共享库的调用减少到了和P/Invoke相同的程度。


    使用JNA,不需要再编写适配用的.dll/.so,只需要在Java中编写一个接口和一些代码,作为.dll/.so的代理,就可以在Java程序中调用dll/so。



    JNA快速启动


         现在让我们直接进入JNA的世界。


    你只需要下载一个jar包,就可以使用JNA的强大功能方便地调用动态链接库中的C函数。

    1,下载jna.jar。

    在这里https://jna.dev.java.net/servlets/ProjectDocumentList?folderID=7408&expandFolder=7408&folderID=0



    2,现在你已经可以使用JNA了。

    为了方便你参考JNA的java类库,我制作了《JNA3.09API参考手册》,是CHM格式的。你可以到这里下载 http://download.csdn.net/source/900438





    JNA例子


    例子1   
    现在让我们运行一个JNA程序,感受它的强大威力。

    1,在Java项目中引入jna.jar包。

    2,创建一个类:


    import com.sun.jna.Library;

    import com.sun.jna.Native;

    import com.sun.jna.Platform;


    /** Simple example of native library declaration and usage. */

    public class HelloWorld {


        public interface CLibrary extends Library {

            CLibrary INSTANCE = (CLibrary)

                Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),

                                   CLibrary.class);

      

            void printf(String format, Object... args);

        }


        public static void main(String[] args) {

            CLibrary.INSTANCE.printf("Hello, World/n");

            for (int i=0;i < args.length;i++) {

                CLibrary.INSTANCE.printf("Argument %d: %s/n", i, args[i]);

            }

        }

    }





    3,执行,可以看到控制台中打印出了

    Hello, World


        但是,请注意,这个程序实际上是使用msvcrt.dll这个C运行时库中的printf函数打印出上面这些字符的。


        看,多简单,不需要写一行C代码,就可以直接在Java中调用外部动态链接库中的函数!


    例子2   


        上面那个例子使用了操作系统自带的动态链接库,现在我们再自己写一个动态链接库试试。



    1,在VS中选择C++语言,然后选择创建一个Win32程序。 选择dll类型。


    2,发布的C函数是:


    #define MYLIBAPI extern   "C"     __declspec( dllexport )


    MYLIBAPI void say(wchar_t* pValue);



    这个函数的实现是:


    void say(wchar_t* pValue){

         std::wcout.imbue(std::locale("chs"));


         std::wcout<<L"上帝说:"<<pValue<<std::endl;

    }


    它需要传入一个Unicode编码的字符数组。然后在控制台上打印出一段中文字符。


    3,生成dll。然后把生成的dll文件复制到Eclipse项目中,放在项目下面。

    4,在Eclipse中编写以下代码:


    import com.sun.jna.Library;

    import com.sun.jna.Native;

    import com.sun.jna.WString;


    /**

    * @author 沈东良 Edward Shen shendl_s@hotmail.com

    * 2008-11-23 下午05:07:14

    *TestDll1.dll

    */

    public class TestDll1Service {


             public interface TestDll1 extends Library {

                       /**

                        * 当前路径是在项目下,而不是bin输出目录下。

                        */

                       TestDll1 INSTANCE = (TestDll1)Native.loadLibrary("TestDll1", TestDll1.class);

                       public void say(WString value);

                     

             }

             /**

              *

              */

             public TestDll1Service() {

                       // TODO Auto-generated constructor stub

             }


             /**

              * @param args

              */

             public static void main(String[] args) {

                       // TODO Auto-generated method stub

                     

                       TestDll1.INSTANCE.say(new WString("Hello World!"));

                       System.out.println("HHEEH我我们无法万恶");

             }


    }


    5,执行这个Java类。可以看到控制台下如下输出:

    上帝说:Hello World!

    HHEEH我我们无法万恶


    6,上面一行是C语言使用C++的std::wcout输出的。

    下面一行是Java语言输出的。




    JNA技术解密
    JNA工作原理
    JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数。

    原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Java的数据类型。

    JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射。你不再需要编写C动态链接库。

    当然,这也意味着,使用JNA技术比使用JNI技术调用动态链接库会有些微的性能损失。可能速度会降低几倍。但影响不大。


    JNA技术难点



    1,当前路径是在项目下,而不是bin输出目录下。

    2,数据结构的对应关系:

    Java—C和操作系统数据类型的对应表
    Java Type
    C Type
    Native Representation

    boolean
    int
    32-bit integer (customizable)

    byte
    char
    8-bit integer

    char
    wchar_t
    platform-dependent

    short
    short
    16-bit integer

    int
    int
    32-bit integer

    long
    long long, __int64
    64-bit integer

    float
    float
    32-bit floating point

    double
    double
    64-bit floating point

    Buffer
    Pointer
    pointer
    platform-dependent (32- or 64-bit pointer to memory)

    <T>[] (array of primitive type)
    pointer
    array
    32- or 64-bit pointer to memory (argument/return)
    contiguous memory (struct member)

    除了上面的类型,JNA还支持常见的数据类型的映射。

    String
    char*
    NUL-terminated array (native encoding or jna.encoding)

    WString
    wchar_t*
    NUL-terminated array (unicode)

    String[]
    char**
    NULL-terminated array of C strings

    WString[]
    wchar_t**
    NULL-terminated array of wide C strings

    Structure
    struct*
    struct
    pointer to struct (argument or return) (or explicitly)
    struct by value (member of struct) (or explicitly)

    Union
    union
    same as Structure

    Structure[]
    struct[]
    array of structs, contiguous in memory

    Callback
    <T> (*fp)()
    function pointer (Java or native)

    NativeMapped
    varies
    depends on definition

    NativeLong
    long
    platform-dependent (32- or 64-bit integer)

    PointerType
    pointer
    same as Pointer




    JNA编程过程


    JNA把一个dll/.so文件看做是一个Java接口。

    Dll是C函数的集合、容器,这正和接口的概念吻合。


        我们定义这样一个接口,

    public interface TestDll1 extends Library {

                       /**

                        * 当前路径是在项目下,而不是bin输出目录下。

                        */

                       TestDll1 INSTANCE = (TestDll1)Native.loadLibrary("TestDll1", TestDll1.class);

                       public void say(WString value);

                     

             }



    如果dll是以stdcall方式输出函数,那么就继承StdCallLibrary。否则就继承默认的Library接口。


    接口内部需要一个公共静态常量:instance。


    TestDll1 INSTANCE = (TestDll1)Native.loadLibrary("TestDll1", TestDll1.class);


    通过这个常量,就可以获得这个接口的实例,从而使用接口的方法。也就是调用外部dll的函数!


    注意:

    1,Native.loadLibrary()函数有2个参数:

        1,dll或者.so文件的名字,但不带后缀名。这符合JNI的规范,因为带了后缀名就不可以跨操作系统平台了。

    搜索dll的路径是:

    1)项目的根路径

    2)操作系统的全局路径、

    3)path指定的路径。


    2,第二个参数是本接口的Class类型。


    JNA通过这个Class类型,根据指定的dll/.so文件,动态创建接口的实例。


    2,接口中你只需要定义你需要的函数或者公共变量,不需要的可以不定义。

    public void say(WString value);


    参数和返回值的类型,应该和dll中的C函数的类型一致。

    这是JNA,甚至所有跨平台调用的难点。


    这里,C语言的函数参数是:wchar_t*。

    JNA中对应的Java类型是WStirng。



    所有跨平台、跨语言调用的难点
    有过跨语言、跨平台开发的程序员都知道,跨平台、语言调用的难点,就是不同语言之间数据类型不一致造成的问题。绝大部分跨平台调用的失败,都是这个问题造成的。

    关于这一点,不论何种语言,何种技术方案,都无法解决这个问题。

    这需要程序员的仔细开发和设计。这是程序员的责任。


    常见的跨平台调用有:
    1,Java调用C语言编写的dll、.so动态链接库中的函数。

    2,.NET通过P/Invoke调用C语言编写的dll、.so动态链接库中的函数。

    3,通过WEBService,在C,C++,Java,.NET等种种语言间调用。

        WebService传递的是xml格式的数据。


    即使是强大的P/Invoke或者WebService,在遇到复杂的数据类型和大数据量的传递时,还是会碰到很大的困难。


    因为,一种语言的复杂的数据类型,很难用另一种语言来表示。这就是跨平台调用问题的本质。
    如,WEBService调用中,很多语言,如Java,.NET都有自动实现的Java/.NET类型和XML类型之间的映射的类库或者工具。

    但是,在现实的编程环境中,如果类型非常复杂,那么这些自动转换工具常常力不从心。

    要么Object-XML映射错误。

    要么映射掉大量的内存。


    因此,我个人对这些Object-XML映射框架相当不感冒。

    我现在使用WEBService,都是直接手工使用xml处理工具提取xml中的数据构建对象。或者反过来,手工根据Object中的属性值构建xml数据。



    Java和C语言之间的调用问题,也是如此。

    Java要调用C语言的函数,那么就必须严格按照C语言要求的内存数量提供Java格式的数据。要用Java的数据类型完美模拟C语言的数据类型。

    JNA已经提供了大量的类型匹配C语言的数据类型。




    跨平台、跨语言调用的第一原则:就是尽量使用基本、简单的数据类型,尽量少跨语言、平台传递数据!
    只有你才能拯救你自己。

    如果在你的程序中,有复杂的数据类型和庞大的跨平台数据传递。那么你必须另外写一些Façade接口,把需要传递的数据类型简化,把需要传递的数据量简化。

    否则,不论是实现的难度还是程序的性能都很难提高。





    JNI还是不能废
    我们已经见识了JNA的强大。JNI和它相比是多么的简陋啊!

    但是,有些需求还是必须求助于JNI。

    JNA是建立在JNI技术基础之上的一个框架。

    使用JNI技术,不仅可以实现Java访问C函数,也可以实现C语言调用Java代码。

    而JNA只能实现Java访问C函数,作为一个Java框架,自然不能实现C语言调用Java代码。此时,你还是需要使用JNI技术。

    JNI是JNA的基础。是Java和C互操作的技术基础。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/shendl/archive/2008/12/23/3589676.aspx
    展开全文
  • 1、监测,使用JNA: pom.xml: <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>4.0.0</version> </dependency> &...

    1、监测,使用JNA:

    pom.xml:
    记住使用5.0.0以上的版本

          <dependency>
                <groupId>net.java.dev.jna</groupId>
                <artifactId>jna</artifactId>
                <version>5.0.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform -->
            <dependency>
                <groupId>net.java.dev.jna</groupId>
                <artifactId>jna-platform</artifactId>
                <version>5.0.0</version>
            </dependency>
    

    键盘:

    public class KeyboardHook implements Runnable
    {
    	private WinUser.HHOOK hhk;
     
    	// 钩子回调函数
    	private WinUser.LowLevelKeyboardProc keyboardProc = new WinUser.LowLevelKeyboardProc()
    	{
    		@Override
    		public LRESULT callback(int nCode, WPARAM wParam, WinUser.KBDLLHOOKSTRUCT event)
    		{
    			// 输出按键值和按键时间
    			if (nCode >= 0)
    			{
    				// 按下F7退出
    				if (event.vkCode == 118)
    				{
    					KeyboardHook.this.setHookOff();
    					System.exit(0);
    				}
    			}
    			
    			return User32.INSTANCE.CallNextHookEx(hhk, nCode, wParam, null);
    		}
    	};
     
    	public void run()
    	{
    		setHookOn();
    	}
     
    	// 安装钩子
    	public void setHookOn()
    	{
    		HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
    		hhk = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardProc, hMod, 0);
    		
    		int result;
    		WinUser.MSG msg = new WinUser.MSG();
    		while ((result = User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0)
    		{
    			if (result == -1)
    			{
    				setHookOff();
    				break;
    			} else
    			{
    				User32.INSTANCE.TranslateMessage(msg);
    				User32.INSTANCE.DispatchMessage(msg);
    			}
    		}
    	}
     
    	// 移除钩子并退出
    	public void setHookOff()
    	{
    		User32.INSTANCE.UnhookWindowsHookEx(hhk);
    	}
    }
    

    鼠标:

     @Override
        public void run() {
            setHookOn();
        }
    
        private WinUser.HHOOK hhk;
    
        private WinUser.LowLevelKeyboardProc mouseProc = new WinUser.LowLevelKeyboardProc() {
    
            @Override
            public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.KBDLLHOOKSTRUCT event) {
                // 加个间隔时间判断,不然太消耗系统资源
                if (System.currentTimeMillis() - ShuBiaoJianKong.last.getTime() >= 200000) {
                    if (nCode >= 0) {
                        ShuBiaoJianKong.last = new Date();
                        if (wParam.intValue() == 512) {
                            System.out.println("鼠标移动");
                        }
    
                        if (wParam.intValue() == 513) {
                            System.out.println("鼠标左键按下");
                        }
    
                        if (wParam.intValue() == 514) {
                            System.out.println("鼠标左键弹起");
                        }
    
                        if (wParam.intValue() == 516) {
                            System.out.println("鼠标右键按下");
                        }
    
                        if (wParam.intValue() == 517) {
                            System.out.println("鼠标右键弹起");
                        }
                    }
                }
                return User32.INSTANCE.CallNextHookEx(hhk, nCode, wParam, null);
            }
        };
    
    
        // 安装钩子
        public void setHookOn() {
            WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
            hhk = User32.INSTANCE.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseProc, hMod, 0);
            int result;
            WinUser.MSG msg = new WinUser.MSG();
            while ((result = User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0) {
                if (result == -1) {
                    setHookOff();
                    break;
                } else {
                    User32.INSTANCE.TranslateMessage(msg);
                    User32.INSTANCE.DispatchMessage(msg);
                }
            }
        }
    
        // 移除钩子并退出
        public void setHookOff() {
            User32.INSTANCE.UnhookWindowsHookEx(hhk);
            System.exit(0);
        }
    

    2.控制,使用Robot

    package test.supcon.util;
    
    import java.awt.*;
    /**
     * @author: zhaoxu
     * @date: 2020/9/25 11:20
     */
    public class ShuBiao implements Runnable {
        Robot rb;
    
        public ShuBiao(Robot robot) {
            rb = robot;
        }
    
        public static void main(String[] args) throws Exception {
            final Robot rb = new Robot();
            rb.delay(500);
            ShuBiao ControlMouse = new ShuBiao(rb);
            new Thread(ControlMouse).start();
        }
    
        @Override
        public void run() {
            while (true) {
                rb.mouseMove((int) (Math.random() * (3500 - 3000 + 1) + 3000), (int) (Math.random() * (500 - 200 + 1) + 200));
                try {
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    3.相结合,实现监控鼠标,超时打开远程文件再关闭,永久亮屏(其实这个功能没有用到Robot)

    ControShuBiao.class:

    package test.supcon.util;
    
    import java.awt.*;
    import java.awt.event.InputEvent;
    import java.io.IOException;
    import java.util.Date;
    
    /**
     * @author: zhaoxu
     * @date: 2020/9/25 16:08
     */
    public class ControShuBiao implements Runnable {
        Robot rb;
    
        public ControShuBiao(Robot robot) {
            rb = robot;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(10000);
                    if (System.currentTimeMillis() - ShuBiaoJianKong.last.getTime() >= 10000) {
                        ShuBiaoJianKong.open("remote.rdp");
                        Thread.sleep(300);
                        ShuBiaoJianKong.close();
                        ShuBiaoJianKong.last = new Date();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    //            rb.mouseMove(3500, 500);
    //            rb.mouseMove(3500, 300);
    //            rb.mousePress(InputEvent.BUTTON1_MASK);
    //            rb.keyPress(KeyEvent.VK_0);
    //            rb.keyPress(KeyEvent.VK_1);
            }
        }
    }
    

    ShuBiaoJianKong.class:

    package test.supcon.util;
    
    import com.sun.jna.Native;
    import com.sun.jna.Pointer;
    import com.sun.jna.platform.win32.*;
    
    import java.awt.*;
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Date;
    
    import static java.lang.Thread.sleep;
    
    /**
     * @author: zhaoxu
     * @date: 2020/9/25 15:20
     */
    public class ShuBiaoJianKong implements Runnable {
        static volatile Date last = new Date();
        static volatile Date main = new Date();
        static ArrayList<String> windowText = new ArrayList<>();
    
        public static void close() throws IOException, InterruptedException {
    //        通过窗口标题获取窗口句柄
            WinDef.HWND hWnd;
            final User32 user32 = User32.INSTANCE;
            user32.EnumWindows(new WinUser.WNDENUMPROC() {
                @Override
                public boolean callback(WinDef.HWND hWnd, Pointer arg1) {
                    char[] windowText = new char[512];
                    user32.GetWindowText(hWnd, windowText, 512);
                    String wText = Native.toString(windowText);
                    // get rid of this if block if you want all windows regardless of whether
                    // or not they have text
                    if (wText.isEmpty()) {
                        return true;
                    }
                    if (wText.contains("Google Chrome (192.168.70.241)")) {
                        ShuBiaoJianKong.windowText.add(wText);
                    }
                    System.out.println(wText);
                    return true;
                }
            }, null);
            if (ShuBiaoJianKong.windowText.size() < 1) {
                System.out.println("找不到窗口,正在打开窗口。。。");
                ShuBiaoJianKong.windowText.add("新标签页 - Google Chrome (192.168.70.241)");
                open("remote.rdp");
            } else {
                int y = 0;
                for (String title : ShuBiaoJianKong.windowText) {
                    hWnd = User32.INSTANCE.FindWindow(null, title);
                    if ("新标签页 - Google Chrome (192.168.70.241)".equals(title) && y == 0) {
                        WinDef.LRESULT lresult = User32.INSTANCE.SendMessage(hWnd, 0X10, null, null);
                        System.out.println("关闭成功");
                        y++;
                    } else {
                        int i = (int) (Math.random() * (3 - 2 + 1) + 2);
                        User32.INSTANCE.ShowWindow(hWnd, i);
                        User32.INSTANCE.SetForegroundWindow(hWnd);
                    }
    //                String username = "a";
    //                for (Character c : username.toCharArray()) {
    //                    sendChar(c);
    //                }
                }
            }
        }
    
        public static void open(String path) throws IOException {
            java.awt.Desktop dp = java.awt.Desktop.getDesktop();
            if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
                File file = new File(path);
                dp.open(file);
            }
        }
    
        public static void main(String[] args) throws Exception {
            System.out.println("正在监控中。。。。");
            final Robot rb = new Robot();
            rb.delay(500);
            ShuBiaoJianKong jianKong = new ShuBiaoJianKong();
            new Thread(jianKong).start();
            new Thread(new ControShuBiao(rb)).start();
        }
    
        static WinUser.INPUT input = new WinUser.INPUT();
    
        static void sendChar(char ch) {
            input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD);
            input.input.setType("ki"); // Because setting INPUT_INPUT_KEYBOARD is not enough: https://groups.google.com/d/msg/jna-users/NDBGwC1VZbU/cjYCQ1CjBwAJ
            input.input.ki.wScan = new WinDef.WORD(0);
            input.input.ki.time = new WinDef.DWORD(0);
            input.input.ki.dwExtraInfo = new BaseTSD.ULONG_PTR(0);
            // Press
            input.input.ki.wVk = new WinDef.WORD(Character.toUpperCase(ch)); // 0x41
            input.input.ki.dwFlags = new WinDef.DWORD(0);  // keydown
            User32.INSTANCE.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());
            // Release
            input.input.ki.wVk = new WinDef.WORD(Character.toUpperCase(ch)); // 0x41
            input.input.ki.dwFlags = new WinDef.DWORD(2);  // keyup
            User32.INSTANCE.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());
        }
    
        @Override
        public void run() {
            setHookOn();
        }
    
        private WinUser.HHOOK hhk;
    
        private WinUser.LowLevelKeyboardProc mouseProc = new WinUser.LowLevelKeyboardProc() {
    
            @Override
            public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.KBDLLHOOKSTRUCT event) {
                if (nCode >= 0) {
                    ShuBiaoJianKong.last = new Date();
                    if (wParam.intValue() == 512) {
                        System.out.println("鼠标移动");
                    }
    
                    if (wParam.intValue() == 513) {
                        System.out.println("鼠标左键按下");
                    }
    
                    if (wParam.intValue() == 514) {
                        System.out.println("鼠标左键弹起");
                    }
    
                    if (wParam.intValue() == 516) {
                        System.out.println("鼠标右键按下");
                    }
    
                    if (wParam.intValue() == 517) {
                        System.out.println("鼠标右键弹起");
                    }
                }
                return User32.INSTANCE.CallNextHookEx(hhk, nCode, wParam, null);
            }
        };
    
        public void setHookOn() {
            WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
            hhk = User32.INSTANCE.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseProc, hMod, 0);
            int result;
            WinUser.MSG msg = new WinUser.MSG();
            while ((result = User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0) {
                if (result == -1) {
                    setHookOff();
                    break;
                } else {
                    User32.INSTANCE.TranslateMessage(msg);
                    User32.INSTANCE.DispatchMessage(msg);
                }
            }
        }
    
        public void setHookOff() {
            User32.INSTANCE.UnhookWindowsHookEx(hhk);
            System.exit(0);
        }
    }
    

    wMsg参数常量值:

    //创建一个窗口   
    const int WM_CREATE = 0x01;   
    //当一个窗口被破坏时发送   
    const int WM_DESTROY = 0x02;   
    //移动一个窗口   
    const int WM_MOVE = 0x03;   
    //改变一个窗口的大小   
    const int WM_SIZE = 0x05;   
    //一个窗口被激活或失去激活状态   
    const int WM_ACTIVATE = 0x06;   
    //一个窗口获得焦点   
    const int WM_SETFOCUS = 0x07;   
    //一个窗口失去焦点   
    const int WM_KILLFOCUS = 0x08;   
    //一个窗口改变成Enable状态   
    const int WM_ENABLE = 0x0A;   
    //设置窗口是否能重画   
    const int WM_SETREDRAW = 0x0B;   
    //应用程序发送此消息来设置一个窗口的文本   
    const int WM_SETTEXT = 0x0C;   
    //应用程序发送此消息来复制对应窗口的文本到缓冲区   
    const int WM_GETTEXT = 0x0D;   
    //得到与一个窗口有关的文本的长度(不包含空字符)   
    const int WM_GETTEXTLENGTH = 0x0E;   
    //要求一个窗口重画自己   
    const int WM_PAINT = 0x0F;   
    //当一个窗口或应用程序要关闭时发送一个信号   
    const int WM_CLOSE = 0x10;   
    //当用户选择结束对话框或程序自己调用ExitWindows函数   
    const int WM_QUERYENDSESSION = 0x11;   
    //用来结束程序运行   
    const int WM_QUIT = 0x12;   
    //当用户窗口恢复以前的大小位置时,把此消息发送给某个图标   
    const int WM_QUERYOPEN = 0x13;   
    //当窗口背景必须被擦除时(例在窗口改变大小时)   
    const int WM_ERASEBKGND = 0x14;   
    //当系统颜色改变时,发送此消息给所有顶级窗口   
    const int WM_SYSCOLORCHANGE = 0x15;   
    //当系统进程发出WM_QUERYENDSESSION消息后,此消息发送给应用程序,通知它对话是否结束   
    const int WM_ENDSESSION = 0x16;   
    //当隐藏或显示窗口是发送此消息给这个窗口   
    const int WM_SHOWWINDOW = 0x18;   
    //发此消息给应用程序哪个窗口是激活的,哪个是非激活的   
    const int WM_ACTIVATEAPP = 0x1C;   
    //当系统的字体资源库变化时发送此消息给所有顶级窗口   
    const int WM_FONTCHANGE = 0x1D;   
    //当系统的时间变化时发送此消息给所有顶级窗口   
    const int WM_TIMECHANGE = 0x1E;   
    //发送此消息来取消某种正在进行的摸态(操作)   
    const int WM_CANCELMODE = 0x1F;   
    //如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时,就发消息给某个窗口   
    const int WM_SETCURSOR = 0x20;   
    //当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给//当前窗口   
    const int WM_MOUSEACTIVATE = 0x21;   
    //发送此消息给MDI子窗口//当用户点击此窗口的标题栏,或//当窗口被激活,移动,改变大小   
    const int WM_CHILDACTIVATE = 0x22;   
    //此消息由基于计算机的训练程序发送,通过WH_JOURNALPALYBACK的hook程序分离出用户输入消息   
    const int WM_QUEUESYNC = 0x23;   
    //此消息发送给窗口当它将要改变大小或位置   
    const int WM_GETMINMAXINFO = 0x24;   
    //发送给最小化窗口当它图标将要被重画   
    const int WM_PAINTICON = 0x26;   
    //此消息发送给某个最小化窗口,仅//当它在画图标前它的背景必须被重画   
    const int WM_ICONERASEBKGND = 0x27;   
    //发送此消息给一个对话框程序去更改焦点位置   
    const int WM_NEXTDLGCTL = 0x28;   
    //每当打印管理列队增加或减少一条作业时发出此消息    
    const int WM_SPOOLERSTATUS = 0x2A;   
    //当button,combobox,listbox,menu的可视外观改变时发送   
    const int WM_DRAWITEM = 0x2B;   
    //当button, combo box, list box, list view control, or menu item 被创建时   
    const int WM_MEASUREITEM = 0x2C;   
    //此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息    
    const int WM_VKEYTOITEM = 0x2E;   
    //此消息由一个LBS_WANTKEYBOARDINPUT风格的列表框发送给他的所有者来响应WM_CHAR消息    
    const int WM_CHARTOITEM = 0x2F;   
    //当绘制文本时程序发送此消息得到控件要用的颜色   
    const int WM_SETFONT = 0x30;   
    //应用程序发送此消息得到当前控件绘制文本的字体   
    const int WM_GETFONT = 0x31;   
    //应用程序发送此消息让一个窗口与一个热键相关连    
    const int WM_SETHOTKEY = 0x32;   
    //应用程序发送此消息来判断热键与某个窗口是否有关联   
    const int WM_GETHOTKEY = 0x33;   
    //此消息发送给最小化窗口,当此窗口将要被拖放而它的类中没有定义图标,应用程序能返回一个图标或光标的句柄,当用户拖放图标时系统显示这个图标或光标   
    const int WM_QUERYDRAGICON = 0x37;   
    //发送此消息来判定combobox或listbox新增加的项的相对位置   
    const int WM_COMPAREITEM = 0x39;   
    //显示内存已经很少了   
    const int WM_COMPACTING = 0x41;   
    //发送此消息给那个窗口的大小和位置将要被改变时,来调用setwindowpos函数或其它窗口管理函数   
    const int WM_WINDOWPOSCHANGING = 0x46;   
    //发送此消息给那个窗口的大小和位置已经被改变时,来调用setwindowpos函数或其它窗口管理函数   
    const int WM_WINDOWPOSCHANGED = 0x47;   
    //当系统将要进入暂停状态时发送此消息   
    const int WM_POWER = 0x48;   
    //当一个应用程序传递数据给另一个应用程序时发送此消息   
    const int WM_COPYDATA = 0x4A;   
    //当某个用户取消程序日志激活状态,提交此消息给程序   
    const int WM_CANCELJOURNA = 0x4B;   
    //当某个控件的某个事件已经发生或这个控件需要得到一些信息时,发送此消息给它的父窗口    
    const int WM_NOTIFY = 0x4E;   
    //当用户选择某种输入语言,或输入语言的热键改变   
    const int WM_INPUTLANGCHANGEREQUEST = 0x50;   
    //当平台现场已经被改变后发送此消息给受影响的最顶级窗口   
    const int WM_INPUTLANGCHANGE = 0x51;   
    //当程序已经初始化windows帮助例程时发送此消息给应用程序   
    const int WM_TCARD = 0x52;   
    //此消息显示用户按下了F1,如果某个菜单是激活的,就发送此消息个此窗口关联的菜单,否则就发送给有焦点的窗口,如果//当前都没有焦点,就把此消息发送给//当前激活的窗口   
    const int WM_HELP = 0x53;   
    //当用户已经登入或退出后发送此消息给所有的窗口,//当用户登入或退出时系统更新用户的具体设置信息,在用户更新设置时系统马上发送此消息   
    const int WM_USERCHANGED = 0x54;   
    //公用控件,自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构   
    const int WM_NOTIFYFORMAT = 0x55;   
    //当用户某个窗口中点击了一下右键就发送此消息给这个窗口   
    //const int WM_CONTEXTMENU = ??;   
    //当调用SETWINDOWLONG函数将要改变一个或多个 窗口的风格时发送此消息给那个窗口   
    const int WM_STYLECHANGING = 0x7C;   
    //当调用SETWINDOWLONG函数一个或多个 窗口的风格后发送此消息给那个窗口   
    const int WM_STYLECHANGED = 0x7D;   
    //当显示器的分辨率改变后发送此消息给所有的窗口   
    const int WM_DISPLAYCHANGE = 0x7E;   
    //此消息发送给某个窗口来返回与某个窗口有关连的大图标或小图标的句柄   
    const int WM_GETICON = 0x7F;   
    //程序发送此消息让一个新的大图标或小图标与某个窗口关联   
    const int WM_SETICON = 0x80;   
    //当某个窗口第一次被创建时,此消息在WM_CREATE消息发送前发送   
    const int WM_NCCREATE = 0x81;   
    //此消息通知某个窗口,非客户区正在销毁    
    const int WM_NCDESTROY = 0x82;   
    //当某个窗口的客户区域必须被核算时发送此消息   
    const int WM_NCCALCSIZE = 0x83;   
    //移动鼠标,按住或释放鼠标时发生   
    const int WM_NCHITTEST = 0x84;   
    //程序发送此消息给某个窗口当它(窗口)的框架必须被绘制时   
    const int WM_NCPAINT = 0x85;   
    //此消息发送给某个窗口仅当它的非客户区需要被改变来显示是激活还是非激活状态   
    const int WM_NCACTIVATE = 0x86;   
    //发送此消息给某个与对话框程序关联的控件,widdows控制方位键和TAB键使输入进入此控件通过应   
    const int WM_GETDLGCODE = 0x87;   
    //当光标在一个窗口的非客户区内移动时发送此消息给这个窗口 非客户区为:窗体的标题栏及窗 的边框体   
    const int WM_NCMOUSEMOVE = 0xA0;   
    //当光标在一个窗口的非客户区同时按下鼠标左键时提交此消息   
    const int WM_NCLBUTTONDOWN = 0xA1;   
    //当用户释放鼠标左键同时光标某个窗口在非客户区十发送此消息    
    const int WM_NCLBUTTONUP = 0xA2;   
    //当用户双击鼠标左键同时光标某个窗口在非客户区十发送此消息   
    const int WM_NCLBUTTONDBLCLK = 0xA3;   
    //当用户按下鼠标右键同时光标又在窗口的非客户区时发送此消息   
    const int WM_NCRBUTTONDOWN = 0xA4;   
    //当用户释放鼠标右键同时光标又在窗口的非客户区时发送此消息   
    const int WM_NCRBUTTONUP = 0xA5;   
    //当用户双击鼠标右键同时光标某个窗口在非客户区十发送此消息   
    const int WM_NCRBUTTONDBLCLK = 0xA6;   
    //当用户按下鼠标中键同时光标又在窗口的非客户区时发送此消息   
    const int WM_NCMBUTTONDOWN = 0xA7;   
    //当用户释放鼠标中键同时光标又在窗口的非客户区时发送此消息   
    const int WM_NCMBUTTONUP = 0xA8;   
    //当用户双击鼠标中键同时光标又在窗口的非客户区时发送此消息   
    const int WM_NCMBUTTONDBLCLK = 0xA9;   
    //WM_KEYDOWN 按下一个键   
    const int WM_KEYDOWN = 0x0100;   
    //释放一个键   
    const int WM_KEYUP = 0x0101;   
    //按下某键,并已发出WM_KEYDOWN, WM_KEYUP消息   
    const int WM_CHAR = 0x102;   
    //当用translatemessage函数翻译WM_KEYUP消息时发送此消息给拥有焦点的窗口   
    const int WM_DEADCHAR = 0x103;   
    //当用户按住ALT键同时按下其它键时提交此消息给拥有焦点的窗口   
    const int WM_SYSKEYDOWN = 0x104;   
    //当用户释放一个键同时ALT 键还按着时提交此消息给拥有焦点的窗口   
    const int WM_SYSKEYUP = 0x105;   
    //当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后提交此消息给拥有焦点的窗口   
    const int WM_SYSCHAR = 0x106;   
    //当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后发送此消息给拥有焦点的窗口   
    const int WM_SYSDEADCHAR = 0x107;   
    //在一个对话框程序被显示前发送此消息给它,通常用此消息初始化控件和执行其它任务   
    const int WM_INITDIALOG = 0x110;   
    //当用户选择一条菜单命令项或当某个控件发送一条消息给它的父窗口,一个快捷键被翻译   
    const int WM_COMMAND = 0x111;   
    //当用户选择窗口菜单的一条命令或//当用户选择最大化或最小化时那个窗口会收到此消息   
    const int WM_SYSCOMMAND = 0x112;   
    //发生了定时器事件   
    const int WM_TIMER = 0x113;   
    //当一个窗口标准水平滚动条产生一个滚动事件时发送此消息给那个窗口,也发送给拥有它的控件   
    const int WM_HSCROLL = 0x114;   
    //当一个窗口标准垂直滚动条产生一个滚动事件时发送此消息给那个窗口也,发送给拥有它的控件   
    const int WM_VSCROLL = 0x115;   
    //当一个菜单将要被激活时发送此消息,它发生在用户菜单条中的某项或按下某个菜单键,它允许程序在显示前更改菜单   
    const int WM_INITMENU = 0x116;   
    //当一个下拉菜单或子菜单将要被激活时发送此消息,它允许程序在它显示前更改菜单,而不要改变全部   
    const int WM_INITMENUPOPUP = 0x117;   
    //当用户选择一条菜单项时发送此消息给菜单的所有者(一般是窗口)   
    const int WM_MENUSELECT = 0x11F;   
    //当菜单已被激活用户按下了某个键(不同于加速键),发送此消息给菜单的所有者   
    const int WM_MENUCHAR = 0x120;   
    //当一个模态对话框或菜单进入空载状态时发送此消息给它的所有者,一个模态对话框或菜单进入空载状态就是在处理完一条或几条先前的消息后没有消息它的列队中等待   
    const int WM_ENTERIDLE = 0x121;   
    //在windows绘制消息框前发送此消息给消息框的所有者窗口,通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置消息框的文本和背景颜色   
    const int WM_CTLCOLORMSGBOX = 0x132;   
    //当一个编辑型控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色   
    const int WM_CTLCOLOREDIT = 0x133;   
      
    //当一个列表框控件将要被绘制前发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置列表框的文本和背景颜色   
    const int WM_CTLCOLORLISTBOX = 0x134;   
    //当一个按钮控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置按纽的文本和背景颜色   
    const int WM_CTLCOLORBTN = 0x135;   
    //当一个对话框控件将要被绘制前发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置对话框的文本背景颜色   
    const int WM_CTLCOLORDLG = 0x136;   
    //当一个滚动条控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置滚动条的背景颜色   
    const int WM_CTLCOLORSCROLLBAR = 0x137;   
    //当一个静态控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以 通过使用给定的相关显示设备的句柄来设置静态控件的文本和背景颜色   
    const int WM_CTLCOLORSTATIC = 0x138;   
    //当鼠标轮子转动时发送此消息个当前有焦点的控件   
    const int WM_MOUSEWHEEL = 0x20A;   
    //双击鼠标中键   
    const int WM_MBUTTONDBLCLK = 0x209;   
    //释放鼠标中键   
    const int WM_MBUTTONUP = 0x208;   
    //移动鼠标时发生,同WM_MOUSEFIRST   
    const int WM_MOUSEMOVE = 0x200;   
    //按下鼠标左键   
    const int WM_LBUTTONDOWN = 0x201;   
    //释放鼠标左键   
    const int WM_LBUTTONUP = 0x202;   
    //双击鼠标左键   
    const int WM_LBUTTONDBLCLK = 0x203;   
    //按下鼠标右键   
    const int WM_RBUTTONDOWN = 0x204;   
    //释放鼠标右键   
    const int WM_RBUTTONUP = 0x205;   
    //双击鼠标右键   
    const int WM_RBUTTONDBLCLK = 0x206;   
    //按下鼠标中键   
    const int WM_MBUTTONDOWN = 0x207;   
      
    const int WM_USER = 0x0400;   
    const int MK_LBUTTON = 0x0001;   
    const int MK_RBUTTON = 0x0002;   
    const int MK_SHIFT = 0x0004;   
    const int MK_CONTROL = 0x0008;   
    const int MK_MBUTTON = 0x0010;   
    const int MK_XBUTTON1 = 0x0020;   
    const int MK_XBUTTON2 = 0x0040;
    

    ShowWindow 参数

    hWnd:指窗口句柄。
    nCmdShow:指定窗口如何显示。如果发送应用程序的程序提供了STARTUPINFO结构,则应用程序第一次调用ShowWindow时该参数被忽略。否则,在第一次调用ShowWindow函数时,该值应为在函数WinMain中nCmdShow参数。在随后的调用中,该参数可以为下列值之一:
    SW_FORCEMINIMIZE:在WindowNT5.0中最小化窗口,即使拥有窗口的线程被挂起也会最小化。在从其他线程最小化窗口时才使用这个参数。nCmdShow=11。
    SW_HIDE:隐藏窗口并激活其他窗口。nCmdShow=0。
    SW_MAXIMIZE:最大化指定的窗口。nCmdShow=3。
    SW_MINIMIZE:最小化指定的窗口并且激活在Z序中的下一个顶层窗口。nCmdShow=6。
    SW_RESTORE:激活并显示窗口。如果窗口最小化或最大化,则系统将窗口恢复到原来的尺寸和位置。在恢复最小化窗口时,应用程序应该指定这个标志。nCmdShow=9。
    SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。nCmdShow=5。
    SW_SHOWDEFAULT:依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。nCmdShow=10。
    SW_SHOWMAXIMIZED:激活窗口并将其最大化。nCmdShow=3。
    SW_SHOWMINIMIZED:激活窗口并将其最小化。nCmdShow=2。
    SW_SHOWMINNOACTIVE:窗口最小化,激活窗口仍然维持激活状态。nCmdShow=7。
    SW_SHOWNA:以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=8。
    SW_SHOWNOACTIVATE:以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=4。
    SW_SHOWNORMAL:激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。nCmdShow=1。
    
    展开全文
  • JNA-5.7.0 jna-platform-5.7.0

    2021-03-09 14:18:11
    JNA-5.7.0 jna-platform-5.7.0
  • JNA实例=======================================================JNA实例
  • Java Native Access (JNA) The definitive JNA reference (including an overview and usage details) is in the JavaDoc. Please read the overview. Questions, comments, or exploratory conversations should ...
  • jna-4.5.1最新JNA

    2018-01-24 09:22:43
    最新版JAVA 调用DLL 的JNA库。亲测可用 。请放心下载。。。
  • jna-4.5.1 , jna-4.5.1-sources , jna-platform-4.5.1 jar包 JNA全称Java Native Access,是一个建立在经典的JNI技术之上的Java开源框架(https://github.com/twall/jna)。JNA提供一组Java工具类用于在运行期动态...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,990
精华内容 1,596
关键字:

jna