2012-01-03 124 views
12

我是JNA的新手。我正在嘗試爲包括最小化窗口的所有窗口獲取句柄。我需要所有窗口中的HWND。我已經去了問題Windows: how to get a list of all visible windows?,這幫助我獲得窗口列表,但它有hWnd類型爲int。我不能用com.sun.jna.platform.win32.User32功能,要求hWndcom.sun.jna.platform.win32.WinDef.HWND類型。那麼,有沒有什麼辦法可以獲得類型com.sun.jna.platform.win32.WinDef.HWND而不是int指針的所有窗口句柄?最後,爲什麼區別intHWND?它如何接受?我有點困惑。謝謝。如何獲取Java中所有窗口句柄的列表(使用JNA)?

我有以下代碼(從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); 
    } 
} 

我試圖用只(不定製接口)的默認User32類。它工作正常。我懷疑,爲什麼我們使用用戶定義的接口而不是現有的接口?還有一件事,用戶定義的方法簽名和現有​​的方法簽名之間總是有區別的。例如,變量windowTextchar[],而Hovercraft的變量的類型是byte[]。任何人都可以解釋我?謝謝。

+0

添加示例代碼。 – 2012-01-03 21:16:03

回答

12

JNA的最新版本有一些改變,應該解決這個問題(作爲JNA的作者之一,Luke Quinane,州here)。如果您使用最新版本並檢查JNA API,則會看到WinUser.WNDENUMPROC接口的方法實際上使用WinDef.HWND作爲其參數,而不是long或int。

例如:使用WinDef.HWND到我的回答

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

非常感謝!我在我的問題中添加了我的代碼(由您編輯)。你能幫我理解更多嗎?再次感謝。 – Ahamed 2012-01-04 05:47:58

+0

'HWND'被清除。爲什麼默認的User32具有'char []'作爲參數,但是你定義的是'byte []'? – Ahamed 2012-01-04 06:10:17

+4

如果訪問方法的Unicode版本(SomeFunctionW),則必須使用char []作爲LPTCHAR參數;如果使用ascii版本(SomeFunctionA),則必須使用byte []。根據是否定義了UNICODE,MS頭自動將「SomeFunction」映射到「SomeFunctionW」或「SomeFunctionA」; JNA根據傳遞給Native.loadLibrary的選項完成相同的事情。您也可以像上例中那樣明確使用「A」或「W」後綴。 – technomage 2012-01-05 14:35:28