2012-01-03 14 views
12

Soy un principiante para JNA. Estoy tratando de obtener identificadores para todas las ventanas, incluidas las minimizadas. Necesito HWND de todas las ventanas. He ido a través de la pregunta Windows: how to get a list of all visible windows? que me ayudó a obtener la lista de ventanas, pero tiene el tipo hWnd como int. No puedo usarlo con las funciones com.sun.jna.platform.win32.User32 que piden hWnd del tipo com.sun.jna.platform.win32.WinDef.HWND. Entonces, ¿hay alguna forma de obtener todos los identificadores de ventana del tipo com.sun.jna.platform.win32.WinDef.HWND en lugar del puntero int? Finalmente, ¿por qué la diferencia es int y HWND? ¿Cómo acepta ambos? Estoy un poco confundido. Gracias.¿Cómo obtener la lista de todos los identificadores de ventanas en Java (usando JNA)?

Tengo el siguiente código (editado a partir de la respuesta de Hovercreft):

import com.sun.jna.Native; 
    import com.sun.jna.Pointer; 
    import com.sun.jna.platform.win32.User32; 
    import com.sun.jna.platform.win32.WinDef.HWND; 
    import com.sun.jna.platform.win32.WinDef.RECT; 
    import com.sun.jna.platform.win32.WinUser.WNDENUMPROC; 

    public class TryWithHWND { 

    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) { 
       char[] windowText = new char[512]; 
       user32.GetWindowText(hWnd, windowText, 512); 
       String wText = Native.toString(windowText); 
       RECT rectangle = new RECT(); 
       user32.GetWindowRect(hWnd, rectangle); 
       // get rid of this if block if you want all windows regardless 
       // of whether 
       // or not they have text 
       // second condition is for visible and non minimised windows 
       if (wText.isEmpty() || !(User32.INSTANCE.IsWindowVisible(hWnd) 
         && rectangle.left > -32000)) { 
        return true; 
       } 
       System.out.println("Found window with text " + hWnd 
         + ", total " + ++count + " Text: " + wText); 
       return true; 
      } 
     }, null); 
    } 
} 

He intentado utilizar solamente (no interfaz personalizada) la clase por defecto User32. Está funcionando bien. Tengo dudas, ¿por qué estamos usando una interfaz definida por el usuario en lugar de una ya existente? Una cosa más, siempre hay diferencia entre la firma del método definido por el usuario y las ya existentes. Por ejemplo, la variable windowText es char[], mientras que la variable de Hovercraft es del tipo byte[]. ¿Alguien puede explicarme? Gracias.

+0

Agregado código de ejemplo usando WinDef.HWND a mi respuesta. –

Respuesta

12

La última versión de JNA ha tenido algunos cambios que deberían solucionarlo (como uno de los autores de JNA, Luke Quinane, indica here). Si utiliza la última versión y comprueba el JNA API, verá que el método de la interfaz WinUser.WNDENUMPROC realmente usa WinDef.HWND como su parámetro, no largo o int.

Por ejemplo:

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
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); 
     int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount); 
    } 

    public static void main(String[] args) { 
     final User32 user32 = User32.INSTANCE; 
     user32.EnumWindows(new WNDENUMPROC() { 
     int count = 0; 
     @Override 
     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); 
      return true; 
     } 
     }, null); 
    } 
} 
+0

¡Muchas gracias! He agregado mi código (editado del tuyo) en mi pregunta. ¿Podrías por favor ayudarme a entender más? Gracias de nuevo. – Ahamed

+0

'HWND' está despejado. ¿Por qué el Usuario32 predeterminado tiene 'char []' como param pero el que usted ha definido tiene 'byte []'? – Ahamed

+4

Si accede a la versión unicode de un método (SomeFunctionW), debe usar char [] para los parámetros LPTCHAR; si usa la versión de ASCII (SomeFunctionA), debe usar byte []. Los encabezados de MS asignan automáticamente "SomeFunction" a "SomeFunctionW" o "SomeFunctionA" dependiendo de si UNICODE está definido; JNA logra lo mismo dependiendo de las opciones pasadas a Native.loadLibrary. También puede usar explícitamente un sufijo "A" o "W" como en el ejemplo anterior. – technomage

Cuestiones relacionadas