2013-07-21 8 views

Odpowiedz

13

Robot wyśle ​​naciśnięcia klawiszy do dowolnego okna aplikacji na wierzchu. Aby wysłać naciśnięcia klawiszy do określonego celu, najpierw musisz ustawić cel jako pierwsze okno platformy. Może to wymagać natywnego kodu, takiego jak udostępniony przez JNI lub (co używam) JNA. Jeśli chcesz wysłać naciśnięcia klawiszy do okna tła, uważam, że nie możesz używać Robot, że będziesz musiał napisać natywny kod. Oczywiście wszystkie natywne rozwiązania kodu będą zależne od platformy.


Pytasz:

Czy mógłbyś mi dać trochę więcej szczegółów na temat jak to zrobić z JNA
przykro, piszę do okien

W systemie Windows interfejs z biblioteką user32.dll. Coś jak to pracował dla mnie:

User32.java

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR; 
import com.sun.jna.platform.win32.WinDef.HWND; 
import com.sun.jna.platform.win32.WinDef.RECT; 
import com.sun.jna.win32.StdCallLibrary; 

/** 
* JNA interface with Window's user32.dll 
* 
* @author Pete S 
* 
*/ 
public interface User32 extends StdCallLibrary { 
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class); 

    interface WNDENUMPROC extends StdCallCallback { 
     boolean callback(Pointer hWnd, Pointer arg); 
    } 

    public static final int GW_OWNER = 4; // used with GetWindow to get win owner 
    public static final int GW_HWNDNEXT = 2; // used with GetNextWindow 
    public static final int GA_ROOT = 2; // used with GetAncestor 
    public static final int GWL_EXSTYLE = -20; // used with GetWindowLong 
    public static final long WS_EX_APPWINDOW = 0x00040000L; 
    public static final Pointer HWND_TOP = new Pointer(0L); // used with 
                  // SetWindowPos 

    boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer userData); 

    int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount); 

    int SetForegroundWindow(Pointer hWnd); 

    Pointer GetForegroundWindow(); 

    boolean GetWindowRect(Pointer hWnd, RECT rect); 

    boolean SetWindowPos(Pointer hWnd, Pointer hWndInsertAfter, int x, int y, 
     int cx, int cy, int uFlags); 

    boolean MoveWindow(Pointer hWnd, int x, int y, int nWidth, int nHeight, boolean bRepaint); 

    boolean IsWindow(Pointer hWnd); 

    Pointer GetWindow(Pointer hWnd, int uCmd); 

    LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex); 

    Pointer GetParent(Pointer hWnd); 

    Pointer GetAncestor(Pointer hWnd, int gaFlags); 

    boolean IsWindowVisible(Pointer hWnd); 
} 

JnaUtil.java

import java.awt.AWTException; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.image.BufferedImage; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR; 
import com.sun.jna.platform.win32.WinDef.HWND; 
import com.sun.jna.platform.win32.WinDef.RECT; 

/** 
* static methods to allow Java to call Windows code. user32.dll code is as 
* specified in the JNA interface User32.java 
* 
* @author Pete S 
* 
*/ 
public class JnaUtil { 
    private static final User32 user32 = User32.INSTANCE; 
    private static Pointer callBackHwnd; 

    public static boolean windowExists(final String startOfWindowName) { 
     return !user32.EnumWindows(new User32.WNDENUMPROC() { 
     @Override 
     public boolean callback(Pointer hWnd, Pointer userData) { 
      byte[] windowText = new byte[512]; 
      user32.GetWindowTextA(hWnd, windowText, 512); 
      String wText = Native.toString(windowText).trim(); 

      if (!wText.isEmpty() && wText.startsWith(startOfWindowName)) { 
       return false; 
      } 
      return true; 
     } 
     }, null); 
    } 

    public static List<String> getAllWindowNames() { 
     final List<String> windowNames = new ArrayList<String>(); 
     user32.EnumWindows(new User32.WNDENUMPROC() { 

     @Override 
     public boolean callback(Pointer hWnd, Pointer arg) { 
      byte[] windowText = new byte[512]; 
      user32.GetWindowTextA(hWnd, windowText, 512); 
      String wText = Native.toString(windowText).trim(); 
      if (!wText.isEmpty()) { 
       windowNames.add(wText); 
      } 
      return true; 
     } 
     }, null); 

     return windowNames; 
    } 

