Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16499299
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:02:05

下载本文示例代码
  一、实现原理  Windows系统通过GDI(图形设备接口)将系统的硬件和用户可以操作的编程接口相分离,以保证系统的稳定型和安全性。当某一个设备的硬件配置发生变化时,Windows发送广播消息WM_DEVICECHANGE给相关的应用和设备驱动程序,此时在应用程序中可以截获该消息并分析其中的消息参数,先分辨当前的消息内容,然后调用不同的事件处理程序。本文中主要考虑的是光驱的弹出和送入事件,因此程序设计时只需对逻辑驱动器进行扫描,判断是哪个驱动器号发生变化即可。一般的外设(包括软、硬盘驱动器、光驱等)在Windows系统中按照逻辑上的驱动器名称进行管理,这样就屏蔽了用户和计算机硬件直接打交道。Windows中用掩码数字0代表驱动器“A”,1代表驱动器“B”,依此类推。其中每个逻辑驱动器又有0和1两种状态变化,如果驱动器一直未发生变化,则此值为0,否则置为1,一个逻辑驱动器状态可以响应多种事件,如打开、关闭、新添加、删除等事件,甚至可以响应用户自定义的事件。   本文中的程序主要是监测光驱的弹出和送入的状态改变,当应用程序启动后,弹出一个对话框,说明正在等待光驱事件的发生,此时如果将光驱弹出,应用程序会提示此时光盘驱动器已经弹出,在送入光驱之后,并且光驱中有CDROM碟片时,应用会提示光驱已经就绪。   二、程序实现  从Visual C 的IDE中的File菜单中选择New对话框,在Project属性页中选择Win32 Application,建立一个空的Win32应用程序,将StdAfx.h和StdAfx.cpp包含进来。建立一个新的对话框资源,在对话框上写上一句静态文本,“正在等待光驱事件”。下面实现监测光驱状态变化的主程序,在主程序cdchange.cpp中实现了三个函数。  第一个函数是chFirstDriveFromMask(ULONG unitmask),该函数的作用是将响应WM_DEVICECHANGE消息事件的内容(即驱动器掩码)作为输入,和系统定义的掩码相比较,从而返回发生变化事件的驱动器的逻辑名称,如“E盘”、“F盘”等。函数的源代码如下: char chFirstDriveFromMask (ULONG unitmask){ char i; for (i = 0; i < 26; i) //假设不会超过26个逻辑驱动器 {  if (unitmask & 0x1) //看该驱动器的状态是否发生了变化   break;  unitmask = unitmask >> 1; } return (i 'A');}  第二个函数是关键,它是对话框的事件处理函数,同时也是用来截获并处理Windows的WM_DEVICECHANGE事件。在该函数中首先声明了一个 PDEV_BROADCAST_HDR类型的结构变量lpdb,该结构里存储了当WM_DEVICECHANGE消息产生时的设备事件信息,它的声明在 VC98目录下面的Include目录中的dbt.h中。接着,进入事件和消息处理程序,当WM_DEVICECHANGE事件出现时,程序再判断该消息的附加消息参数以判断CDROM的事件类型。当一个设备被插入并变得可用时,系统会发送广播事件DBT_DEVICEARRIVAL,而当一个设备被除去并变得不可用时,系统会发送广播事件DBT_DEVICEREMOVECOMPLETE,根据这两种消息可以判断当前的光驱是否是开着的。处理完以上事件之后,还要检查一下光驱中是否由CDROM碟片,如有才弹出对话框表明光驱已经弹出或成功送入。同时为了防止于其他的自动识别光驱状态的应用产生冲突,本例中将暂时禁止光驱的自动播放功能。函数的源代码如下: BOOL WINAPI DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ BOOL fRet = TRUE; // 返回值 //通过响应WM_DEVICECHANGE消息得到的设备事件信息结构 PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam; //对话框消息处理 switch (uMsg) {  case WM_INITDIALOG:   fRet = TRUE;   break;   //对 WM_DEVICECHANGE 消息进行处理  case WM_DEVICECHANGE:  char szMsg[80]; // 对话框中要表示的字符串   switch (wParam)   {    //当一个设备变得被插入并变得可用时,    //系统会发送广播事件DBT_DEVICEARRIVAL    case DBT_DEVICEARRIVAL:     // 判断CDROM碟片是否已经插入到光驱中     if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME) {      PDEV_BROADCAST_VOLUME lpdbv=(PDEV_BROADCAST_VOLUME) lpdb;      //判断是否有CDROM碟片      if (lpdbv -> dbcv_flags & DBTF_MEDIA)      {       // 显示消息,获取光驱的逻辑驱动器号       wsprintf (szMsg, "驱动器 %c: 已经可用\n",chFirstDriveFromMask(lpdbv ->dbcv_unitmask));       MessageBox (hwnd, szMsg, "光驱自动监测", MB_OK |MB_ICONINFORMATION);      }     }     break;    //当一个设备变得被移走并变得不可用时,    //系统会发送广播事件DBT_ DEVICEREMOVECOMPLETE    case DBT_DEVICEREMOVECOMPLETE:     // 判断CDROM碟片是否从光驱中移走     if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME) {       PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;      if (lpdbv -> dbcv_flags & DBTF_MEDIA)      {       //显示消息,获取光驱的逻辑驱动器号       wsprintf (szMsg, "驱动器 %c: 已经弹出\n",chFirstDriveFromMask(lpdbv ->dbcv_unitmask));       MessageBox (hwnd, szMsg, "光驱自动监测", MB_OK| MB_ICONINFORMATION);      }     }     break;    }    //处理其他Windows消息   case WM_COMMAND:    int wmId, wmEvent;    wmId = LOWORD(wParam);    wmEvent = HIWORD(wParam);    switch (wmId)    {     case IDOK:      EndDialog(hwnd, 0);      break;    }   default:    fRet = FALSE;    break;  }  // 禁止光驱的AutoPlay功能  static UINT uMsgQueryCancelAutoPlay=RegisterWindowMessage("QueryCancelAutoPlay");  if (uMsg==uMsgQueryCancelAutoPlay)  {   int n = MessageBox(hwnd, "你想禁止AutoPlay功能吗?", NULL,MB_YESNO | MB_ICONQUESTION);   // 1代表取消 AutoPlay   // 0 t代表允许AutoPlay   SetDlgMsgResult(hwnd, uMsg, (n == IDYES) ? 1 : 0);   fRet = (n == IDYES) ? 1 : 0;  }  return(fRet);}  第三个函数非常简单,产生一个模式对话框。代码如下: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){ //从对话框模版资源中创建一个模式对话框 DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),NULL, DlgProc); return 0;}   一、实现原理  Windows系统通过GDI(图形设备接口)将系统的硬件和用户可以操作的编程接口相分离,以保证系统的稳定型和安全性。当某一个设备的硬件配置发生变化时,Windows发送广播消息WM_DEVICECHANGE给相关的应用和设备驱动程序,此时在应用程序中可以截获该消息并分析其中的消息参数,先分辨当前的消息内容,然后调用不同的事件处理程序。本文中主要考虑的是光驱的弹出和送入事件,因此程序设计时只需对逻辑驱动器进行扫描,判断是哪个驱动器号发生变化即可。一般的外设(包括软、硬盘驱动器、光驱等)在Windows系统中按照逻辑上的驱动器名称进行管理,这样就屏蔽了用户和计算机硬件直接打交道。Windows中用掩码数字0代表驱动器“A”,1代表驱动器“B”,依此类推。其中每个逻辑驱动器又有0和1两种状态变化,如果驱动器一直未发生变化,则此值为0,否则置为1,一个逻辑驱动器状态可以响应多种事件,如打开、关闭、新添加、删除等事件,甚至可以响应用户自定义的事件。   本文中的程序主要是监测光驱的弹出和送入的状态改变,当应用程序启动后,弹出一个对话框,说明正在等待光驱事件的发生,此时如果将光驱弹出,应用程序会提示此时光盘驱动器已经弹出,在送入光驱之后,并且光驱中有CDROM碟片时,应用会提示光驱已经就绪。   二、程序实现  从Visual C 的IDE中的File菜单中选择New对话框,在Project属性页中选择Win32 Application,建立一个空的Win32应用程序,将StdAfx.h和StdAfx.cpp包含进来。建立一个新的对话框资源,在对话框上写上一句静态文本,“正在等待光驱事件”。下面实现监测光驱状态变化的主程序,在主程序cdchange.cpp中实现了三个函数。  第一个函数是chFirstDriveFromMask(ULONG unitmask),该函数的作用是将响应WM_DEVICECHANGE消息事件的内容(即驱动器掩码)作为输入,和系统定义的掩码相比较,从而返回发生变化事件的驱动器的逻辑名称,如“E盘”、“F盘”等。函数的源代码如下: char chFirstDriveFromMask (ULONG unitmask){ char i; for (i = 0; i < 26; i) //假设不会超过26个逻辑驱动器 {  if (unitmask & 0x1) //看该驱动器的状态是否发生了变化   break;  unitmask = unitmask >> 1; } return (i 'A');}  第二个函数是关键,它是对话框的事件处理函数,同时也是用来截获并处理Windows的WM_DEVICECHANGE事件。在该函数中首先声明了一个 PDEV_BROADCAST_HDR类型的结构变量lpdb,该结构里存储了当WM_DEVICECHANGE消息产生时的设备事件信息,它的声明在 VC98目录下面的Include目录中的dbt.h中。接着,进入事件和消息处理程序,当WM_DEVICECHANGE事件出现时,程序再判断该消息的附加消息参数以判断CDROM的事件类型。当一个设备被插入并变得可用时,系统会发送广播事件DBT_DEVICEARRIVAL,而当一个设备被除去并变得不可用时,系统会发送广播事件DBT_DEVICEREMOVECOMPLETE,根据这两种消息可以判断当前的光驱是否是开着的。处理完以上事件之后,还要检查一下光驱中是否由CDROM碟片,如有才弹出对话框表明光驱已经弹出或成功送入。同时为了防止于其他的自动识别光驱状态的应用产生冲突,本例中将暂时禁止光驱的自动播放功能。函数的源代码如下: BOOL WINAPI DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ BOOL fRet = TRUE; // 返回值 //通过响应WM_DEVICECHANGE消息得到的设备事件信息结构 PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam; //对话框消息处理 switch (uMsg) {  case WM_INITDIALOG:   fRet = TRUE;   break;   //对 WM_DEVICECHANGE 消息进行处理  case WM_DEVICECHANGE:  char szMsg[80]; // 对话框中要表示的字符串   switch (wParam)   {    //当一个设备变得被插入并变得可用时,    //系统会发送广播事件DBT_DEVICEARRIVAL    case DBT_DEVICEARRIVAL:     // 判断CDROM碟片是否已经插入到光驱中     if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME) {      PDEV_BROADCAST_VOLUME lpdbv=(PDEV_BROADCAST_VOLUME) lpdb;      //判断是否有CDROM碟片      if (lpdbv -> dbcv_flags & DBTF_MEDIA)      {       // 显示消息,获取光驱的逻辑驱动器号       wsprintf (szMsg, "驱动器 %c: 已经可用\n",chFirstDriveFromMask(lpdbv ->dbcv_unitmask));       MessageBox (hwnd, szMsg, "光驱自动监测", MB_OK |MB_ICONINFORMATION);      }     }     break;    //当一个设备变得被移走并变得不可用时,    //系统会发送广播事件DBT_ DEVICEREMOVECOMPLETE    case DBT_DEVICEREMOVECOMPLETE:     // 判断CDROM碟片是否从光驱中移走     if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME) {       PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;      if (lpdbv -> dbcv_flags & DBTF_MEDIA)      {       //显示消息,获取光驱的逻辑驱动器号       wsprintf (szMsg, "驱动器 %c: 已经弹出\n",chFirstDriveFromMask(lpdbv ->dbcv_unitmask));       MessageBox (hwnd, szMsg, "光驱自动监测", MB_OK| MB_ICONINFORMATION);      }     }     break;    }    //处理其他Windows消息   case WM_COMMAND:    int wmId, wmEvent;    wmId = LOWORD(wParam);    wmEvent = HIWORD(wParam);    switch (wmId)    {     case IDOK:      EndDialog(hwnd, 0);      break;    }   default:    fRet = FALSE;    break;  }  // 禁止光驱的AutoPlay功能  static UINT uMsgQueryCancelAutoPlay=RegisterWindowMessage("QueryCancelAutoPlay");  if (uMsg==uMsgQueryCancelAutoPlay)  {   int n = MessageBox(hwnd, "你想禁止AutoPlay功能吗?", NULL,MB_YESNO | MB_ICONQUESTION);   // 1代表取消 AutoPlay   // 0 t代表允许AutoPlay   SetDlgMsgResult(hwnd, uMsg, (n == IDYES) ? 1 : 0);   fRet = (n == IDYES) ? 1 : 0;  }  return(fRet);}  第三个函数非常简单,产生一个模式对话框。代码如下: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){ //从对话框模版资源中创建一个模式对话框 DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),NULL, DlgProc); return 0;} 下载本文示例代码


VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变VC实现自动监测光驱状态的改变
阅读(80) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~