Java / JNA 中是否有 MAKELPARAM 之类的东西?

Is there something like MAKELPARAM in Java / JNA?

我想实现取自 this answer 的代码并在非 java 应用程序 window 中模拟点击而不模拟鼠标移动。我知道 JNA 从理论上讲,它应该具有所有 WinAPI 函数。最新的JNA版本是5.6.0但是我没有找到类似MAKELPARAM.

的东西
POINT pt;
    pt.x = 30; // This is your click coordinates
    pt.y = 30;

HWND hWnd = WindowFromPoint(pt);
LPARAM lParam = MAKELPARAM(pt.x, pt.y);
PostMessage(hWnd, WM_RBUTTONDOWN, MK_RBUTTON, lParam);
PostMessage(hWnd, WM_RBUTTONUP, MK_RBUTTON, lParam);

有谁知道Java中是否有类似的东西JNA?

请不要推荐Java机器人。我已经尝试过了,但不幸的是,鼠标光标移动(消失)了大约一毫秒,从起始位置到您需要单击并返回到起始位置的点。

public void performClick(int x, int y) {
        Point origLoc = MouseInfo.getPointerInfo().getLocation();
        robot.mouseMove(x, y);
        robot.mousePress(InputEvent.BUTTON1_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_MASK);
        robot.mouseMove(origLoc.x, origLoc.y);
    }

简答:

不,但您可以自己轻松完成。

长答案:

正如您所说,“JNA ... 理论上应该具有所有 WinAPI 功能。”重要的是要认识到 JNA 有两个组件,核心功能允许 Java 通过 libffi 与本机 (C) 代码交互,包含在 jna 工件中;以及 jna-platform 中用户提供的平台映射(包括许多 WinAPI 映射)。所以 JNA 有能力在 WinAPI 中映射任何东西,但有人需要将它贡献给项目以与他人分享他们的工作。

现在说到MAKELPARAM,简直就是一个宏。你可以看到 source code for it here:

#define MAKELPARAM(l, h)      ((LPARAM)(DWORD)MAKELONG(l, h))

它使用 (WORD) 输入 lh 调用 MAKELONG 宏,将其转换为 DWORD,并进一步将其转换为LPARAM.

MAKELONG 宏是 defined in Windef.h:

#define MAKELONG(a, b)      ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))

JNA does have the LPARAM type mapped,目前在 WinDef class。它需要一个 long 参数给构造函数。

所以你必须简单地取两个 16 位值 lh,将它们映射到 long 的最右边的 32 位,然后将那个长度发送到 LPARAM构造函数。

所以您寻求的解决方案是:

// int args are needed for unsigned 16-bit values
public static WinDef.LPARAM makeLParam(int l, int h) {
    // note the high word bitmask must include L
    return new WinDef.LPARAM((l & 0xffff) | (h & 0xffffL) << 16);
}