JAVA JNA WindowProc实现

Gab*_*bor 7 java wndproc jna

我正在尝试用Java编写一个简单的应用程序,它将与USB设备通信.USB设备由我使用Microchip微控制器制造.通信相当简单,因为USB设备来自HID类,所以在计算机和设备之间交换64字节的数组.我的程序根据产品ID和供应商ID查找设备,可以写入和读取64个字节,但现在我想检测设备何时连接或断开与计算机的连接.

正如我在Microchip提供的C#程序中看到的那样,WndProc方法被覆盖并处理WM_DEVICECHANGE消息.我的问题是如何使用JNA在Java中完成,我如何覆盖WindowProc方法并处理消息,如果可能的话:),但我希望它是:D

提前谢谢你的答案.

的Gabor.

Gab*_*bor 8

我终于设法解决了问题:)我找到了以下解决方案:

首先以下列方式扩展User32接口

public interface MyUser32 extends User32 {

    public static final MyUser32 MYINSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.UNICODE_OPTIONS);

    /**
     * Sets a new address for the window procedure (value to be set).
     */
    public static final int GWLP_WNDPROC = -4;

    /**
     * Changes an attribute of the specified window
     * @param   hWnd        A handle to the window
     * @param   nIndex      The zero-based offset to the value to be set.
     * @param   callback    The callback function for the value to be set.
     */
    public int SetWindowLong(WinDef.HWND hWnd, int nIndex, Callback callback);
}
Run Code Online (Sandbox Code Playgroud)

然后使用您需要的Windows消息代码扩展WinUser接口,在我的情况下,这是WM_DEVICECHANGE,因为我想检查USB设备是否已连接或与计算机分离.

public interface MyWinUser extends WinUser {
    /**
     * Notifies an application of a change to the hardware configuration of a device or the computer.
     */
    public static final int WM_DEVICECHANGE = 0x0219;
}
Run Code Online (Sandbox Code Playgroud)

然后用回调函数创建一个接口,它实际上是我的WndProc函数.

//Create the callback interface 
public interface MyListener extends StdCallCallback {

    public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
}

public MyListener listener = new MyListener()
{
    public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam)
    {
        if (uMsg == MyWinUser.WM_DEVICECHANGE)
        {
            // TODO Check If my device was attached or detached
            return new LRESULT(1);
        }
        return new LRESULT(0);
    }
};
Run Code Online (Sandbox Code Playgroud)

然后在初始化事物的JFrame代码中的某处使用SetWindowLong函数为窗口过程添加新地址:

    // Get Handle to current window
    HWND hWnd = new HWND();
    hWnd.setPointer(Native.getWindowPointer(this));

    MyUser32.MYINSTANCE.SetWindowLong(hWnd, MyUser32.GWLP_WNDPROC, listener);
Run Code Online (Sandbox Code Playgroud)

这段代码很好用,但我对一件事情有些怀疑.我不确定回调函数的返回值是否正确.我在MSDN中读到,在处理WM_DEVICECHANGE消息后,回调函数应该返回true,我不确定我当前返回的值是系统预期的值,所以欢迎任何建议.

如果有人对我为HID通信编写的整个代码感兴趣,那么我会非常乐意帮助:)

干杯,Gabor.


Ash*_*och 1

您可以创建 C# 程序的 COM DLL 或 OCX 并在 java 代码中使用它。如果您创建应用程序。

使用 JACOB 或JCOM

它将成为 Java 和 COM 对象之间的桥梁。另一种选择是您可以使用 JNI 与 DLL 和 OCX 进行通信。