Я также заинтересован в вашем коде. Не могли бы вы предоставить его? Tnx!

аюсь написать простое приложение на Java, которое будет взаимодействовать с USB-устройством. Устройство USB сделано мной, используя Микроконтроллер Микрочипа. Связь довольно проста, поскольку устройство USB относится к классу HID, между компьютером и устройством обмениваются массивами по 64 байта. Моя программа находит устройство на основе идентификатора продукта и идентификатора производителя, может записывать и считывать 64 байта, но теперь я хотел бы определить, когда устройство подключено или отключено от компьютера.

Как я видел в программе на C #, предоставляемой Microchip в качестве примера приложения, метод WndProc переопределяется и обрабатывается сообщение WM_DEVICECHANGE. У меня вопрос, как это можно сделать в Java с помощью JNA, как я могу переопределить метод WindowProc и обрабатывать сообщения, если это вообще возможно :), но я надеюсь, что это так: D

Заранее спасибо за ответы.

Габор.

 user95479020 сент. 2011 г., 14:53
Можете ли вы опубликовать код, который вы использовали. Благодарю.
 user99475014 окт. 2011 г., 06:53
У меня один вопрос: разве вам не приходилось использовать что-то вроде RegisterDeviceNotification или вы просто ищете устройства портов, для которых Windows автоматически передает WM_DEVICECHANGE?

Ответы на вопрос(4)

Сначала расширьте интерфейс 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);
}

Затем добавьте в интерфейс WinUser необходимый вам код сообщения Windows, в моем случае это 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;
}

Затем создайте интерфейс с функцией обратного вызова, которая фактически будет моей функцией 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);
    }
};

И затем где-нибудь в коде JFrame, где вы инициализируете вещи, добавьте новый адрес для оконной процедуры с помощью функции SetWindowLong:

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

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

Этот код работает хорошо, но у меня есть некоторые сомнения относительно одной вещи. Я не уверен, что возвращаемое значение функции обратного вызова является правильным. Я прочитал в MSDN, что после обработки сообщения WM_DEVICECHANGE функция обратного вызова должна возвращать true, и я не уверен, что значение, которое я возвращаю в настоящее время, является ожидаемым системой, поэтому любые предложения приветствуются.

Если кого-то интересует весь код, который я написал для HID-связи, просто спросите, я был бы более чем рад помочь :)

Ура, Габор.

 Sundae24 февр. 2015 г., 11:24
Нет необходимости создавать пользовательский интерфейс обратного вызова, как MyListener больше. JNA предоставляет интерфейс WinUser.WindowProc.
 mtraut14 янв. 2011 г., 14:26
спасибо, что поделились своими результатами

которое я выложил ранее, имеет некоторые проблемы, к сожалению :(

Так как он переопределяет WndProc окна, элементы управления, которые я добавил в свой фрейм, не работали (что неудивительно, поскольку сообщения рисования, перекраски и т. Д. Не обрабатывались). Тогда я понял, что вместо возвращенияLRESULT(1) Я должен вызывать процедуру окна по умолчанию (как она используется в программах Win32 C ++), но это все равно не решило проблему, рамка была нарисована, но кнопки не работали, хотя я смог обновить метки ... Поэтому мне пришлось отказаться и от этого решения.

После поиска еще в Интернете я нашел отличную статьюВот (редактировать: ссылка не работает,оригинальную статью можно найти здесь)где статическое скрытое окно создается для обработки сообщений Windows. Мне удалось закодировать его для моего приложения, и оно прекрасно работает. (Мне пришлось дополнительно расширить классы из JNA, потому что некоторые функции не были включены. Я могу опубликовать свой код, если кому-то интересно.)

Надеюсь это поможет.

 Martijn29 авг. 2013 г., 22:02
Я также заинтересован в вашем коде. Не могли бы вы предоставить его? Tnx!
 Algok11 авг. 2014 г., 17:42
Я также заинтересован в вашем коде. Не могли бы вы предоставить его? Tnx!
 Maxbester14 мая 2013 г., 13:28
Мне интересен ваш код. Не могли бы вы предоставить это? Спасибо!
 Joachim Sauer25 янв. 2011 г., 09:44
Не публикуйте дополнительную информацию в качестве ответа, вместо этого отредактируйте свой вопрос.

ь ее в коде Java. Если вы создаете приложение.

Используйте JACOB ИЛИJCOM

Это будет мост между Java и COM-объектом. Другой вариант - вы можете использовать JNI для связи с DLL и OCX.

 Gabor13 янв. 2011 г., 10:28
Спасибо за ответ, но нет другого варианта, потому что я на самом деле не хочу использовать код C #, я только что упомянул его, потому что это не то, откуда я получил представление о WM_DEVICECHANGE. Например, через класс Kernel32 JNA у меня был доступ к методам ReadFile и WriteFile для чтения и записи на мое USB-устройство. Благодарю.

вы должны сначала создать собственное окно. И когда вы создаете новое окно, вы также должны управлять его насосом сообщений. Вот пример того, как вы можете это сделать.Собственный пример кода JNA также может быть очень полезным.

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

Ваш ответ на вопрос