2012-01-03 52 views
12

Tôi mới làm quen với JNA. Tôi đang cố gắng để có được xử lý cho tất cả các cửa sổ bao gồm cả những người thu nhỏ. Tôi cần HWND của tất cả các cửa sổ. Tôi đã đi qua các câu hỏi Windows: how to get a list of all visible windows? mà đã giúp tôi để có được danh sách các cửa sổ, nhưng nó có hWnd loại như int. Tôi không thể sử dụng chức năng này với các chức năng com.sun.jna.platform.win32.User32 yêu cầu hWnd loại com.sun.jna.platform.win32.WinDef.HWND. Vì vậy, có cách nào để có được tất cả các cửa sổ xử lý của loại com.sun.jna.platform.win32.WinDef.HWND chứ không phải là con trỏ int? Cuối cùng, tại sao sự khác biệt là intHWND? Làm thế nào nó chấp nhận cả hai? Tôi hơi bối rối. Cảm ơn.Làm thế nào để có được danh sách tất cả các cửa sổ xử lý trong Java (Sử dụng JNA)?

Tôi có đoạn code sau (thay đổi nội dung từ câu trả lời của 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); 
    } 
} 

tôi cố gắng chỉ sử dụng (không phải giao diện tùy chỉnh) default class User32. Nó hoạt động tốt. Tôi có nghi ngờ, tại sao chúng tôi đang sử dụng giao diện người dùng xác định thay vì giao diện đã tồn tại? Một điều nữa, Luôn có sự khác biệt giữa chữ ký phương thức do người dùng xác định và chữ ký của phương thức đã tồn tại. Ví dụ: biến số windowTextchar[], trong khi biến của Hovercraft thuộc loại byte[]. Bất cứ ai có thể giải thích cho tôi? Cảm ơn.

+0

gia tăng mẫu mã sử dụng WinDef.HWND vào câu trả lời của tôi. –

Trả lời

12

Phiên bản mới nhất của JNA đã có một số thay đổi cần sửa lỗi này (là một trong những tác giả của JNA, Luke Quinane, nêu rõ here). Nếu bạn sử dụng phiên bản mới nhất và kiểm tra JNA API, bạn sẽ thấy rằng phương thức của giao diện WinUser.WNDENUMPROC thực sự sử dụng WinDef.HWND làm tham số của nó, không dài hoặc int.

Ví dụ:

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

Cảm ơn rất nhiều! Tôi đã thêm mã của tôi (được chỉnh sửa từ mã của bạn) trong câu hỏi của tôi. Bạn có thể giúp tôi hiểu thêm không? Cảm ơn một lần nữa. – Ahamed

+0

'HWND' bị xóa. Tại sao User32 mặc định có 'char []' làm param nhưng cái bạn đã định nghĩa là có 'byte []'? – Ahamed

+4

Nếu truy cập phiên bản unicode của một phương thức (SomeFunctionW), bạn phải sử dụng char [] cho các tham số LPTCHAR; nếu sử dụng phiên bản ascii (SomeFunctionA), bạn phải sử dụng byte []. Các tiêu đề MS tự động ánh xạ "SomeFunction" thành "SomeFunctionW" hoặc "SomeFunctionA" tùy thuộc vào việc UNICODE được xác định; JNA hoàn thành cùng một điều tùy thuộc vào các tùy chọn được chuyển đến Native.loadLibrary. Bạn cũng có thể sử dụng hậu tố "A" hoặc "W" một cách rõ ràng như trong ví dụ trên. – technomage

Các vấn đề liên quan