简体   繁体   English

Java JNA关注特定的窗口

[英]Java JNA focus a specific Window

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 Win32WindowUtils {

  public interface User32 extends StdCallLibrary {
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
        HWND GetParent(HWND hWnd);
        HWND FindWindow(String lpClassName, String lpWindowName);
        HWND SetFocus(HWND hWnd);
        HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter, String lpszClass, String lpszWindow);
        int GetWindowText(HWND hWnd, char[] lpString, int nMaxCount);
    }

    private static final int WIN_TITLE_MAX_SIZE = 512;

    public static HWND GetWindowHandle(String strSearch, String strClass) {
        char[] lpString = new char[WIN_TITLE_MAX_SIZE];
        String strTitle;
        int iFind = -1;
        HWND hWnd = User32.INSTANCE.FindWindow(strClass, null);
        while(hWnd != null) {
            User32.INSTANCE.GetWindowText(hWnd, lpString, WIN_TITLE_MAX_SIZE);
            strTitle = new String(lpString);
            strTitle = strTitle.toUpperCase();
            iFind = strTitle.indexOf(strSearch);
            if(iFind != -1) {
                return hWnd;
            }
            hWnd = (User32.INSTANCE).FindWindowEx(null, hWnd, strClass, null);
        }
        return hWnd;
    }
}

And I am calling it by using: 我通过使用以下方式调用它:

User32.INSTANCE.SetFocus(Win32WindowUtils.GetWindowHandle(windowTitle, null));

Note: 注意:

public String windowTitle = "Unbennant - Editor";

Sadly nothing is happening and I dont know why 可悲的是什么都没有发生,我也不知道为什么

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. 下面的代码片段遍历机器上所有打开的窗口,当发现具有特定标题的Notepad ++窗口时停止,然后将其聚焦,在使其聚焦时,按Enter键三下。

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. 希望这对您有所帮助,我相信发送击键的部分也可以由User32库完成。

它可能应该读

public String windowTitle = "Unbenannt - Editor";

Answer by Avinash Jha is good. Avinash Jha的回答很好。 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 (eg button OK, Run) 只需在user32.SetForegroundWindow(hWnd);之后添加以下两行,就无需添加机器人键VK_ENTER来激活窗口,因为单击Enter将导致单击窗口的默认键(例如,确定,运行按钮)。

...
user32.SetForegroundWindow(hWnd);

user32.SetFocus( winOne.winHandle);
Thread.sleep(500);
user32.ShowWindow(winOne.winHandle, WinUser.SW_SHOWNOACTIVATE);

return false;
...

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. 我知道我晚了3年,但是由于Windows API的局限性,当试图在与您的来源不同的其他程序上进行修改时,当前的答案至少不适用于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: 使用Avinash Jha代码库的方法是:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM