工作需要,需要随时检测U盘的插入或拔出状态,然后根据状态做出相关操作。在网上搜索到下列方法:
今天一位老兄要我帮忙做一个软件,需要把在U盘插入USB接口激活之后自动把U盘里的内容拷贝到硬上。拷贝文件不难,麻烦的就是不知道怎么检测U盘是否激活,激活后又是哪个盘符。
google了一下,在MSDN上看了几个例子,找到了检测U盘插入,并确定其盘符的方法。
下面给出窗口的回调函数:
- LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_CREATE:/*初始化*/
- MessageBox(hWnd, "go!", "405 Studio", MB_OK);
- break;
- case WM_DEVICECHANGE:
- if(wParam == DBT_DEVICEARRIVAL) //设备激活
- {
- PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
- PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
- char szMsg[80];
- wsprintf (szMsg, "Drive %c: Media has arrived./n",
- FirstDriveFromMask(lpdbv ->dbcv_unitmask));
- MessageBox (hWnd, szMsg, "WM_DEVICECHANGE", MB_OK);
- }
- break;
- default:
- return DefWindowProc (hWnd, message, wParam, lParam) ;
- }
- return 0;
- }
原理很简单检测U盘是否被插入是通过监听WM_DEVICECHANGE消息来实现的。18,19行是从WM_DEVICECHANGE的lParam里获取盘符。
FirstDriveFromMask是一个用返回盘符(A,B,C ....)的简单函数
- char FirstDriveFromMask (ULONG unitmask)
- {
- char i;
- for (i = 0; i < 26; ++i)
- {
- if (unitmask & 0x1)
- break;
- unitmask = unitmask >> 1;
- }
- return (i + 'A');
- }
具体是哪个盘符的,我这边不太关系,主要是需要截获U盘插拔消息WM_DEVICECHANG,然后进行相关处理。最终在PreTranslateMessage(MSG* pMsg)里if (WM_DEVICECHANGE == pMsg->message)判断里来进行的处理。
至此,问题解决。
上述方式在win xp下运行是完全没问题的,可是在Win7或Vista下却根本没有WM_DEVICECHANG消息,在网络搜索后发现是由于win7的安全机制引起,于是采用下述方式来实现:
- #include <windows.h>
- #include <ShlObj.h>
- #pragma comment(lib, "shell32.lib")
- #define WM_SHNOTIFY WM_USER + 1001
- BEGIN_MESSAGE_MAP(CTvPlayerDlg, CDialog)
- ON_MESSAGE(WM_SHNOTIFY, &CTvPlayerDlg::OnSHWinProc)
- END_MESSAGE_MAP()
- //OnSHWinProc
- RESULT OnSHWinProc(WPARAM wParam, LPARAM lParam)
- {
- int res = CheckCard();
- if(res != TRUE)
- {
- //退出程序
- }
- return 0;
- }
在Win7 64bit 下验证OK