Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know when a new USB storage device is connected in Qt?

Tags:

c++

windows

qt

usb

I want to know when a USB device is connected to the computer that my Qt application is running on (in Windows). In my main QWidget, I've reimplemented winEventFilter like this:

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

I'd expect qDebug to send at least something when I connect a USB device, but I don't get anything.

I'm guessing that I'm fundamentally misunderstanding the process here - this is my first Qt app!

like image 729
Skilldrick Avatar asked May 12 '09 13:05

Skilldrick


3 Answers

I believe what you may be missing is the call to register for device notification. Here is code that I use to do the same thing, though I override the winEvent() method of the QWidget class and not the 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

NOTE: You will most likely need to change the values of the DEV_BROADCAST_DEVICEINTERFACE to fit your needs.

EDIT: To use this code you will need to include the proper header files and perform the proper setup. DEV_BROADCAST_DEVICEINTERFACE requires the Dbt.h header to be included. Also, the focal point of this code is on the RegisterDeviceNotification function. Info is available on MSDN

like image 117
brader24 Avatar answered Nov 13 '22 05:11

brader24


I'm working along the same lines but in C#.

you need to register your application with the system (look at the RegisterHidNotification() function). Mine looks like this: `

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

The most important part of the function is the bit I've highlighted in bold (or at least tried to). Defined as: public Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); Hope you can adapt it to your application.

like image 26
Dark Star1 Avatar answered Nov 13 '22 05:11

Dark Star1


You can easily reimplement QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) and check for device connection :

    #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;
    }
  • Ref: Developing multi-platform USB applications with Qt
like image 1
IMAN4K Avatar answered Nov 13 '22 04:11

IMAN4K