QT detect event windows

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)

By last week had some very frustrating problems about QT. What I would like to do is to detect if a USB stick is plugged and then write a file on it. On Linux totally no problem but on windows it was totally difficult to find out how it works. The QT documentation is very worse and should be extended. I didn’t find any hint regarding my problem. What I did is I took a look at a Visual Studio project which does what I would like to do. So I tried to do the same in QT. But what I found out is that even when I set the broadcast the so called “wineventfilterdidn’t get any signal!

Here is the solution for everybody who is looking for the solution:

Important parts .h:

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
bool winEvent ( MSG * msg, long * result );
~MainWindow();
private:
bool writefile(QChar usblet);
bool SetupNamedPipe(void);

OVERLAPPED   m_PipeOverlappedIO;
HANDLE       m_ConnectEvent;
HDEVNOTIFY   hDevNotify;
UINT         m_shutdownMsgID;
Ui::MainWindow *ui;

signals:
void USB_Plugged(QChar tchar);
void USB_Removed(QChar tchar);

};

Important parts .cpp:

bool MainWindow::winEvent ( MSG * msg, long * result )
{
int msgType = msg->message;
if(msgType == WM_DEVICECHANGE)
{
qDebug() << “winEvent in MgFrame : WM_DEVICECHANGE” ;
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
switch(msg->wParam)
{
case DBT_DEVICEARRIVAL:
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{

PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
//if (lpdbv -> dbcv_flags & DBTF_NET)
if(DBTF_NET)
{
char ALET = FirstDriveFromMask(lpdbv->dbcv_unitmask);
emit USB_Plugged(QChar(ALET));
this->writefile(QChar(ALET));
qDebug() << “USB_Arrived “<<ALET;

}
}
break;

case DBT_DEVICEREMOVECOMPLETE:
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
//if (lpdbv -> dbcv_flags & DBTF_NET)
if(DBTF_NET)
{
char ALET = FirstDriveFromMask(lpdbv->dbcv_unitmask);
emit USB_Removed(QChar(ALET));

qDebug() << “USB_Removed “<<ALET;
}
}
break;
} // skip the rest

} // end of if msgType
return false; // let qt handle the rest

}

If you need more help with QT could suggest that you may ask “Programmierung Advertiseman“. He’s a very smart and good programmer worked with him many times and could strongly recommend him.

That’s what I tried hard before. Don’t waste your time by doing it the same way like in Visual Studio.

DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0x53F56307, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B);

bool MainWindow::doRegisterForDevNotification(){
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
CopyMemory(&NotificationFilter.dbcc_classguid, &GUID_DEVINTERFACE_USB_DEVICE, sizeof(GUID));
if( RegisterDeviceNotification( this->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE ) == NULL)
qWarning() << “RegisterDeviceNotification failed:” << GetLastError(); //NotificationFilter.dbcc_classguid = GUID_DEVINTERFCE_USB_DEVICE; //GUID_DEVINTERFACE_USB_DEVICE; //DevNotify = RegisterDeviceNotification( this->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

//return(NULL != hDevNotify);
qDebug()<<“Test”;
return true;
}

This entry was posted in QT. Bookmark the permalink.

5 Responses to QT detect event windows

  1. Sam says:

    Hi,

    Does it work fine? I mean your QT app does receive the usb plug-in message from the system? if so could you please send me your whole code, I got stuck on this issue for a while, thanks very much.

    • adminknown says:

      Hi Sam,

      Sure it works in my case. It’s quiet a while ago that I did the project. Just let me know if you still need the project sources

      • Sam says:

        Hi adminknown ,

        Thanks for your feedback, I had resloved this problem.

        But I have to invoke the RegisterDeviceNotification function(which you tried before) to regist the app’s winid to the system, otherwise I only can receive the WM_DEVICECHANGE message with wParam set to DBT_DEVNODES_CHANGED and lParam set to zero (no DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE) in MainWindow::winEvent function, I only can receive the proper messages after the registing step.

        Maybe I made another mistake?

  2. Raghu says:

    Thank you very much for this piece of code.

  3. skydvr says:

    thanks! this helped. I had to find the “FirtDriveFromMask” code though – found that at:
    http://support.microsoft.com/kb/163503

Leave a Reply

Your email address will not be published. Required fields are marked *