接收不到DBT_DEVICEQUERYREMOVE消息怎么办?

接收不到 DBT_DEVICEQUERYREMOVE 消息怎么办?

 

注册这个消息就可以了。

 

ms-help://MS.MSDNQTR.v90.en/devio/base/processing_a_request_to_remove_a_device.htm

 

In the following example, an application maintains an open handle, hFile, to the file or device represented by FileName. The application registers for device event notification on the underlying device by calling the RegisterDeviceNotification function, using a DBT_DEVTYP_HANDLE type notification filter and specifying the hFile variable in the dbch_handle member of the filter.

 

MSDN 上面这么简单的一句,弄了半天才明白。

 

下面是注册方法

 

HANDLE  hU = CreateFile(

                   L"F://" ,

                   GENERIC_READ,

                   FILE_SHARE_READ | FILE_SHARE_WRITE,

                   0,

                   OPEN_EXISTING,

                   FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL,

                   0);

 

DEV_BROADCAST_HANDLE  NotificationFilter;

ZeroMemory( &NotificationFilter, sizeof (NotificationFilter) );

NotificationFilter.dbch_size = sizeof (DEV_BROADCAST_HANDLE );

NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;

NotificationFilter.dbch_handle = hU;

*hDevNotify = RegisterDeviceNotification(hDlg, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

 

if (!*hDevNotify)

{

         DWORD iRet = GetLastError();

         _tprintf(L"RegisterDeviceNotification failed: %d/n" , GetLastError());

         return FALSE;

}

 

简单的说一下。就是要定义一个 DEV_BROADCAST_HANDLE 的结构,它的 devicetype 被赋值成 DBT_DEVTYP_HANDLE ,它的 handle createFile 创建出来的,这里是 F ( 我的 u 盘的盘符 ) ,然后调用 RegisterDeviceNotification 方法,第一个参数是接收 DBT_DEVICEQUERYREMOVE 消息的窗口的句柄。第二个参数是刚才定义的一个 DEV_BROADCAST_HANDLE ,第三个参数是标志参数,这里取值 DEVICE_NOTIFY_WINDOW_HANDLE ,第三个和第一个是配合的,这里是要把这个消息传给一个窗口,所以用的这个。

 

在接受这个消息的时候:

 

                            case DBT_DEVICEQUERYREMOVE:

                                     {

                                               PDEV_BROADCAST_HDR pDBHdr;

                                               PDEV_BROADCAST_HANDLE pDBHandle;

                                                pDBHdr = (PDEV_BROADCAST_HDR) lParam;

                                               switch (pDBHdr->dbch_devicetype)

                                               {

                                               case DBT_DEVTYP_HANDLE:

                                                        pDBHandle = (PDEV_BROADCAST_HANDLE) pDBHdr;

                                                        //return BROADCAST_QUERY_DENY ;

                                                        if (hU != INVALID_HANDLE_VALUE)

                                                        {

                                                                 CloseHandle(hU);

                                                                 UnregisterDeviceNotification(pDBHandle->dbch_hdevnotify);

return true;

                                                        }

                                               }

                                               break ;

                                     }

这里我做的是强制的关掉 U 盘句柄。这样当你点击拔出 U 盘时,即使你正在使用 U 盘,也不会跳出 U 盘的提示框了。

 

WM_DEVICECHANGE 里默认是只注册了 DBT_DEVICEREMOVECOMPLETE DBT_DEVICEARRIVAL 消息,所以只能接收到这两个,如果要使用其他的消息,必需手动注册一下才可以。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章