2011-12-06 35 views
10

Tôi đang cố gắng tìm hiểu cách tương tác với Windows API bằng cách sử dụng Java và JNA (Java Native Access), nhưng đang ở một khối đường. Tôi đang cố gắng làm cho con chuột làm điều gì đó bằng cách xếp hàng sự kiện chuột trên luồng đầu vào của chuột và mã hoạt động, trong đó phương thức SendInput(...) trả về 1 cho thấy rằng nó đã xếp hàng thành công sự kiện, nhưng bản thân con chuột không làm gì cả.Làm thế nào để di chuyển (hoặc làm bất cứ điều gì với) chuột

My SSCCE:

Edit: chỉnh sửa để điền vào các lĩnh vực dwFlags. Tôi đã thử một số kết hợp của các hằng số một mình hoặc bit hoặc kết hợp mà không thành công. Một lần nữa, phương pháp SendInput trả về 1 như nó phải gợi ý một phương pháp hoạt động, nhưng chuột không nhúc nhích:

import com.sun.jna.Native; 
import com.sun.jna.platform.win32.WinDef.*; 
import com.sun.jna.platform.win32.WinUser.*; 
import com.sun.jna.win32.StdCallLibrary; 

public class MouseUtils { 
    public interface User32 extends StdCallLibrary { 
     public static final long MOUSEEVENTF_MOVE = 0x0001L; 
     public static final long MOUSEEVENTF_VIRTUALDESK = 0x4000L; 
     public static final long MOUSEEVENTF_ABSOLUTE = 0x8000L; 

     User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class); 
     DWORD SendInput(DWORD dWord, INPUT[] input, int cbSize); 
    } 

    public static void main(String[] args) { 
     INPUT input = new INPUT(); 
     input.type = new DWORD(INPUT.INPUT_MOUSE); 

     input.input.mi.dx = new LONG(500); 
     input.input.mi.dy = new LONG(500); 
     input.input.mi.mouseData = new DWORD(0); 
     input.input.mi.dwFlags = new DWORD(User32.MOUSEEVENTF_MOVE 
      | User32.MOUSEEVENTF_VIRTUALDESK | User32.MOUSEEVENTF_ABSOLUTE); 
     // input.input.mi.dwFlags = new DWORD(0x8000L); 
     input.input.mi.time = new DWORD(0); 

     INPUT[] inArray = {input}; 

     int cbSize = input.size(); // mouse input struct size 
     DWORD nInputs = new DWORD(1); // number of inputs 
     DWORD result = User32.INSTANCE.SendInput(nInputs , inArray, cbSize); 
     System.out.println("result: " + result); // return 1 if the 1 event successfully inserted 
    } 
} 

Chỉnh sửa 2:

Làm đọc nhiều hơn, và có vẻ như sự hiểu biết của tôi về mảng với JNA là thiếu, mà tôi phải suy nghĩ về mảng C, nơi một mảng chỉ đơn giản là một con trỏ đến một khu vực của bộ nhớ tiếp giáp. Sắp tới (tôi hy vọng!).

+0

Offtopic: Nó luôn luôn là một niềm vui khi nhìn thấy bạn là tốt đẹp, thoải mái và thân thiện với folks. Bạn là một trong những người tôi thực sự tra cứu quanh đây. Chúc mừng ngày lễ; và một năm tuyệt vời 2017! – GhostCat

+1

@GhostCat: Câu đầu tiên của bạn hơi buồn cười, nhưng câu thứ hai của bạn quá tốt. Và tôi tìm đến bạn, khả năng và mong muốn của bạn để truyền bá kiến ​​thức của bạn cho người khác. –

Trả lời

9

JNA tài liệu Using Structures And Unions đọc:

đoàn thường hoán đổi cho nhau với Kiến trúc, nhưng yêu cầu bạn chỉ ra những lĩnh vực công đoàn đang hoạt động với phương pháp setType trước khi nó có thể được thông qua đúng cách để một lời gọi hàm.

Tôi đoán bạn đã bỏ lỡ setType một phần. Ngoài ra, khi sử dụng MOUSEEVENTF_ABSOLUTE, dxdy được chỉ định làm tọa độ của chuột chứ không phải pixel.

công trình sau:

public interface User32 extends StdCallLibrary { 
    ... 
    public static final int SM_CXSCREEN = 0x0; 
    public static final int SM_CYSCREEN = 0x1; 
    int GetSystemMetrics(int index); 
} 

public static void main(String[] args) {  
    ... 
    input.input.setType("mi"); 
    input.input.mi.dx = new LONG(500 * 65536/User32.INSTANCE.GetSystemMetrics(User32.SM_CXSCREEN)); 
    input.input.mi.dy = new LONG(500 * 65536/User32.INSTANCE.GetSystemMetrics(User32.SM_CYSCREEN)); 
    ... 
} 
+3

Holy chit! 'setType (...)' là nó! Tôi đã giả định sai rằng việc thiết lập trường kiểu biến đầu vào sẽ là đủ, nhưng đã sai. Với các chỉnh sửa của bạn, mã của tôi hoạt động. Tôi không thể cảm ơn đủ! –

2
input.input.mi.dwFlags = new DWORD(0); 

Bạn không chỉ định bất kỳ cờ nhập chuột nào, do đó không có đầu vào chuột.

+0

Cảm ơn! hãy để tôi nhìn vào đó! –

+0

vui lòng xem chỉnh sửa câu hỏi của tôi và mã được cập nhật. Tất cả sự giúp đỡ được đánh giá cao! –

+0

Cảm ơn bạn một lần nữa vì những gợi ý tuyệt vời của bạn; chúng hữu ích nhất! –

3

Gọi phương thức toArray() trên cấu trúc của bạn để lấy khối bộ nhớ liền kề.

INPUT input = new INPUT(); 
INPUT[] arg = (INPUT[])input.toArray(1); 

Ngoài ra, bạn chỉ có thể tuyên bố một bản đồ phương pháp thay thế cho SendInput: (? Quyền, có lẽ thấy MS ghi chú trên UIPI)

DWORD SendInput(int nInputs, INPUT pInputs, int cbSize); 

Tuy nhiên, có thể có một cái gì đó khác đang xảy ra, vì bạn ví dụ nên làm việc (ít nhất là với một phần tử mảng đơn).

EDIT: câu trả lời Union.setType() thực sự là đúng.

+0

Cảm ơn các đề xuất có giá trị của bạn !! Tôi rất cảm kích điều đó. Tôi đã bình chọn bài đăng của bạn và chỉ muốn tôi có thể chia tiền thưởng cho tất cả những ai đã giúp. –

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