【发布时间】:2019-01-17 15:57:57
【问题描述】:
如标题所述:有没有办法使用 JNA 将模拟击键发送到非活动窗口(因为 Java 是我最擅长的语言)?当然,当有替代语言可以实现这个目标时,我会去的。
我在网上阅读了很多东西,除了 JNA,但没有成功实现这个目标。
现在我可以用 JNA 的 sendInput() 模拟击键,但这不是我们想要的,因为它会影响活动窗口。 你可以在这里阅读:https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendinput
我的理解是,您可以将 sendMessage() 用于该主题,但我无法使其正常工作。 https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendmessage
LRESULT 发送消息( HWND hWnd, UINT 消息, WPARAM wParam, LPARAM lParam );
还有 SendMessageA 和 SendMessageW。有人说 SendMessage 对于某些操作系统来说太旧了,但我无法验证。
我们以记事本为例。 窗口标题是'new 2 - Notepad++'
按键:https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-keydown
键入:https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-keyup
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
}
public void winAPI() throws InterruptedException {
HWND handler = User32.INSTANCE.FindWindow(null, "new 2 - Notepad++");
// 0x0100 WM_KEYDOWN
User32.INSTANCE.SendMessage(handler, 0x0100, new WinDef.WPARAM(0x31), new WinDef.LPARAM(0)}
// recommended for dedection
Thread.sleep(200);
// 0x0101 WM_KEYUP
User32.INSTANCE.SendMessage(handler, 0x0101, new WinDef.WPARAM(0x31), new WinDef.LPARAM(0)}
}
我为 SendMessage(A?)(W?)() 的正确实现而苦恼,因为它没有在 JNA 中实现。
还有如何创建 WPARAM 和 LPARAM? MSDN 说有特定的消息。 所以当传递 WM_KEYDOWN 或 WM_KEYUP 作为消息参数时:
WPARAM 是虚拟的 KeyCode:只是一个 int?
LPARAM 是一个字节数组(?)。
我猜它不起作用是因为 WPARAM 和 LPARAM 的参数数据类型错误。
【问题讨论】:
标签: java winapi jna sendmessage sendinput