    public static boolean windowExists(Pointer hWnd) { 
     return user32.IsWindow(hWnd); 
    } 

    public static Pointer getWinHwnd(final String startOfWindowName) { 
     callBackHwnd = null; 

     user32.EnumWindows(new User32.WNDENUMPROC() { 
     @Override 
     public boolean callback(Pointer hWnd, Pointer userData) { 
      byte[] windowText = new byte[512]; 
      user32.GetWindowTextA(hWnd, windowText, 512); 
      String wText = Native.toString(windowText).trim(); 

      if (!wText.isEmpty() && wText.startsWith(startOfWindowName)) { 
       callBackHwnd = hWnd; 
       return false; 
      } 
      return true; 
     } 
     }, null); 
     return callBackHwnd; 
    } 

    public static boolean setForegroundWindow(Pointer hWnd) { 
     return user32.SetForegroundWindow(hWnd) != 0; 
    } 

    public static Pointer getForegroundWindow() { 
     return user32.GetForegroundWindow(); 
    } 

    public static String getForegroundWindowText() { 
     Pointer hWnd = getForegroundWindow(); 
     int nMaxCount = 512; 
     byte[] lpString = new byte[nMaxCount]; 
     int getWindowTextResult = user32 
      .GetWindowTextA(hWnd, lpString, nMaxCount); 
     if (getWindowTextResult == 0) { 
     return ""; 
     } 

     return Native.toString(lpString); 
    } 

    public static boolean isForegroundWindow(Pointer hWnd) { 
     return user32.GetForegroundWindow().equals(hWnd); 
    } 

    public static boolean setForegroundWindow(String startOfWindowName) { 
     Pointer hWnd = getWinHwnd(startOfWindowName); 
     return user32.SetForegroundWindow(hWnd) != 0; 
    } 

    public static Rectangle getWindowRect(Pointer hWnd) throws JnaUtilException { 
     if (hWnd == null) { 
     throw new JnaUtilException(
       "Failed to getWindowRect since Pointer hWnd is null"); 
     } 
     Rectangle result = null; 
     RECT rect = new RECT(); 
     boolean rectOK = user32.GetWindowRect(hWnd, rect); 
     if (rectOK) { 
     int x = rect.left; 
     int y = rect.top; 
     int width = rect.right - rect.left; 
     int height = rect.bottom - rect.top; 
     result = new Rectangle(x, y, width, height); 
     } 

     return result; 
    } 

    /** 
    * set window at x and y position with w and h width. Set on top of z-order 
    * 
    * @param hWnd 
    * @param x 
    * @param y 
    * @param w 
    * @param h 
    * @return boolean -- did it work? 
    */ 
    public static boolean setWindowPos(Pointer hWnd, int x, int y, int w, int h) { 
     int uFlags = 0; 
     return user32.SetWindowPos(hWnd, User32.HWND_TOP, x, y, w, h, uFlags); 
    } 

    public static boolean moveWindow(Pointer hWnd, int x, int y, int nWidth, 
     int nHeight) { 
     boolean bRepaint = true; 
     return user32.MoveWindow(hWnd, x, y, nWidth, nHeight, bRepaint); 
    } 

    public static Rectangle getWindowRect(String startOfWindowName) 
     throws JnaUtilException { 
     Pointer hWnd = getWinHwnd(startOfWindowName); 
     if (hWnd != null) { 
     return getWindowRect(hWnd); 
     } else { 
     throw new JnaUtilException("Failed to getWindowRect for \"" 
       + startOfWindowName + "\""); 
     } 
    } 

    public static Pointer getWindow(Pointer hWnd, int uCmd) { 
     return user32.GetWindow(hWnd, uCmd); 
    } 

    public static String getWindowText(Pointer hWnd) { 
     int nMaxCount = 512; 
     byte[] lpString = new byte[nMaxCount]; 
     int result = user32.GetWindowTextA(hWnd, lpString, nMaxCount); 
     if (result == 0) { 
     return ""; 
     } 
     return Native.toString(lpString); 
    } 

