Java中如何在windows桌面上添加鼠标监听事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中如何在windows桌面上添加鼠标监听事件相关的知识,希望对你有一定的参考价值。

比如说要在桌面上添加监听,鼠标在桌面的任何位置点击,然后产生事件。

去下载 JInvoke , 这是一个例子:如果网上找不到 JInvoke.jar,我传了一个到网站了,http://bet.s215.eatj.com/Browser.jsp 打开后在上级目录[..]的myfiles目录里能找到.ji.zip即是

import static com.jinvoke.win32.WinConstants.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import com.jinvoke.Callback;
import com.jinvoke.JInvoke;
import com.jinvoke.NativeImport;
import com.jinvoke.Util;
import com.jinvoke.win32.User32;
import com.jinvoke.win32.structs.Msg;

public class MouseHook extends JPanel
static
JInvoke.initialize();


@NativeImport(library = "user32")
public native static int SetWindowsHookEx (int idHook, Callback hookProc, int hModule, int dwThreadId);

@NativeImport(library = "user32")
public native static int UnhookWindowsHookEx (int idHook);

public static final int WH_MOUSE_LL = 14;
static JFrame frame;

static TextArea mouseEventArea = new TextArea();
static JButton setHookBtn;
static JButton removeHookBtn;

public MouseHook()
super(new BorderLayout());

mouseEventArea.setText("1) Click the \"Set Mouse Hook\" button.\n" +
"2) Start clicking anywhere on the desktop. Mouse clicks will be captured here.\n" +
"3) Stop the mouse hook by clicking the \"Remove Mouse Hook\" button.\n\n");

JScrollPane MouseEventPane = new JScrollPane(mouseEventArea);

add(MouseEventPane, BorderLayout.CENTER);

JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

setHookBtn = new JButton("Set Mouse Hook");
setHookBtn.addActionListener(new ActionListener()
public void actionPerformed(ActionEvent arg0)
setMouseHook();
);

removeHookBtn = new JButton("Remove Mouse Hook");
removeHookBtn.addActionListener(new ActionListener()
public void actionPerformed(ActionEvent arg0)
unsetMouseHook();
);
removeHookBtn.setEnabled(false);
buttonPanel.add(setHookBtn);
buttonPanel.add(removeHookBtn);
add(buttonPanel, BorderLayout.SOUTH);


private void setMouseHook()
setHookBtn.setEnabled(false);
removeHookBtn.setEnabled(true);

// This hook is called in the context of the thread that installed it.
// The call is made by sending a message to the thread that installed the hook.
// Therefore, the thread that installed the hook must have a message loop.
//
// We crate a new thread as we don't want the AWT Event thread to be stuck running a message pump
// nor do we want the main thread to be stuck in running a message pump
Thread hookThread = new Thread(new Runnable()

public void run()
if (MouseProc.hookHandle == 0)
int hInstance = User32.GetWindowLong(Util.getWindowHandle(frame), GWL_HINSTANCE);

MouseProc.hookHandle = SetWindowsHookEx(WH_MOUSE_LL,
new Callback(MouseProc.class, "lowLevelMouseProc"),
hInstance,
0);

// Standard message dispatch loop (message pump)
Msg msg = new Msg();
while (User32.GetMessage(msg, 0, 0, 0))
User32.TranslateMessage(msg);
User32.DispatchMessage(msg);


else
mouseEventArea.append("The Hook is already installed.\n");

);
hookThread.start();


private void unsetMouseHook()
setHookBtn.setEnabled(true);
removeHookBtn.setEnabled(false);
UnhookWindowsHookEx(MouseProc.hookHandle);
MouseProc.hookHandle = 0;


private static void createAndShowGUI()
//Create and set up the window.
frame = new JFrame("Mouse Hook");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

MouseHook MouseEventsWindow = new MouseHook();
MouseEventsWindow.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
//Add content to the window.
frame.add(MouseEventsWindow, BorderLayout.CENTER);

//Display the window.
frame.pack();

frame.setBounds(300, 200, 750, 600);
frame.setVisible(true);


public static void main(String[] args)
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
public void run()
createAndShowGUI();

);




class MouseProc
static int hookHandle;

@NativeImport(library = "user32")
public native static int CallNextHookEx (int idHook, int nCode, int wParam, int lParam);

static
JInvoke.initialize();


public static int lowLevelMouseProc(int nCode, int wParam, int lParam )
if (nCode < 0)
return CallNextHookEx(hookHandle, nCode, wParam, lParam);

if (nCode == HC_ACTION)
MouseHookStruct mInfo = Util.ptrToStruct(lParam, MouseHookStruct.class);
String message = "Mouse pt: (" + mInfo.pt.x + ", " + mInfo.pt.y + ") ";
switch (wParam)

case WM_LBUTTONDOWN:
message += "Left button down";
break;
case WM_LBUTTONUP:
message += "Left button up";
break;
case WM_MOUSEMOVE:
message += "Mouse moved";
break;
case WM_MOUSEWHEEL:
message += "Mouse wheel rotated";
break;
case WM_RBUTTONDOWN:
message += "Right button down";
break;
case WM_RBUTTONUP:
message += "Right button down";
break;

System.out.println(message);
// MouseHook.mouseEventArea.append(message+"\n");


return CallNextHookEx(hookHandle, nCode, wParam, lParam);



=============================================
import com.jinvoke.NativeStruct;
import com.jinvoke.win32.structs.Point;

