java microchip_JAVA JNA WindowProc implementation

该博客讨论了如何在Java应用程序中利用JNA(Java Native Access)来检测USB设备的连接和断开。作者通过扩展User32接口并定义回调函数来处理WM_DEVICECHANGE消息,从而实现对USB设备状态变化的监听。同时,提到了在处理WM_DEVICECHANGE消息时返回值的疑问以及可能存在的问题,如影响到窗口控件的正常工作,并分享了最终的解决方案。
摘要由CSDN通过智能技术生成

问题

I'm trying to write a simple application in Java that will communicate with an USB device. The USB device is made by me using a Microchip Microcontroller. The communication is rather simple, since the USB device is from the HID Class, arrays of 64 bytes are exchanged between the computer and the device.

My program finds the device based on the product ID and the vendor ID, can write and read 64 bytes, but now I would like to detect when the device is connected or disconnected from the computer.

As I've seen in a C# program provided by Microchip as an example application, the WndProc method is overriden and the WM_DEVICECHANGE message is handled. My question is how can this be done in Java using JNA, how can I override the WindowProc Method and handle messages, if this is possible at all :), but I hope it is :D

Thanks in advance for the answers.

Gabor.

回答1:

I finally managed to solve the problem :) And I found the following solution:

First extend the User32 interface in the following way

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);

}

Then extend the WinUser interface with the Windows Message code that you need, in my case this is the WM_DEVICECHANGE, because I want to check I the USB Device was attached or detached from the computer.

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;

}

Then create an interface with the callback function, which will actually be my WndProc function.

//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);

}

};

And then somewhere in the code of the JFrame where you initialize things add the new address for the window procedure with the SetWindowLong function:

// Get Handle to current window

HWND hWnd = new HWND();

hWnd.setPointer(Native.getWindowPointer(this));

MyUser32.MYINSTANCE.SetWindowLong(hWnd, MyUser32.GWLP_WNDPROC, listener);

This code works nicely, but I have some doubts regarding one thing. I'm not sure if the return value of the callback function is correct. I've read in the MSDN that after handling a WM_DEVICECHANGE message the callback function should return true and I'm not sure that the value i'm currently returning is the one expected by the system, so any suggestions are welcome.

If anyone is interested in the whole code I've written for the HID communication just ask, I would be more than happy to help :)

Cheers,

Gabor.

回答2:

If you don't have an existing window handle you have to create your own window first. And when you create a new window you also have to manage its message pump. Here's an example on how you can do this. JNA's own example code could also be very useful.

Thread thread;

HWND hWnd;

static final int WM_NCCREATE = 0x0081;

void start() {

thread = new Thread(this::myThread);

thread.start();

}

void stop() {

User32.INSTANCE.PostMessage(hWnd, User32.WM_QUIT, null, null);

}

WindowProc callback = new WindowProc() {

@Override

public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) {

switch (uMsg) {

case WM_NCCREATE:

return new LRESULT(1);

case User32.WM_DEVICECHANGE:

return new LRESULT(1);

default:

return new LRESULT(0);

}

}

};

void myThread() {

WString className = new WString("myclass");

WNDCLASSEX wx = new WNDCLASSEX();

wx.clear();

wx.lpszClassName = className;

wx.lpfnWndProc = callback;

if (User32.INSTANCE.RegisterClassEx(wx).intValue() != 0) {

hWnd = User32.INSTANCE.CreateWindowEx(0, className, null, 0, 0, 0, 0, 0, null, null, null, null);

WinUser.MSG msg = new WinUser.MSG();

msg.clear();

while (User32.INSTANCE.GetMessage(msg, hWnd, 0, 0) > 0) {

User32.INSTANCE.TranslateMessage(msg);

User32.INSTANCE.DispatchMessage(msg);

}

}

}

回答3:

You can create COM DLL or OCX of your C# program and use it in the java code. If you create application.

Use JACOB OR JCOM

It will be a bridge between Java and COM Object. Other option is you can use JNI to communicate with DLL and OCX.

回答4:

The solution I posted previously has some problems, unfortunately :(

Since it overrides the WndProc of the window, the controls I added to my Frame weren't working (not surprisingly, because no paint, repaint, etc. messages were handled). Then I realised that instead of returning LRESULT(1) I should call the default window proc (as it is used in Win32 C++ programs), but this still didn't solve the problem, the frame was painted but the buttons weren't working, although I was able to update labels... So I had to abandon this solution too.

After searching some more on the internet I've found a great article here (edit: link is dead, original article can be found here), where a static hidden window is created to handle windows messages. I managed to code it for my application and it works great. (I had to further extend the classes from JNA because several functions were not included. I can post my code if someone is interested.)

Hope this helps.

来源:https://stackoverflow.com/questions/4678247/java-jna-windowproc-implementation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>