    public static Pointer getOwnerWindow(Pointer hWnd) { 
     return user32.GetWindow(hWnd, User32.GW_OWNER); 
    } 

    public static String getOwnerWindow(String childTitle) { 
     Pointer hWnd = getWinHwnd(childTitle); 
     Pointer parentHWnd = getOwnerWindow(hWnd); 
     if (parentHWnd == null) { 
     return ""; 
     } 
     return getWindowText(parentHWnd); 

    } 

    public static Pointer getNextWindow(Pointer hWnd) { 
     if (hWnd == null) { 
     return null; 
     } 

     return user32.GetWindow(hWnd, User32.GW_HWNDNEXT); 
    } 

    public static boolean isWindowVisible(Pointer hWnd) { 
     return user32.IsWindowVisible(hWnd); 
    } 

    public static Pointer getParent(Pointer hWnd) { 
     return user32.GetParent(hWnd); 
    } 

    public static Pointer getRoot(Pointer hWnd) { 
     return user32.GetAncestor(hWnd, User32.GA_ROOT); 
    } 

    public static LONG_PTR getWindowLongPtr(Pointer hWndP, int nIndex) { 
     HWND hwnd = new HWND(hWndP); 
     return user32.GetWindowLongPtr(hwnd, nIndex); 
    } 

    // main method to test the library 
    public static void main(String[] args) throws InterruptedException { 
     List<String> winNameList = getAllWindowNames(); 
     for (String winName : winNameList) { 
     System.out.println(winName); 
     } 

     String[] testStrs = { "Untitled-Notepad", "Untitled - Notepad", 
      "Untitled - Notepad", "Java-Epic", "Java - Epic", "Fubars rule!", 
      "The First Night", "New Tab", "Citrix X", "EHR PROD - SVC" }; 
     for (String testStr : testStrs) { 
     Pointer hWnd = getWinHwnd(testStr); 
     boolean isWindow = windowExists(hWnd); 
     System.out.printf("%-22s %5b %16s %b%n", testStr, 
       windowExists(testStr), hWnd, isWindow); 
     } 

     String notePad = "Untitled - Notepad"; 
     Pointer hWnd = getWinHwnd(notePad); 
     System.out 
      .println("is it foreground window? " + isForegroundWindow(hWnd)); 
     boolean foo = setForegroundWindow(notePad); 
     System.out.println("foregroundwindow: " + foo); 
     Thread.sleep(400); 
     System.out 
      .println("is it foreground window? " + isForegroundWindow(hWnd)); 
     Thread.sleep(1000); 
     System.out.println("here A"); 
     try { 
     Rectangle rect = getWindowRect(notePad); 
     System.out.println("rect: " + rect); 
     Robot robot = new Robot(); 
     System.out.println("here B"); 

     BufferedImage img = robot.createScreenCapture(rect); 
     System.out.println("here C, img is " + img); 
     Thread.sleep(500); 
     ImageIcon icon = new ImageIcon(img); 
     System.out.println("here D. icon is null? " + icon); 
     Thread.sleep(500); 
     final JLabel label = new JLabel(icon); 
     System.out.println("here E. label is null? " + label); 
     Thread.sleep(500); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       System.out.println("here F");    
       JOptionPane.showMessageDialog(null, label); 
       System.out.println("here G"); 
      } 
     }); 

     } catch (AWTException e) { 
     e.printStackTrace(); 
     } catch (JnaUtilException e) { 
     e.printStackTrace(); 
     } 
    } 

} 

JnaUtilException.java

public class JnaUtilException extends Exception { 
    private static final long serialVersionUID = 1L; 

    public JnaUtilException(String text) { 
     super(text); 
    } 

} 
+0

Czy mógłbyś mi dać trochę więcej szczegółów na temat jak to zrobić z JNA – Basil

+0

@BasilMostafa: ponownie, jeśli używasz JNA lub JNI, twoje rozwiązanie będzie platowane forma zależna. Na jakiej platformie to piszesz? Windows? –

+0

Przepraszam, piszę dla windows – Basil

Powiązane problemy