VC中添加WM_DEVICECHANGE消息 (转)

在mfc添加WM_DEVICECHANGE不像添加WM_MOUSEMOVE(举例)等等那样直接鼠标点击之后就自动添加。当中是有封装WM_DEVICECHANGE消息的(CWnd::OnDeviceChange),括号里的东西就是msdn里面的东西,就是说CWnd是有这个函数的。

在开发的时候,我们不得不手动添加,而不是用IDE的自动添加功能。所以如果不了解mfc的消息机制的话,看起来会比较晦涩。

入主题。

①添加消息映射

BEGIN_MESSAGE_MAP(CFileCopyDlg, CDialog)

……

ON_WM_DEVICECHANGE()

……

END_MESSAGE_MAP()

②在窗口类当中添加消息响应函数

afx_msg BOOL OnDeviceChange(UINT nEventType,
    DWORD dwData);

所有的消息响应函数都是afx_msg 开头的,而且被定义为空,按jjh的话应该是留着在后面有用的。

③定义这个函数

BOOL CFileCopyDlg::OnDeviceChange(UINT nEventType,
        DWORD dwData)
{
    DEV_BROADCAST_DEVICEINTERFACE * dbd =
        (DEV_BROADCAST_DEVICEINTERFACE*) dwData;

//

//这里进行信息匹配,比如guid等
    switch(nEventType) 
    { 
    case DBT_DEVICEARRIVAL: 
        ::AfxMessageBox(TEXT("得到新的设备"),1,0); 
        return TRUE; 
    } 
    return FALSE; 
}

tips:其中nEventType就是WM_DEVICECHANGE消息的wParam参数,具体的值参考msdn,具体的含义直接查就好了。

DBT_CONFIGCHANGECANCELED
DBT_CONFIGCHANGED
DBT_CUSTOMEVENT
DBT_DEVICEARRIVAL
DBT_DEVICEQUERYREMOVE
DBT_DEVICEQUERYREMOVEFAILED
DBT_DEVICEREMOVECOMPLETE
DBT_DEVICEREMOVEPENDING
DBT_DEVICETYPESPECIFIC
DBT_DEVNODES_CHANGED
DBT_QUERYCHANGECONFIG
DBT_USERDEFINED

 

KUGOU的将歌曲发送到移动设备这个功能,应该就是通过这个消息实现,不过他是把这个消息写入了dll。

不过后来发现原来这个消息是系统给所有的程序发送的,当窗口失去焦点依然可以处理该消息,就想关机或者log off的时候会发送WM_QUERYENDSESSION消息一样。

同样是在处理WM_DEVICECHANGE的函数内,现在知道了,DWORD dwData参数是指向DEV_BROADCAST_*为前缀的指针,它是一个结构体,为什么有个“*”,是因为以此为前缀的结构体有好多个,但是在这里我们会用到两个。

typedef struct _DEV_BROADCAST_HDR {
DWORD

dbch_size

;
DWORD

dbch_devicetype

;
DWORD

dbch_reserved

;

} DEV_BROADCAST_HDR,
*PDEV_BROADCAST_HDR;

 

这个结构体是DEV_BROADCAST_*中最为简单的。只有三个,第三个是保留的。其中

dbch_devicetype参数决定了事件指定的信息,也就是说指定了dwData参数是何种类型的struct,msnd中列举了五种。也就是说,需要获取更多的信息先要判断这个dbch_devicetype参数。

typedef struct _DEV_BROADCAST_VOLUME {
DWORD
dbcv_size
;
DWORD
dbcv_devicetype
;
DWORD
dbcv_reserved
;
DWORD
dbcv_unitmask
;
WORD
dbcv_flags
; } DEV_BROADCAST_VOLUME,
*PDEV_BROADCAST_VOLUME
;
如果dbch_devicetype==DBT_DEVTYP_VOLUME,那就说明是逻辑卷标触发了这个消息。
其中dbcv_unitmask就是盘符,(Bit 0 represents drive A, bit 1弄了好久才明白是什么意思
0为A,1为B,10为C,11为D…以此类推。
而通过GetVolumeInformation就可以得到卷标等信息。
不罗嗦了,直接上代码。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
BOOL CFileCopyDlg::OnDeviceChange( UINT nEventType, 
                                   DWORD dwData)
{
  
     TCHAR szVol[100]; //卷标
     TCHAR szBuffer[100]; //缓冲
     DWORD dwVol; //盘符
     int i = 0;
  
     DEV_BROADCAST_HDR  * dbd = 
         (DEV_BROADCAST_HDR *) dwData;
  
     switch (nEventType)
     {
     case DBT_DEVICEARRIVAL:
         switch (dbd->dbch_devicetype)
         {
         case DBT_DEVTYP_VOLUME:
             PDEV_BROADCAST_VOLUME pbv=   
                 (DEV_BROADCAST_VOLUME * )dwData; 
             DWORD dwDrive = pbv->dbcv_unitmask;
             for (i = 0 ; i < 32 ; i++)
             {
                 if (dwDrive & (1 << i))    //找到第一个可用的逻辑盘符,神笔在这里。
                     break ;        
             }
             ::wsprintf(szBuffer,TEXT( "得到新的设备%c" ), 'A' +i);
             //::AfxMessageBox(szBuffer,1,0);
             ::wsprintf(szBuffer,TEXT( "%c:\\" ), 'A' +i);
             ::GetVolumeInformation(szBuffer,szVol,32,&dwVol,
                 NULL,NULL,NULL,0);
             ::AfxMessageBox(szVol,1,0);
             break ;
         }
         break ;
     }
     return FALSE;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值