2012-01-03 10 views
12

Jestem nowicjuszem dla JNA. Próbuję uzyskać uchwyty dla wszystkich okien, w tym zminimalizowane. Potrzebuję HWND wszystkich okien. Przeszedłem przez pytanie Windows: how to get a list of all visible windows?, które pomogło mi uzyskać listę okien, ale ma typ hWnd jako int. Nie można go używać z funkcjami com.sun.jna.platform.win32.User32, które wymagają hWnd typu com.sun.jna.platform.win32.WinDef.HWND. Czy istnieje sposób na uzyskanie wszystkich uchwytów okien typu com.sun.jna.platform.win32.WinDef.HWND zamiast wskaźnika int? Wreszcie, dlaczego jest różnica int i HWND? Jak akceptuje oba? Jestem trochę zdezorientowany. Dzięki.Jak uzyskać listę wszystkich uchwytów okien w Javie (przy użyciu JNA)?

Mam następujący kod (red od odpowiedzi Hovercreft'S):

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

Próbowałem używać tylko (nie niestandardowy interfejs) domyślnej User32 klasę. Działa dobrze. Mam wątpliwości, dlaczego używamy interfejsu zdefiniowanego przez użytkownika, zamiast już istniejącego? Jeszcze jedno, zawsze istnieje różnica między podpisem metody zdefiniowanej przez użytkownika a już istniejącą. Na przykład zmienna windowText jest char[], natomiast zmienna Hovercraft jest typu byte[]. Czy ktoś może mi wyjaśnić? Dzięki.

+0

Dodany przykładowy kod korzystania WinDef.HWND na moją odpowiedź. –

Odpowiedz

12

Najnowsza wersja JNA miała pewne zmiany, które powinny to naprawić (jako jeden z autorów JNA, Luke Quinane, podaje here). Jeśli używasz najnowszej wersji i sprawdzasz JNA API, zobaczysz, że metoda interfejsu WinUser.WNDENUMPROC faktycznie używa WinDef.HWND jako jego parametru, nie długiego lub int.

Na przykład:

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

Wielkie dzięki! Dodałem mój kod (zredagowany z twojego) w moim pytaniu. Czy możesz pomóc mi zrozumieć więcej? Dzięki jeszcze raz. – Ahamed

+0

'HWND' jest wyczyszczone. Dlaczego domyślnie User32 ma "char []" jako parametr, ale ten, który zdefiniowałeś, ma 'byte []'? – Ahamed

+4

Uzyskując dostęp do wersji kodu Unicode metody (SomeFunctionW), należy użyć char [] dla parametrów LPTCHAR; jeśli używasz wersji ASCII (SomeFunctionA), musisz użyć byte []. Nagłówki MS automatycznie zamieniają "SomeFunction" na "SomeFunctionW" lub "SomeFunctionA" w zależności od tego, czy zdefiniowano UNICODE; JNA realizuje to samo w zależności od opcji przekazanych do Native.loadLibrary. Możesz również jawnie użyć sufiksu "A" lub "W", jak w powyższym przykładzie. – technomage

Powiązane problemy