如何在Qt中知道何时连接了新的USB存储设备?

8

我希望了解当USB设备连接到我的Qt应用程序正在运行的计算机上时(在Windows中),如何检测。在我的主QWidget中,我已经重新实现了winEventFilter方法,代码如下:

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

我希望在连接USB设备时,qDebug至少发送一些内容,但我没有收到任何信息。

我猜想我对整个过程的理解有误 - 这是我的第一个Qt应用程序!


不知道您是否还有这个项目,但我想知道(因为我刚开始学习QT),能否给我一个副本作为参考。我还不知道如何覆盖wndProc过程,并且还没有看到好的示例。同样的,我也没有看到适用于Qt的平台调用的好例子。 提前感谢您。 - Dark Star1
3个回答

6

我认为你可能缺少注册设备通知的调用。这是我用来完成同样任务的代码,不过我重写了QWidget类的winEvent()方法而不是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

抱歉我不太懂,但是我无法让DEV_BROADCAST_DEVICEINTERFACE工作(错误:`DEV_BROADCAST_DEVICEINTERFACE' 在此范围内未声明)。我需要包含额外的头文件吗? - Skilldrick
不用道歉。我自己也曾花了很长时间来理解这一切。希望我的编辑能为您提供一些关于如何使用我提供的代码的方向。但其中仍然可能存在不完整的部分。我附上了 MSDN 的链接,以便您获取更多信息的来源。如果我有更多的时间,我会尽力给您更详细的实现指导。这样至少可以将消息传递到您的处理程序中。 - brader24

2

我正在使用C#沿着同样的路线工作。

你需要注册你的应用程序到系统中(查看 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"); 希望您可以将其适应于您的应用程序。

1
你可以轻松地重新实现 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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接