首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用javax.accessibility与来自另一个JVM的应用程序交互

使用javax.accessibility与来自另一个JVM的应用程序交互
EN

Stack Overflow用户
提问于 2021-06-30 12:18:01
回答 1查看 124关注 0票数 1

我正在尝试使用java辅助功能实用程序与一个java swing应用程序交互。java可访问性指南指出

要使辅助技术与Java应用程序一起工作,将其加载到与其提供访问的Java应用程序相同的JVM中。这是通过使用assistive_technologies属性完成的。

Monkey类位于此版本的Java辅助工具附带的示例/Monkey目录中。在运行它之前,需要按照以下说明适当地设置您的环境: 将jaccess.jar和jaccess-examples.jar复制到JDKHOME/jre/lib/ext目录下的JDK1.2或更高版本的安装中。修改$JDKHOME/jre/lib/create sibility.properties文件(如果不存在的话创建一个),以包含以下行: assistive_technologies=Monkey 按照上面的说明,任何时候启动Java应用程序时都会自动启动Monkey。例如,您可以运行作为Swing演示应用程序的一部分的SwingSet演示。

我已经将jaccess-examples.jar复制到我的jre文件夹(C:\ProgramFiles\Java\jre1.8.0_221\lib\ext)中,jaccess.jar已经在那里,添加到了(C:\ProgramFiles\Java\jre1.8.0_221\lib)行assistive_technologies=Monkey中的accessibility.properties文件中,但是在启动launching应用程序时什么也不会发生。我怎么才能让它起作用?

要注意的是,如果Monkey在与它需要访问的应用程序相同的JVM中启动,即使不修改accessibility.properties文件,它实际上也能工作。

EN

回答 1

Stack Overflow用户

发布于 2021-11-14 18:52:16

