Как узнать, когда в Qt подключено новое запоминающее устройство USB?

Я хочу знать, когда USB-устройство подключено к компьютеру, на котором работает мое приложение Qt (в Windows). В моем основном QWidget я повторно реализовал winEventFilter следующим образом:

bool winEventFilter ( MSG * msg, long * result ) {
    qDebug() << msg;
    return false;
}

Я ожидаю, что qDebug отправит хоть что-то, когда я подключу USB-устройство, но ничего не получаю.

Я предполагаю, что я в корне неправильно понимаю процесс здесь - это мое первое приложение Qt!


person Skilldrick    schedule 12.05.2009    source источник
comment
Не знаю, есть ли у вас еще этот проект, но мне было интересно (поскольку я только начал изучать QT), могу ли я получить его копию для справки. Я еще не знаю, как переопределить процедуру wndProc, и пока не видел хороших примеров для нее. Я также не видел хороших для вызова платформы для Qt. Заранее спасибо.   -  person Dark Star1    schedule 01.06.2010


Ответы (3)


Я считаю, что вам может не хватать вызова для регистрации для уведомления устройства. Вот код, который я использую, чтобы сделать то же самое, хотя я переопределяю метод winEvent() класса QWidget, а не метод winEventFilter.

// Register for device connect notification
DEV_BROADCAST_DEVICEINTERFACE devInt;
ZeroMemory( &devInt, sizeof(devInt) );
devInt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
devInt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
devInt.dbcc_classguid = GUID_DEVINTERFACE_VOLUME;

m_hDeviceNotify =
    RegisterDeviceNotification( winId(), &devInt, DEVICE_NOTIFY_WINDOW_HANDLE );   
if(m_hDeviceNotify == NULL)
{
    qDebug() << "Failed to register device notification";
} // end if

ПРИМЕЧАНИЕ. Скорее всего, вам потребуется изменить значения DEV_BROADCAST_DEVICEINTERFACE в соответствии с вашими потребностями.

РЕДАКТИРОВАТЬ: Чтобы использовать этот код, вам нужно будет включить соответствующие файлы заголовков и выполнить правильную настройку. DEV_BROADCAST_DEVICEINTERFACE требует включения заголовка Dbt.h. Кроме того, основное внимание в этом коде уделяется функции RegisterDeviceNotification. Информация доступна на MSDN.

person brader24    schedule 12.05.2009
comment
Извините за глупость, но я не могу заставить DEV_BROADCAST_DEVICEINTERFACE работать (ошибка: `DEV_BROADCAST_DEVICEINTERFACE' не был объявлен в этой области). Нужно ли включать дополнительные заголовочные файлы? - person Skilldrick; 12.05.2009
comment
Не жалей. Мне самому было трудно во многом разобраться. Надеюсь, мое редактирование даст вам некоторое представление о том, как использовать код, который я дал. Хотя, возможно, он еще не завершен. Я включил ссылку на MSDN, чтобы дать вам источник для получения дополнительной информации. Если бы у меня было больше времени, я бы попытался дать вам более подробное руководство о том, как это реализовать. Это действительно должно по крайней мере доставлять сообщения вашему обработчику. - person brader24; 12.05.2009

Я работаю в том же направлении, но на С#.

вам необходимо зарегистрировать ваше приложение в системе (посмотрите на функцию RegisterHidNotification()). Мой выглядит так: `

void RegisterHidNotification() //Register this application to recieve all USB device notices

        {
            BroadcastHeader dbi = new BroadcastHeader();
            int size = Marshal.SizeOf(dbi);
            dbi.Size = size;
            dbi.Type = DeviceType.DeviceInterface;
            **dbi.Classguid = GUID_DEVINTERFACE_USB_DEVICE**;
            dbi.Name = 0;
            IntPtr buffer = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(dbi, buffer, true);
            IntPtr r = RegisterDeviceNotification(this.Handle, buffer, (int)DeviceEvents.regWindowHandle);
            if (r == IntPtr.Zero)
                statusLabel.Text = GetLastError().ToString();
        }`

Самая важная часть функции — это часть, которую я выделил жирным шрифтом (или, по крайней мере, попытался). Определяется как: public Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); Надеюсь, вы сможете адаптировать его к своему приложению.

person Dark Star1    schedule 14.05.2009

Вы можете легко переопределить QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) и проверить подключение устройства:

    #ifdef Q_OS_WIN
    #include <Dbt.h>
    #endif

    bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) {
#ifdef Q_OS_WIN
        MSG* msg = reinterpret_cast<MSG*>(message);
        if (msg->message == WM_DEVICECHANGE) {
            switch (msg->wParam) {
            case DBT_DEVICEARRIVAL:
                qDebug() << "connected";
                break;
            case DBT_DEVICEREMOVECOMPLETE:
                qDebug() << "disconnected";
                break;
            default:
                break;
            }
        }
#endif // Q_OS_WIN
        return false;
    }
person IMAN4K    schedule 17.08.2019