代码改变世界

对《VC中添加WM_DEVICECHANGE消息(经典)》的补充

2011-10-31 20:12  捣乱小子  阅读(3215)  评论(0编辑  收藏  举报

笔者在VC中添加WM_DEVICECHANGE消息(经典)中就做了关于消息WM_DEVICECHANGE的笔记,是酷狗的将歌曲发送至移动设备让我有感而发,其实在win下的右键菜单功能就已经有了这个功能。

但是知道了有新的设备是完全不够的,为了能够达到更加客观的效果,至少让用户知道这个盘符(A,B,C,…)和其卷标。(相信通过盘符我们以后又可以对文件进行操作,到时一头雾水之时,兴许可以在此处找到答案)

一开始便把头埋进msdn的瀚海里,准把我淹死,所以学习计算机的童鞋们要好好提高英语的水平,绝对没有害处。

入主题。

同样是在处理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就可以得到卷标等信息。
不罗嗦了,直接上代码。
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;
}