代码语言:javascript
复制
//load WindowsAccessBridge-64.dll

    import com.sun.jna.Library;
    import com.sun.jna.Native;
    import com.sun.jna.Pointer;
    import com.sun.jna.platform.win32.WinDef;
    import com.sun.jna.ptr.PointerByReference;

    public interface WindowsAccessBridge extends Library {

        //Load the .dll using JNA
        WindowsAccessBridge INSTANCE = Native.load("windowsaccessbridge-64", WindowsAccessBridge.class);


        //declare some functions from the .dll

        void Windows_run();

        boolean isJavaWindow(WinDef.HWND window);

        boolean getAccessibleContextFromHWND(WinDef.HWND target, WinDef.LONGByReference vmID, PointerByReference accessibleContext);

        boolean getAccessibleContextInfo(WinDef.LONG vmID, Pointer accessibleContext, ABPackages.AccessibleContextInfo.ByReference info);

    }



 //load custom user32.dll, the user32 provided by JNA does not have the ChangeWindowMessageFilter function

    import com.sun.jna.Native;
    import com.sun.jna.Pointer;
    import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
    import com.sun.jna.ptr.PointerByReference;
    import com.sun.jna.win32.StdCallLibrary;
    import com.sun.jna.platform.win32.WinDef.HWND;

    public interface UUser32 extends StdCallLibrary {

        UUser32 INSTANCE = Native.load("user32", UUser32.class);

        boolean ChangeWindowMessageFilter(int message, int flag);

    }

    //to get window messages you need a message pump
    import com.sun.jna.platform.win32.User32;
    import com.sun.jna.platform.win32.WinUser;
    import static com.sun.jna.platform.win32.WinUser.WM_COPYDATA;
    import static com.sun.jna.platform.win32.WinUser.WM_USER;

    public class WindowMessagePump extends Thread {
        //get a WAB instance
        private final WindowsAccessBridge wab = WindowsAccessBridge.INSTANCE;
        //get a custom user32 instance
        private final UUser32 uUser32 = UUser32.INSTANCE;
        // the user32 provided by JNA
        private final User32 user32 = User32.INSTANCE;

        @Override
        public void run() {
            uUser32.ChangeWindowMessageFilter(WM_COPYDATA, 1);
            for (int i = WM_USER + 1; i < 0xfff; i++) {
                uUser32.ChangeWindowMessageFilter(i, 1);
            }
            wab.Windows_run();
            WinUser.MSG msg = new WinUser.MSG();
            while (user32.GetMessage(msg, null, 0, 0) > 0) {
                user32.TranslateMessage(msg);
                user32.DispatchMessage(msg);
            }
        }
    }

    //you also need some structures to get the needed information 

    import com.sun.jna.Structure;

    public class ABPackages {

        static final int MAX_STRING_SIZE = 1024;
        static final int SHORT_STRING_SIZE = 256;

        @Structure.FieldOrder({"name", "description", "role", "role_en_US", "states", "states_en_US", "indexInParent",
                "childrenCount", "x", "y", "width", "height", "accessibleComponent", "accessibleAction",
                "accessibleSelection", "accessibleText", "accessibleInterfaces"})
        public static class AccessibleContextInfo extends Structure {
            public char[] name = new char[MAX_STRING_SIZE];        // the AccessibleName of the object
            public char[] description = new char[MAX_STRING_SIZE]; // the AccessibleDescription of the object
            public char[] role = new char[SHORT_STRING_SIZE];      // localized AccesibleRole string
            public char[] role_en_US = new char[SHORT_STRING_SIZE];
            public char[] states = new char[SHORT_STRING_SIZE];    // localized AccesibleStateSet string (comma separated)
            public char[] states_en_US = new char[SHORT_STRING_SIZE];
            public int indexInParent;                   // index of object in parent
            public int childrenCount;                  // # of children, if any
            public int x;                              // screen x-axis co-ordinate in pixels
            public int y;                              // screen y-axis co-ordinate in pixels
            public int width;                          // pixel width of object
            public int height;                         // pixel height of object
            public int accessibleComponent;            // flags for various additional
            public int accessibleAction;               // Java Accessibility interfaces
            public int accessibleSelection;            // FALSE if this object doesn't
            public int accessibleText;                 // implement the additional interface
            public int accessibleInterfaces;           // new bitfield containing additional interface flags

            public static class ByReference extends AccessibleContextInfo implements Structure.ByReference {
            }

            public static class ByValue extends AccessibleContextInfo implements Structure.ByValue {
            }
        }
    }


    //and now for the implementation
    import com.sun.jna.Native;
    import com.sun.jna.Pointer;
    import com.sun.jna.platform.DesktopWindow;
    import com.sun.jna.platform.WindowUtils;
    import com.sun.jna.platform.win32.WinDef;
    import com.sun.jna.ptr.PointerByReference;

    public static void main(String[] args) throws InterruptedException {
        //start the message pump
        WindowMessagePump messagePump = new WindowMessagePump();
        messagePump.setDaemon(true);
        messagePump.start();
        //wait a few seconds for the pump to start just in case
        Thread.sleep(2000);

        //get an instance of windows access bridge
        WindowsAccessBridge accessBridge = WindowsAccessBridge.INSTANCE;

        //get a list of active windows
        List<DesktopWindow> list = WindowUtils.getAllWindows(true);

        for (DesktopWindow window : list) {
            if (window.getFilePath().contains("the name of the window you are looking for")) {
                WinDef.HWND handle = window.getHWND();
                //check if its a java window
                if (accessBridge.isJavaWindow(handle)) {

                    WinDef.LONGByReference vmID = new WinDef.LONGByReference();
                    PointerByReference accessibleContext = new PointerByReference();

                    boolean getAccessibleContextSuccess = accessBridge.getAccessibleContextFromHWND(handle, vmID, accessibleContext);

                    if(getAccessibleContextSuccess) {
                        ABPackages.AccessibleContextInfo.ByReference contextInfo = new ABPackages.AccessibleContextInfo.ByReference();
                        boolean getContextInfoSuccess = accessBridge.getAccessibleContextInfo(vmID.getValue(), accessibleContext.getValue(), contextInfo);
                        System.out.println("getContextInfoSuccess: " + getContextInfoSuccess);
                    }
                    break;
                }
            }
        }
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68194608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档