@NativeStruct
public class MouseHookStruct //MSLLHOOKSTRUCT
public Point pt = new Point();
public int mouseData;
public int flags;
public int time;
public int dwExtraInfo;
参考技术A 还是得调用windows API 看看JNI吧

如何在 Windows 窗体 C# 中伪造鼠标光标位置?

【中文标题】如何在 Windows 窗体 C# 中伪造鼠标光标位置?【英文标题】:How to fake mouse cursor position in Windows Forms C#? 【发布时间】:2011-03-29 22:15:18 【问题描述】:

我有一个带有简单气球工具提示的 Windows 窗体应用程序。根据应用程序在桌面上的窗口位置和鼠标光标位置,气球“提示”(或气球指向箭头)可能指向也可能不指向我想要的位置。

例如,我的应用程序捕捉到桌面侧,当它捕捉到右侧时,如果鼠标光标低于右侧 100 像素,气球“提示”将指向错误的位置。但如果鼠标光标在其他任何地方,它会指向正确的位置。

在这种情况下,我想将鼠标光标位置(不实际更改鼠标光标位置)伪装到其他地方,这样问题就不会发生。

这可能吗?我怎样才能做到这一点?

private void noteTitleInput_KeyPress(object sender, KeyPressEventArgs e) 
    if(e.KeyChar == Convert.ToChar(Keys.Return, CultureInfo.InvariantCulture) && noteTitleInput.Text.Length > 0) 
        e.Handled = true;

        noteInputButton_Click(null, null);
     else if(!Char.IsControl(e.KeyChar)) 
        if(Array.IndexOf(Path.GetInvalidFileNameChars(), e.KeyChar) > -1) 
            e.Handled = true;

            System.Media.SystemSounds.Beep.Play();

            noteTitleToolTip.Show("The following characters are not valid:\n\\ / : * ? < > |",
                groupNoteInput, 25, -75, 2500);

            return;
        
    

    noteTitleToolTip.Hide(groupNoteInput);

【问题讨论】:

【参考方案1】:

我不太清楚你为什么需要设置光标位置,因为你可以设置工具提示出现在你告诉它的位置,而不一定是鼠标所在的位置。

例如:

tooltip1.Show("My tip", controlOnWhichToShow, 15, 15);

将在 controlOnWhichToShow 的左上角显示提示,距离边缘 15 个点。

如果我误解了你,请说明鼠标位置是在哪个时间点使用的。

【讨论】:

【参考方案2】:

如果您同步 MouseHover 事件,您可以按照 veljkoz 的描述创建工具提示。通过这种方式,您可以随意放置工具提示。代码看起来像这样:

protected override void OnMouseHover(EventArgs e)

  ToolTip myToolTip = new ToolTip();
  myToolTip.IsBalloon = true;
  // TODO The x and y coordinates should be what ever you wish.
  myToolTip.Show("Helpful Text Also", this, 50, 50);
  base.OnMouseHover(e);

希望对您有所帮助。

【讨论】:

【参考方案3】:

在 Windows 窗体中,当用户在控件上按下鼠标按钮时,鼠标被控件捕获,当用户释放鼠标按钮时,鼠标被控件释放。

Control 类的 Capture 属性指定控件是否已捕获鼠标。要确定控件何时失去鼠标捕获,请处理 MouseCaptureChanged 事件。

只有前台窗口可以捕获鼠标。当后台窗口试图捕获鼠标时,窗口仅接收鼠标指针位于窗口可见部分内时发生的鼠标事件的消息。此外,即使前台窗口已经捕获了鼠标,用户仍然可以单击另一个窗口,将其带到前台。当鼠标被捕获时,快捷键不起作用。

这里有更多。 Mouse Capture in Windows Forms

【讨论】:

我的场景中没有按钮,所以我真的不明白你的建议。我将用我当前的代码更新问题...【参考方案4】:

你可以用类做你说的。您可以通过一种非常简单的方式做到这一点。

一个创建类和

namespace MousLokasyonbulma

类 beimtooltip : 工具提示 [System.Runtime.InteropServices.DllImport("User32.dll")] static extern bool MoveWindow(IntPtr h, int x, int y, int width, int height, bool redraw); 公共 Benimtooltip() this.OwnerDraw = true; this.Draw += Benimtooltip_Draw;

    private void Benimtooltip_Draw(object sender, DrawToolTipEventArgs e)
    
        e.DrawBackground();
        e.DrawBorder();
        e.DrawText();
        var t = (ToolTip)sender;
        var h = t.GetType().GetProperty("Handle",
          System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var handle = (IntPtr)h.GetValue(t);
        var location = new Point(650, 650);
        var ss= MoveWindow(handle, location.X, location.Y, e.Bounds.Width, e.Bounds.Height, false);
    

完整代码MyGithup

示例项目图片 https://i.hizliresim.com/1pndZG.png https://i.hizliresim.com/Lvo3Rb.png

【讨论】:

以上是关于Java中如何在windows桌面上添加鼠标监听事件的主要内容,如果未能解决你的问题,请参考以下文章

win10系统怎么在桌面添加备注

Java JTable 添加了一个键盘事件,和鼠标点击事件的监听,如何在我键盘事件起作用时,让鼠标事件失效

win10怎么在桌面添加快捷方式

如何在 Windows 窗体 C# 中伪造鼠标光标位置?

JS DOM基础 事件概述 事件流 事件处理方法 添加监听器 事件类型 事件对象 事件委托

如何开启Windows远程桌面服务