VC实现自动监测光驱状态的改变

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;
}

时间: 2024-09-26 12:33:03

VC实现自动监测光驱状态的改变的相关文章

状态同步-如果同步一个状态经常改变的设备

问题描述 如果同步一个状态经常改变的设备 本人有两个设备,一个是主设备,另一个是冗余设备,设备靠IP网络对外提供服务,客户会经常操作这个设备,也就是设备的状态会经常的改变,并且设备的状态还很多,请问各位大神,有没有什么相对较好的办法,使冗余设备与主设备的状态能够较好的同步吗? 我原本想将所有的状态保存下来,但是由于状态经常改变,频繁的IO操作肯定会影响性能. 解决方案 试试zookeeper

android-Android中点击 ImageButton后状态没有改变

问题描述 Android中点击 ImageButton后状态没有改变 我的问题是点击ImageButton后图像也不会改变.当我单击或者触摸按钮仍然显示相同的图像.这是代码片段: <selectorxmlns:android=""http://schemas.android.com/apk/res/android""><item android:state_focused=""true"" android:s

辜胜阻:支持新兴产业的VC和PE需要三个改变

ChinaVenture北京时间6月4日上午消息,民建中央副主席辜胜阻在今日于深圳举办的十二届中国风险投资论坛上发表演讲,他指出,7大战略性新兴产业里,与应对气候变化相关的新能源.节能环保.电动汽车的低碳产业,与物联网.智慧地球.云计算等等为代表的信息产业,都将成为超过10万亿元的支柱性大产业.他认为,发展新兴产业需要两轮驱动,需要政府和市场的两只手协调,天使,风投以及私募股权基金是新兴产业的三大孵化器. 辜胜阻认为,新兴产业的金融创新发展需要以出口为导向,要打开多层次的资本市场,迫切需要大力发

iOS实时监控网络状态的改变_IOS

在网络应用中,有的时候需要对用户设备的网络状态进行实时监控,有两个目的:  (1)让用户了解自己的网络状态,防止一些误会(比如怪应用无能)  (2)根据用户的网络状态进行智能处理,节省用户流量,提高用户体验  WIFI网络:自动下载高清图片  4G/3G网络:只下载缩略图  没有网络:只显示离线的缓存数据   常用的有以下两种方法:  (1).使用苹果观法提供的检测iOS设备网络环境用的库 Reachablity  (2).使用AFN框架中的AFNetworkReachabilityManage

需要做一个类似扫描二维码付款的页面,服务器状态一旦改变立即通知客户端

问题描述 服务器状态改变,能够立马主动通知客户端,而不是客户端在不停地轮询.请问采用什么方式,简单查了下资料,主要是用长连接的方式,但是没有具体的例子.请问哪位做过?麻烦分享一下,感谢! 解决方案 解决方案二:了解下SignalR--解决方案三:SignalR这个,按照文章中写的一步一步,最后提示如下错误:PM>install-packageSignalR.SampleInstall-Package:无法找到程序包"SignalR.Sample".所在位置行:1字符:16+ins

用VC++控制多光驱

对于初学者,编写CD播放器不妨为一种入门的捷径.CD播放器的核心在于MCI命令,而在各种媒体上介绍MCI命令如何使用的文章比比皆是,因此我暂且对其略过不谈.在这儿,我着重向大家介绍一个比较重要的技术--多光驱的支持. 人们的机器上的光驱往往不止一个,有普通的CDROM.有CDR.有DVD,还有穷人使用的虚拟光驱:).这样一来,对于编写多媒体软件的程序员就出了个难题:如何能在软件中加入多光驱的支持.要解决这个问题,首先要学会两个API函数,其目的是获得目标电脑的光驱数. GetLogicalDri

radio button-【Android】自定义RadioButton,请问如何改变选中状态的图片大小?

问题描述 [Android]自定义RadioButton,请问如何改变选中状态的图片大小? 在点击按钮时,按钮被选中状态的图片要高出一些,请问该如何实现? 解决方案 等我会实验室,现在在上课 解决方案二: android 自定义 radiobutton 文字颜色随选中状态而改变android 自定义 radiobutton 文字颜色随选中状态而改变android 自定义 radiobutton 文字颜色随选中状态而改变 解决方案三: 准备两套图片,一张正常的,一张点击之后大的,点击时切换就可以了

VC/MFC 编程技巧大总结

 1 toolbar默认位图左上角那个点的颜色是透明色,不喜欢的话可以自己改. 2 VC++中 WM_QUERYENDSESSION WM_ENDSESSION 为系统关机消息. 3 Java学习书推荐:<java编程思想> 4 在VC下执行DOS命令 a. system("md c:\\12"); b. WinExec("Cmd.exe /C md c:\\12", SW_HIDE); c. ShellExecute ShellExecute(NULL

[译] iOS 响应式编程:Swift 中的轻量级状态容器

本文讲的是[译] iOS 响应式编程:Swift 中的轻量级状态容器, 原文地址:Reactive iOS Programming: Lightweight State Containers in Swift 原文作者:Tyler Tillage 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:deepmissea 校对者:FlyOceanFish iOS 响应式编程:Swift 中的轻量级状态容器 事物的状态 在客户端架构如何工作上,每一个 iOS