Java JNA focus a specific Window

后端 未结 4 706
Happy的楠姐
Happy的楠姐 2021-01-07 03:59

I am trying to give my application the power to focus another Window (Notepad in this case)

My Class is looking like this

 public static class Win32W         


        
相关标签:
4条回答
  • 2021-01-07 04:12

    The below code snippet iterates through all the windows open in the machine , stops when a Notepad++ window with a specific title is found and then brings it into focus.On bringing it to focus it presses the enter key three times.

    import java.awt.AWTException;
    import java.awt.Robot;
    import java.awt.event.KeyEvent;
    
    import com.sun.jna.Native;
    import com.sun.jna.Pointer;
    import com.sun.jna.platform.win32.WinDef;
    import com.sun.jna.platform.win32.WinDef.HWND;
    import com.sun.jna.platform.win32.WinUser;
    import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
    import com.sun.jna.win32.StdCallLibrary;
    
    public class TryWithHWND {
    public interface User32 extends StdCallLibrary {
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
    
        boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc, Pointer arg);
    
        WinDef.HWND SetFocus(WinDef.HWND hWnd);
    
        int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);
    
        boolean SetForegroundWindow(WinDef.HWND hWnd);
    }
    
    public static void main(String[] args) {
        final User32 user32 = User32.INSTANCE;
        user32.EnumWindows(new WNDENUMPROC() {
            int count = 0;
    
            public boolean callback(HWND hWnd, Pointer arg1) {
                byte[] windowText = new byte[512];
                user32.GetWindowTextA(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;
                }
    
                System.out.println("Found window with text " + hWnd
                        + ", total " + ++count + " Text: " + wText);
                if (wText
                        .equals("C:\\Users\\Avi.J\\Desktop\\Datasource and Mq setup commands.txt - Notepad++")) {
                    user32.SetForegroundWindow(hWnd);
                    return false;
                }
                return true;
            }
        }, null);
        // user32.SetFocus(hWnd);
        try {
            Robot r = new Robot();
            r.keyPress(KeyEvent.VK_ENTER);
            r.keyRelease(KeyEvent.VK_ENTER);
            r.keyPress(KeyEvent.VK_ENTER);
            r.keyRelease(KeyEvent.VK_ENTER);
            r.keyPress(KeyEvent.VK_ENTER);
            r.keyRelease(KeyEvent.VK_ENTER);
            r.keyPress(KeyEvent.VK_ENTER);
            r.keyRelease(KeyEvent.VK_ENTER);
        } catch (AWTException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    }
    

    Hope this helps , I believe the part of sending keystrokes can be done by User32 library as well.

    0 讨论(0)
  • 2021-01-07 04:12

    I know im like 3 years late, but because of the limitation of the windows api when trying to make modifications at other programs with a different origin than yours, the current answers doesn't work at least with JNA. I've done some hours of research trying lots of different functions without success. Finally I've found the way to do it really clean. Using Avinash Jha code base here is the way to do it:

    public class JnaInstances {
    
        public interface User32 extends StdCallLibrary {
            User32 INSTANCE = Native.loadLibrary("user32", User32.class);
    
            boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc,
                                Pointer data);
    
            int GetWindowTextW(WinDef.HWND hWnd, char[] lpString, int nMaxCount);
    
            boolean ShowWindow(WinDef.HWND hWnd, int nCmdShow);
    
        }
    
    }
    
    public static void main(String[] args) {
        JnaInstances.User32 user32 = JnaInstances.User32.INSTANCE;
    
        user32.EnumWindows(new WinUser.WNDENUMPROC() {
    
            @Override
            public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
                char[] windowText = new char[512];
                user32.GetWindowTextW(hwnd, windowText, 512);
    
                String windowName = Native.toString(windowText);
    
                System.out.println("The window is called: "+ windowName);
    
                if(windowName.contains("Window name")) { //Here you can use the .equals if you want more accurancy
    
                    user32.ShowWindow(hwnd, User32.SW_RESTORE);
                    return false;
                }
    
                return true;
            }
    
        }, null);
    }
    
    0 讨论(0)
  • 2021-01-07 04:31

    It should probably read

    public String windowTitle = "Unbenannt - Editor";
    
    0 讨论(0)
  • 2021-01-07 04:32

    Answer by Avinash Jha is good. Just add following two lines after user32.SetForegroundWindow(hWnd);, you will not need to add robot keys VK_ENTER to activate window, as clicking enter will cause clicking default key of window (e.g. button OK, Run)

    ...
    user32.SetForegroundWindow(hWnd);
    
    user32.SetFocus( winOne.winHandle);
    Thread.sleep(500);
    user32.ShowWindow(winOne.winHandle, WinUser.SW_SHOWNOACTIVATE);
    
    return false;
    ...
    
    0 讨论(0)
提交回复
热议问题