通过WMDeviceChange 消息可以知道插入U盘,但怎样得到设备,得到盘符呢 通过WMDeviceChange 消息可以知道插入U盘,但怎样得到设备,得到盘符呢?现在有两种解决方案,一是通过WMDeviceChange获取U盘的设备ID,然后根据设备ID获取对应的盘符.二是通过U盘盘符获取对应的设备ID?请们大家怎么解决. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 当wParam==DBT_DEVICEARRIVAL时,lParam是一个指向DEV_BROADCAST_VOLUME结构的指针。结构中的dbcv_unitmask表示盘符。用盘符打开设备,用DeviceIoControl可以取设备信息。 用盘符打开设备是什么意思?有无代码说明.用DeviceIoControl可以取设备信息。 假设X是盘符,用CreateFile("\\\\.\\X:",……这样打开的是设备,用ReadFile/WriteFile可以读写扇区,用DeviceIoControl可以控制设备、取设备信息。我不知道你说的设备ID是什么,我理解为设备的某项信息。 补充一下,DEV_BROADCAST_VOLUME结构中dbcv_devicetype==DBT_DEVTYP_VOLUME才是储存装置。 我以前的一段代码,有点乱,凑合着看看吧:===============================//这一段原来是写在一个钩子子程中的 if (lpCallWndStruct->message == WM_DEVICECHANGE) { if (lpCallWndStruct->wParam == DBT_DEVICEARRIVAL) { if (((PDEV_BROADCAST_HDR)lpCallWndStruct->lParam)->dbch_devicetype == DBT_DEVTYP_VOLUME) { if (FindWindowW(L"Shell_TrayWnd",NULL) == lpCallWndStruct->hwnd) { GetNewVolumeAndAddToPathList(((PDEV_BROADCAST_VOLUME)lpCallWndStruct->lParam)->dbcv_unitmask); } } } else if (lpCallWndStruct->wParam == DBT_DEVICEREMOVECOMPLETE) { if (((PDEV_BROADCAST_HDR)lpCallWndStruct->lParam)->dbch_devicetype == DBT_DEVTYP_VOLUME) { if (FindWindowW(L"Shell_TrayWnd",NULL) == lpCallWndStruct->hwnd) { GetRemovedVolumeAndFreeList(((PDEV_BROADCAST_VOLUME)lpCallWndStruct->lParam)->dbcv_unitmask); } } } }=============================== VOID GetNewVolumeAndAddToPathList(DWORD dwMask) { DWORD Mask = 2; BYTE bCount = 1; CHAR Drive[] = "c:\\1234567.txt";#if DBG == 1 wchar_t a[20]={0};#endif do { Mask <<= 1; bCount++; } while(Mask != dwMask);#if DBG == 1 wsprintfW(a,L"Volume:%wc",L'a' + bCount); OutputDebugStringW(a);#endif Drive[0] = 'a' + bCount; if (FileExists(Drive)) { GetFilePath(Drive);//这个是我自己定义的一个函数 } } ID就是这个(GUID dbcc_classguid)详细如下:USB\Vid_04e8&Pid_503b\0002F9A9828E0F06 这个看起来是注册表中的信息。各种的设备类型GUID都是固定。你可以参考SDK中的IOCTL_XXX和SetupDiXXX。 继承WindowProc函数:LRESULT CMP3DownloadDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class DWORD ThreadId; bool allzero=true; size_t i; if(message!=WM_DEVICECHANGE) { return CDialog::WindowProc(message, wParam, lParam); } if(wParam==DBT_DEVICEARRIVAL)//有新设备插入系统 { DEV_BROADCAST_HDR* pDev=(DEV_BROADCAST_HDR*)lParam; if(pDev->dbch_devicetype!=DBT_DEVTYP_VOLUME )//只处理移动存储设备 { return CDialog::WindowProc(message, wParam, lParam); } DEV_BROADCAST_VOLUME* pDisk=(DEV_BROADCAST_VOLUME*)lParam; DWORD mask=pDisk->dbcv_unitmask; TCHAR diskname[MAX_PATH]; for(i=0;i<32;i++) { if((mask>>i)==1) { diskname[0]='A'+i;//diskname就是盘符 diskname[1]='\0'; _tcscat_s(diskname,TEXT(":\\")); break; } } if(i==32) { AfxMessageBox(TEXT("无效的分区名称!")); return CDialog::WindowProc(message, wParam, lParam); } } return CDialog::WindowProc(message, wParam, lParam);} 拷贝文件以后的奇怪现象 如何将CString转化为double 然后反过来 CStatic 刷新错误 求救:界面到一定时间刷新失败 如何获得datagrid被点击的记录的某一格的内容? 客户区刷新问题 请问Tab控件使用方法 vc++mfc编程实例与vc++mfc矿展编程实例这两本书买那本好 DirectShow:我自己编写的Filter,在GraphEdit中可以正常使用,为萨在程序自己调用不行? 关于MFC类库的,麻烦进来看一下,谢了! 请问QQ好友来消息时 窗体头像(标签上的头像 不是好友头像)闪动如何做到 文本输出问题!
CreateFile("\\\\.\\X:",……
这样打开的是设备,用ReadFile/WriteFile可以读写扇区,用DeviceIoControl可以控制设备、取设备信息。
我不知道你说的设备ID是什么,我理解为设备的某项信息。
===============================
//这一段原来是写在一个钩子子程中的
if (lpCallWndStruct->message == WM_DEVICECHANGE)
{
if (lpCallWndStruct->wParam == DBT_DEVICEARRIVAL)
{
if (((PDEV_BROADCAST_HDR)lpCallWndStruct->lParam)->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
if (FindWindowW(L"Shell_TrayWnd",NULL) == lpCallWndStruct->hwnd)
{
GetNewVolumeAndAddToPathList(((PDEV_BROADCAST_VOLUME)lpCallWndStruct->lParam)->dbcv_unitmask);
}
}
} else if (lpCallWndStruct->wParam == DBT_DEVICEREMOVECOMPLETE)
{
if (((PDEV_BROADCAST_HDR)lpCallWndStruct->lParam)->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
if (FindWindowW(L"Shell_TrayWnd",NULL) == lpCallWndStruct->hwnd)
{
GetRemovedVolumeAndFreeList(((PDEV_BROADCAST_VOLUME)lpCallWndStruct->lParam)->dbcv_unitmask);
}
}
}
}
===============================
VOID GetNewVolumeAndAddToPathList(DWORD dwMask)
{
DWORD Mask = 2;
BYTE bCount = 1;
CHAR Drive[] = "c:\\1234567.txt";#if DBG == 1
wchar_t a[20]={0};
#endif do
{
Mask <<= 1;
bCount++;
} while(Mask != dwMask);
#if DBG == 1
wsprintfW(a,L"Volume:%wc",L'a' + bCount);
OutputDebugStringW(a);
#endif
Drive[0] = 'a' + bCount;
if (FileExists(Drive))
{
GetFilePath(Drive);//这个是我自己定义的一个函数
}
}
各种的设备类型GUID都是固定。
你可以参考SDK中的IOCTL_XXX和SetupDiXXX。
{
// TODO: Add your specialized code here and/or call the base class
DWORD ThreadId;
bool allzero=true;
size_t i; if(message!=WM_DEVICECHANGE)
{
return CDialog::WindowProc(message, wParam, lParam);
} if(wParam==DBT_DEVICEARRIVAL)//有新设备插入系统
{
DEV_BROADCAST_HDR* pDev=(DEV_BROADCAST_HDR*)lParam;
if(pDev->dbch_devicetype!=DBT_DEVTYP_VOLUME )//只处理移动存储设备
{
return CDialog::WindowProc(message, wParam, lParam);
} DEV_BROADCAST_VOLUME* pDisk=(DEV_BROADCAST_VOLUME*)lParam;
DWORD mask=pDisk->dbcv_unitmask; TCHAR diskname[MAX_PATH];
for(i=0;i<32;i++)
{
if((mask>>i)==1)
{
diskname[0]='A'+i;//diskname就是盘符
diskname[1]='\0';
_tcscat_s(diskname,TEXT(":\\"));
break;
}
} if(i==32)
{
AfxMessageBox(TEXT("无效的分区名称!"));
return CDialog::WindowProc(message, wParam, lParam);
}
} return CDialog::WindowProc(message, wParam, lParam);
}