Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.223.196.171] |
|
Сообщ.
#1
,
|
|
|
Всем привет!
Народ, выручайте - я уже весь моск сломал! Крокодил не ловится, и не растет кокос! Решил добавить в свою прогу функционал сабжа (тот самый usb-картридер). Ну и понеслась ... Типа хистори А рабочий проект без Qt работает только в путь ... единственное (я х3) пришлось его мало-мало править, иначе не компилился. В результате получился работающий исходник, который ловит мой девайс: Скрытый текст #define ANSI #define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x0501 #include <windows.h> #include <winuser.h> #include <Dbt.h> #include <string> #include <iostream> #include <stdexcept> #define HID_CLASSGUID {0x4d1e55b2, 0xf16f, 0x11cf,{ 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}} #define CLS_NAME L"DUMMY_CLASS" #define HWND_MESSAGE ((HWND)-3) LRESULT message_handler(HWND__* hwnd, UINT uint, WPARAM wparam, LPARAM lparam) { switch (uint) { case WM_NCCREATE: // before window creation return true; break; case WM_CREATE: { // the actual creation of the window // you can get your creation params here..like GUID.. LPCREATESTRUCT params = (LPCREATESTRUCT) lparam; GUID InterfaceClassGuid = *((GUID *)params->lpCreateParams); DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid = InterfaceClassGuid; HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); if (dev_notify == NULL) throw std::runtime_error("Could not register for devicenotifications!"); break; } case WM_DEVICECHANGE: { PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lparam; PDEV_BROADCAST_DEVICEINTERFACE lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE) lpdb; std::string path; if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { std::wstring ws(lpdbv->dbcc_name); path = std::string(ws.begin(), ws.end()); switch (wparam) { case DBT_DEVICEARRIVAL: std::cout << "new device connected: " << path << "\n"; break; case DBT_DEVICEREMOVECOMPLETE: std::cout << "device disconnected: " << path << "\n"; break; } } break; } } return 0L; } int main(int, char **) { HWND hWnd = NULL; WNDCLASSEX wx; ZeroMemory(&wx, sizeof(wx)); wx.cbSize = sizeof(WNDCLASSEX); wx.lpfnWndProc = reinterpret_cast<WNDPROC>(message_handler); wx.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0)); wx.style = CS_HREDRAW | CS_VREDRAW; wx.hInstance = GetModuleHandle(0); wx.hbrBackground = (HBRUSH)(COLOR_WINDOW); wx.lpszClassName = CLS_NAME; GUID guid = HID_CLASSGUID; if (RegisterClassEx(&wx)) { hWnd = CreateWindow(CLS_NAME, L"DevNotifWnd", WS_ICONIC, 0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), (void *)&guid); } if (hWnd == NULL) throw std::runtime_error("Could not create message window!"); std::cout << "waiting for new devices..\n"; MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } Вот теперь наверное самое время ругаться (нет, не ругаться!!! просто разговаривать - матом). Последний сорс - ловит. Spy++ эту хрень не ловит, равно как и все остальные мои ранешние поползновения. Что я ДЕЛАЮ НЕ ТАГ!!! |
Сообщ.
#2
,
|
|
|
JoeUser
Короче вот тут китайцы работают с ЮСБ под виндоус. Код с прода, работает детектит нужное устройство, но только с хабами работать не умеет(или не совсеми). Исходник простой думаю если разберетесь он вам сильно поможет. https://github.com/xuxiandi/AndroidAdb/tree...dows/usb/winusb |
Сообщ.
#3
,
|
|
|
Pavia. tnx - завтра гляну и отпишусь!
|
Сообщ.
#4
,
|
|
|
Pavia, глянул. Материал интересный, но уж больно низкоуровневый.
Я пока обхожусь программированием на уровне юзерспейса. Может быть когда-нибудь, для чего нибудь ... |
Сообщ.
#5
,
|
|
|
Ну что .... это Победа!
Все работает, все ловится. Файлы тестового проекта прилагаю (Qt 5.14.1, С++17, версия компилятора 19.16.27035 от студии 2017) UsbTestWatcher.pro Скрытый текст QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ dialog.cpp HEADERS += \ dialog.h LIBS += -lUser32 # Fuck windows-1251 !!! QMAKE_EXTRA_TARGETS += before_build makefilehook makefilehook.target = $(MAKEFILE) makefilehook.depends = .beforebuild PRE_TARGETDEPS += .beforebuild before_build.target = .beforebuild before_build.depends = FORCE before_build.commands = chcp 1251 main.cpp Скрытый текст #include <QApplication> #include "dialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); } dialog.h Скрытый текст #ifndef DIALOG_H #define DIALOG_H #include <QtWidgets> #include <dbt.h> class Dialog : public QDialog { Q_OBJECT QLabel *L; bool nativeEvent(const QByteArray& eventType, void *message, long *result); public: Dialog(QWidget *parent = nullptr); ~Dialog() {} public slots: void SlotRegister(); void SlotArrived(QString iName); void SlotRemoved(QString iName); signals: void SigUsbArrived(QString iName); void SigUsbRemoved(QString iName); }; #endif // DIALOG_H dialog.cpp Скрытый текст #include "dialog.h" #define DBT_DEVNODES_CHANGED 0x0007 // devnode changed #define DBT_DEVINSTSTARTED 0x8008 // device installed and started #define DBT_DEVINSTREMOVED 0x8009 // device removed from system // // Можно расширить своими классами USB-устройств, тех которые нужно отслеживать // static const GUID GUID_DEVINTERFACE_LIST[] = { // USB Raw Device Interface Class GUID { 0xa5dcbf10, 0x6530, 0x11d2, {0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed}}, // Disk Device Interface Class GUID { 0x53f56307, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}}, // Human Interface Device Class GUID { 0x4d1e55b2, 0xf16f, 0x11Cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}}, // FTDI_D2XX_Device Class GUID { 0x219d0508, 0x57a8, 0x4ff5, {0x97, 0xa1, 0xbd, 0x86, 0x58, 0x7c, 0x6c, 0x7e}}, // FTDI_VCP_Device Class GUID { 0x86e0d1e0, 0x8089, 0x11d0, {0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73}} }; Dialog::Dialog(QWidget *parent) : QDialog(parent) { L = new QLabel("Можно читать список usb-устройств при старте ..."); QVBoxLayout *H = new QVBoxLayout(); H->addWidget(L); setLayout(H); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); connect(this, &Dialog::SigUsbArrived, this, &Dialog::SlotArrived); connect(this, &Dialog::SigUsbRemoved, this, &Dialog::SlotRemoved); QTimer::singleShot(100, this, &Dialog::SlotRegister); } void Dialog::SlotRegister() { DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; HWND hw = (HWND) this->effectiveWinId(); for (size_t i = 0; i < sizeof(GUID_DEVINTERFACE_LIST) / sizeof(GUID); i++) { NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i]; HDEVNOTIFY hDevNotify = RegisterDeviceNotification(hw, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); if (!hDevNotify) { QMessageBox::critical(this, "Ошибка", "Ошибка регистрации уведомителя!"); emit close(); } } } void Dialog::SlotArrived(QString iName) { L->setText(QString("Подключено: %1").arg(iName)); L->repaint(); qDebug() << QString("Подключено: %1").arg(iName); } void Dialog::SlotRemoved(QString iName) { L->setText(QString("Отключено: %1").arg(iName)); L->repaint(); qDebug() << QString("Отключено: %1").arg(iName); } bool Dialog::nativeEvent([[maybe_unused]] const QByteArray& eventType, void *message, [[maybe_unused]] long *result) { MSG *msg = static_cast< MSG * >(message); int msgType = msg->message; if (msgType == WM_DEVICECHANGE) { if (msg->wParam == DBT_DEVICEARRIVAL || msg->wParam == DBT_DEVICEREMOVECOMPLETE) { PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam; PDEV_BROADCAST_DEVICEINTERFACE lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE) lpdb; if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { QString path = QString::fromWCharArray(lpdbv->dbcc_name); if (msg->wParam == DBT_DEVICEARRIVAL) emit SigUsbArrived(path); else emit SigUsbRemoved(path); return true; } } } return false; } Пример отладочного вывода при использовании моего картридера: "Подключено: \\\\?\\USB#VID_0801&PID_0001#6&5f46f56&0&6#{a5dcbf10-6530-11d2-901f-00c04fb951ed}" "Подключено: \\\\?\\HID#VID_0801&PID_0001#7&8918959&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}" "Отключено: \\\\?\\HID#VID_0801&PID_0001#7&8918959&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}" "Отключено: \\\\?\\USB#VID_0801&PID_0001#6&5f46f56&0&6#{a5dcbf10-6530-11d2-901f-00c04fb951ed}" Устройство регается дважды - как обычное USB-устройство, и как HID USB. Это можно фильтровать - правильно настроить в коде регистрацию в RegisterDeviceNotification. Всем спасибо за участие |