2012-01-03 13 views
12

Sono novizio per JNA. Sto cercando di ottenere maniglie per tutte le finestre, comprese quelle ridotte a icona. Ho bisogno di HWND di tutte le finestre. Sono andato attraverso la domanda Windows: how to get a list of all visible windows? che mi ha aiutato a ottenere l'elenco di Windows, ma ha il tipo hWnd come int. Non posso usarlo con le funzioni com.sun.jna.platform.win32.User32 che richiedono hWnd di tipo com.sun.jna.platform.win32.WinDef.HWND. Quindi, Esiste un modo per ottenere tutti gli handle di finestra di tipo com.sun.jna.platform.win32.WinDef.HWND anziché il puntatore int? Infine, perché la differenza è int e HWND? Come accetta entrambi? Sono un po 'confuso. Grazie.Come ottenere l'elenco di tutti gli handle di finestra in Java (utilizzando JNA)?

Ho il codice seguente (a cura dalla risposta di 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); 
    } 
} 

ho cercato di utilizzare solo (non un'interfaccia personalizzata) la classe predefinita User32. Funziona bene. Ho dei dubbi, perché stiamo usando un'interfaccia userdefined invece di una già esistente? Un'altra cosa, c'è sempre differenza tra la firma del metodo definito dall'utente e quelle già esistenti. Ad esempio, la variabile windowText è char[], mentre la variabile di Hovercraft è di tipo byte[]. Qualcuno può spiegarmi? Grazie.

+0

Aggiunto codice di esempio utilizzando WinDef.HWND alla mia risposta. –

risposta

12

L'ultima versione di JNA ha avuto alcune modifiche che dovrebbero risolvere questo problema (come uno degli autori di JNA, Luke Quinane, afferma here). Se si utilizza la versione più recente e si verifica JNA API, il metodo utilizzato dall'interfaccia WinUser.WNDENUMPROC utilizza effettivamente WinDef.HWND come parametro, non long o int.

Ad esempio:

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

Grazie mille! Ho aggiunto il mio codice (modificato dal tuo) nella mia domanda. Potresti per favore aiutarmi a capire di più? Grazie ancora. – Ahamed

+0

'HWND' è azzerato. Perché l'utente32 predefinito ha 'char []' come parametro ma quello che hai definito sta avendo 'byte []'? – Ahamed

+4

Se si accede alla versione unicode di un metodo (SomeFunctionW), è necessario utilizzare char [] per i parametri LPTCHAR; se si utilizza la versione ascii (SomeFunctionA), è necessario utilizzare byte []. Le intestazioni MS mappano automaticamente "SomeFunction" su "SomeFunctionW" o "SomeFunctionA" a seconda che sia definito UNICODE; JNA realizza la stessa cosa a seconda delle opzioni passate a Native.loadLibrary. È anche possibile utilizzare esplicitamente un suffisso "A" o "W" come nell'esempio precedente. – technomage

Problemi correlati