2010-06-20 31 views
13

Tôi đã đặt cùng một mã JNA để cài đặt móc nối bàn phím trong Windows (sử dụng các ví dụ JNA). Các mã biên dịch và tất cả mọi thứ, và tôi nhận được móc cài đặt (tôi có được xử lý để móc thành công), tôi cũng có thể gỡ bỏ cài đặt các móc thành công. Tuy nhiên, cuộc gọi lại không bao giờ được gọi khi tôi nhấn bất kỳ phím nào trên bàn phím. Đây là mã của tôi (hầu hết của nó là định nghĩa kiểu nhận được từ các ví dụ JNA, hãy vào phần "chính" trực tiếp cho một phần của tôi)Bàn phím móc JNA trong Windows

import com.sun.jna.IntegerType; 
import com.sun.jna.Pointer; 
import com.sun.jna.PointerType; 
import com.sun.jna.Structure; 
import com.sun.jna.FromNativeContext; 
import com.sun.jna.ptr.IntByReference; 
import com.sun.jna.ptr.PointerByReference; 
import com.sun.jna.win32.StdCallLibrary; 
import com.sun.jna.win32.StdCallLibrary.StdCallCallback; 
import com.sun.jna.Native; 
import com.sun.jna.Platform; 
import com.sun.jna.Library; 
import com.sun.jna.win32.W32APITypeMapper; 
import com.sun.jna.win32.W32APIFunctionMapper; 

import java.util.Map; 
import java.util.HashMap; 

public class HelloWorld { 
    static Map UNICODE_OPTIONS = new HashMap() { 
     { 
      put("type-mapper", W32APITypeMapper.UNICODE); 
      put("function-mapper", W32APIFunctionMapper.UNICODE); 
     } 
    }; 

    public static class LONG_PTR extends IntegerType { 
     public LONG_PTR() { this(0); } 
     public LONG_PTR(long value) { super(Pointer.SIZE, value); } 
    } 

    public static class UINT_PTR extends IntegerType { 
     public UINT_PTR() { super(Pointer.SIZE); } 
     public UINT_PTR(long value) { super(Pointer.SIZE, value); } 
     public Pointer toPointer() { return Pointer.createConstant(longValue()); } 
    } 

    public static class ULONG_PTR extends IntegerType { 
     public ULONG_PTR() { this(0); } 
     public ULONG_PTR(long value) { super(Pointer.SIZE, value); } 
    } 

    public static class LRESULT extends LONG_PTR { 
     public LRESULT() { this(0); } 
     public LRESULT(long value) { super(value); } 
    } 

    public static class WPARAM extends UINT_PTR { 
     public WPARAM() { this(0); } 
     public WPARAM(long value) { super(value); } 
    } 

    public static class LPARAM extends LONG_PTR { 
     public LPARAM() { this(0); } 
     public LPARAM(long value) { super(value); } 
    } 

    public static class KBDLLHOOKSTRUCT extends Structure { 
     public int vkCode; 
     public int scanCode; 
     public int flags; 
     public int time; 
     public ULONG_PTR dwExtraInfo; 
    } 

    static HANDLE INVALID_HANDLE_VALUE = new HANDLE() { 
     { super.setPointer(Pointer.createConstant(-1)); } 
     public void setPointer(Pointer p) { 
      throw new UnsupportedOperationException("Immutable reference"); 
     } 
    }; 

    public static class HANDLE extends PointerType { 
     public Object fromNative(Object nativeValue, FromNativeContext context) { 
      Object o = super.fromNative(nativeValue, context); 
      if (INVALID_HANDLE_VALUE.equals(o)) 
       return INVALID_HANDLE_VALUE; 
      return o; 
     } 
    } 

    public static class HHOOK extends HANDLE { } 
    public static class HINSTANCE extends HANDLE { } 
    public static class HMODULE extends HINSTANCE { } 

    public interface User32 extends StdCallLibrary { 
     User32 INSTANCE = (User32)Native.loadLibrary("user32", User32.class, UNICODE_OPTIONS); 

     static final int WH_KEYBOARD_LL = 13; 

     public static interface HOOKPROC extends StdCallCallback { 
      LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam); 
     } 

     HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HMODULE hMod, int dwThreadId); 
     LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, LPARAM lParam); 
     LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, Pointer lParam); 

     boolean UnhookWindowsHookEx(HHOOK idHook); 
    } 

    public interface Kernel32 extends StdCallLibrary { 
     Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class, UNICODE_OPTIONS); 

     HMODULE GetModuleHandle(String name); 
    } 

    public static HHOOK hHook; 
    public static User32.HOOKPROC lpfn; 
    public static volatile boolean quit = false; 

    public static void main(String[] args) throws Exception { 
     HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null); 
     System.out.println(hMod); 

     lpfn = new User32.HOOKPROC() { 
      public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam) { 
       System.out.println("here"); 
       quit = true; 
       return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam.getPointer()); 
      } 
     }; 

     hHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, lpfn, hMod, 0); 
     System.out.println(hHook); 

     if(hHook != null) 
      System.out.println("Keyboard hooked, type anything to quit"); 

     while(!quit) { 
      Thread.sleep(100); 
     } 

     if(User32.INSTANCE.UnhookWindowsHookEx(hHook)) 
      System.out.println("Unhooked"); 

    } 
} 

Tôi đã làm bàn phím/móc chuột vài lần sử dụng cả C++ và C# trong quá khứ. Đây là nỗ lực đầu tiên của tôi với Java, và tôi không biết liệu tôi đã nhập và ánh xạ thư viện một cách chính xác hay chưa. Bất kỳ ý tưởng?

Cảm ơn bạn.

Trả lời

10

Có vẻ như bạn cần gọi số GetMessage hoặc PeekMessage, là số lẻ - không được đề cập trong tài liệu cho Hooks hoặc LowLevelKeyboardProc. Tôi không biết đủ về phần này của API để đoán lý do.

tôi chỉ sử dụng các lớp Ví dụ:

import com.sun.jna.examples.win32.*; 

public class Callback { 
    public static User32.HHOOK hHook; 
    public static User32.LowLevelKeyboardProc lpfn; 
    public static volatile boolean quit = false; 

    public static void main(String[] args) throws Exception { 
    W32API.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null); 
    lpfn = new User32.LowLevelKeyboardProc() { 
     public W32API.LRESULT callback(int nCode, W32API.WPARAM wParam, 
      User32.KBDLLHOOKSTRUCT lParam) { 
     System.out.println("here"); 
     quit = true; 
     return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam 
      .getPointer()); 
     } 
    }; 
    hHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, lpfn, hMod, 
     0); 
    if (hHook == null) 
     return; 
    User32.MSG msg = new User32.MSG(); 
    while (!quit) { 
     User32.INSTANCE.PeekMessage(msg, null, 0, 0, 0); 
     Thread.sleep(100); 
    } 
    if (User32.INSTANCE.UnhookWindowsHookEx(hHook)) 
     System.out.println("Unhooked"); 
    } 
} 
+0

Saw một ví dụ sử dụng GetMessage/DispatchMessage, mặc dù chưa bao giờ nghĩ nó có bất cứ điều gì để làm với các hook bàn phím riêng của mình (Tôi không bao giờ cần chúng trong C++/C#). Thực sự đánh giá cao sự giúp đỡ của bạn McDowell, tôi đã tỉnh táo một lần nữa :) – temp

+2

làm thế nào để có được com.sun.jna.examples.win32? Tôi không thể tìm thấy nó từ jna.jar hoặc platform.jar. Làm ơn cho tôi biết. Cảm ơn bạn. –

+3

@Qiang Li - Tôi đã viết mã này chống lại JNA 3.0.9; các lớp mẫu trong 'examples.jar' – McDowell

0

Một ví dụ nhỏ gọn:

import com.sun.jna.platform.win32.Kernel32; 
import com.sun.jna.platform.win32.User32; 
import com.sun.jna.platform.win32.WinDef.HINSTANCE; 
import com.sun.jna.platform.win32.WinDef.LPARAM; 
import com.sun.jna.platform.win32.WinDef.LRESULT; 
import com.sun.jna.platform.win32.WinDef.WPARAM; 
import com.sun.jna.platform.win32.WinUser.HOOKPROC; 

public class MainTestKeyHook { 


    public static void main(String[] args) throws Exception { 
     HOOKPROC hookProc = new HOOKPROC_bg(); 
     HINSTANCE hInst = Kernel32.INSTANCE.GetModuleHandle(null); 

     User32.HHOOK hHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, hookProc, hInst, 0); 
     if (hHook == null) 
      return; 
     User32.MSG msg = new User32.MSG(); 
     System.err.println("Please press any key ...."); 
     while (true) { 
      User32.INSTANCE.GetMessage(msg, null, 0, 0); 
     } 
    } 
} 

class HOOKPROC_bg implements HOOKPROC { 

    public HOOKPROC_bg() { 
    } 

    public LRESULT callback(int nCode, WPARAM wParam, LPARAM lParam) { 
     System.err.println("callback bbbnhkilhjkibh nCode: " + nCode); 
     return new LRESULT(0); 
    } 
} 
Các vấn đề liên quan