Posted on 2010-12-17 00:49
penngo 閱讀(5239)
評(píng)論(2) 編輯 收藏
java本身是沒(méi)有提供直接訪問(wèn)系統(tǒng)的API方法,查了下資料,要實(shí)現(xiàn)鼠標(biāo)鉤子有3種方法,
1、使用JNI方法,需要自己寫(xiě)C實(shí)現(xiàn),比較復(fù)雜。
2、使用swt extension,直接提供了鼠標(biāo)鉤子的實(shí)現(xiàn),但是用它調(diào)用其它windows api,沒(méi)有成功,放棄了使用它。
3、使用JNA,JNA是建立在JNI 技術(shù)之上的,簡(jiǎn)化了Java訪問(wèn)window api的方法。
考慮到要調(diào)用其它window api的原因,選用了JNA,順便寫(xiě)一個(gè)JNA實(shí)現(xiàn)鼠標(biāo)鉤子的測(cè)試?yán)樱?br />

public class MouseHook extends JFrame
{
private static final long serialVersionUID = 1L;
public static final int WM_MOUSEMOVE = 512;
public static final int WM_LBUTTONDOWN = 513;
public static final int WM_LBUTTONUP = 514;
public static final int WM_RBUTTONDOWN = 516;
public static final int WM_RBUTTONUP = 517;
public static final int WM_MBUTTONDOWN = 519;
public static final int WM_MBUTTONUP = 520;
private static HHOOK hhk;
private static LowLevelMouseProc mouseHook;

private JLabel labelX;
private JLabel labelY;
private JPanel contentPane;


public static void main(String[] args)
{
final MouseHook frame = new MouseHook();
frame.setVisible(true);

final User32 lib = User32.INSTANCE;
HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);

mouseHook = new LowLevelMouseProc()
{
public LRESULT callback(int nCode, WPARAM wParam,

MOUSEHOOKSTRUCT info)
{

if (nCode >= 0)
{

switch (wParam.intValue())
{
case MouseHook.WM_MOUSEMOVE:
System.err.println("in callback, x=" + info.pt.x
+ " y=" + info.pt.y);
frame.getLabelX().setText(String.valueOf(info.pt.x));
frame.getLabelY().setText(String.valueOf(info.pt.y));
}
}
return lib
.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
}
};
hhk = lib.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseHook, hMod, 0);

int result;
MSG msg = new MSG();

while ((result = lib.GetMessage(msg, null, 0, 0)) != 0)
{

if (result == -1)
{
System.err.println("error in get message");
break;

} else
{
System.err.println("got message");
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
}
lib.UnhookWindowsHookEx(hhk);
}


public MouseHook()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);

JLabel lblX = new JLabel("X:");
lblX.setFont(new Font("宋體", Font.PLAIN, 14));
lblX.setBounds(46, 33, 22, 27);
contentPane.add(lblX);

JLabel lblY = new JLabel("Y:");
lblY.setFont(new Font("宋體", Font.PLAIN, 14));
lblY.setBounds(144, 39, 17, 15);
contentPane.add(lblY);

labelX = new JLabel("");
labelX.setBounds(65, 39, 54, 15);
contentPane.add(labelX);

labelY = new JLabel("");
labelY.setBounds(160, 39, 54, 15);
contentPane.add(labelY);
}


public JLabel getLabelX()
{
return labelX;
}


public void setLabelX(JLabel labelX)
{
this.labelX = labelX;
}


public JLabel getLabelY()
{
return labelY;
}


public void setLabelY(JLabel labelY)
{
this.labelY = labelY;
}


public interface LowLevelMouseProc extends HOOKPROC
{
LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
}


public class Point extends Structure
{

public class ByReference extends Point implements Structure.ByReference
{
};
public com.sun.jna.NativeLong x;
public com.sun.jna.NativeLong y;
}


public static class MOUSEHOOKSTRUCT extends Structure
{
public static class ByReference extends MOUSEHOOKSTRUCT implements

Structure.ByReference
{
};

public User32.POINT pt;
public User32.HWND hwnd;
public int wHitTestCode;
public User32.ULONG_PTR dwExtraInfo;
}
}
源碼