有很多软件都有开关光驱的功能..但是在 "开/关" 在一个按钮中时就要判断光驱是开还是关.如果用户操作时,即用软件,又用手动控制光驱,就有获得光驱当前是"打开"还是"关闭"状态的必要..以下代码加入LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
程序在开关光驱的过程中没有反应.. PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
      char szMsg[80];
 case DBT_DEVICEARRIVAL:
         // See if a CD-ROM or DVD was inserted into a drive.
         if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
         {
            PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;            if (lpdbv -> dbcv_flags & DBTF_MEDIA)
            {
               wsprintf (szMsg, "Drive %c: arrived\n",
                         FirstDriveFromMask(lpdbv ->dbcv_unitmask));               MessageBox (hwnd, szMsg, "WM_DEVICECHANGE", MB_OK);
            }
         }
        break;     case DBT_DEVICEREMOVECOMPLETE:
        // See if a CD-ROM was removed from a drive.
        if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
        {
           PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;           if (lpdbv -> dbcv_flags & DBTF_MEDIA)
           {
              wsprintf (szMsg, "Drive %c: was removed\n",
                        FirstDriveFromMask(lpdbv ->dbcv_unitmask));              MessageBox (hwnd, szMsg, "WM_DEVICECHANGE", MB_OK);
           }
        }
        break;谢谢!

解决方案 »

  1.   

    不知道有没有什么简单点的办法....
    代码:
    char FirstDriveFromMask (ULONG unitmask)
       {
          char i;      for (i = 0; i < 26; ++i)
          {
             if (unitmask & 0x1)
                break;
             unitmask = unitmask >> 1;
          }      return (i + 'A');
       }
      

  2.   

    mciSendString
    The mciSendString function sends a command string to an MCI device. The device that the command is sent to is specified in the command string. MCIERROR mciSendString(
      LPCTSTR lpszCommand,  
      LPTSTR lpszReturnString,  
      UINT cchReturn,       
      HANDLE hwndCallback   
    );使用MS提供的多媒体控制API可以非常容易地实现此功能。有两种方法,分别使用mciSendCommand, mciSendString1. 使用mciSendCommand
    MCIDEVICEID mciID;MCI_OPEN_PARMS OpenParms;//光驱的设备名
    OpenParms.lpstrDeviceType = "cdaudio";//打开此设备
    mciSendCommand (NULL, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE,
    (DWORD)LPVOID) &OpenParms);//得到设备ID
    mciID = mciGetDeviceID(OpenParms.lpstrDeviceType);//打开光驱门
    //将下句中的MCI_SET_DOOR_OPEN更改为MCI_SET_DOOR_CLOSED即为关闭光驱门
    mciSendCommand(mciID, MCI_SET, MCI_WAIT | MCI_SET_DOOR_OPEN, NULL);
    2. 使用mciSendString,这种方法更为简便
    //打开光驱门
    //将此语句中的open更改为close即为关闭光驱的门
    mciSendString( "set cdaudio door open", NULL, 0, NULL);
    http://www.china-askpro.com/msg4/qa10.shtml
      

  3.   

    转载:-
    用VC实现自动监测光驱状态的改变  
     
     
    目前有许多的商业软件特别是一些音频、视频播放软件中都带有自动监测光驱的弹出和送入的状态,然后进行自动播放的功能。本文介绍的小软件演示了一种自动识别光驱弹出和送入状态的能力,并且可以判断出当前的光驱中是否有Windows系统可识别的CDROM碟片。程序实现过程中利用了Windows的WM_DEVICECHANGE消息和Windows系统广播机制来达到自动监测光驱状态改变的目的。一、实现原理
    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;}三、结束语
    本文介绍了一种自动判断光驱状态改变的方法。通过对该方法进行扩展,可以应用到任何外设的状态改变监测应用中去。WM_DEVICECHANGE消息中提供了丰富的事件类型,还可以支持用户自定义的事件类型,通过处理这些事件可以编写出对外部设备进行处理的更加复杂的应用。以上程序在Windows98和Visual C++ 6.0环境下编译通过。
      

  4.   

    WM_DEVICECHANGE消息 在Win2003中反应很慢..且有时没反应..
      

  5.   

    用MCI指令可以的!!!你自己去查查
    http://community.csdn.net/Expert/topic/2913/2913921.xml?temp=.9959375
      

  6.   

    说了用MCI指令可以的,你自己去查查!!
      

  7.   

    to sohou(大秦之刃) :
      要是可以:
      你写几行代码出来看看...
      我这样都不行.///////////光驱开关状态////////////////////////
    DWORD  GetCDROMStatus(HWND  m_hMainWnd) 
    {
    MCI_OPEN_PARMS mciOpenParms;
    MCI_STATUS_PARMS mciStatusParms;
    mciStatusParms.dwCallback = (DWORD) m_hMainWnd;
    mciStatusParms.dwItem = MCI_STATUS_READY;
    mciStatusParms.dwReturn = 0; mciSendCommand(mciOpenParms.wDeviceID, MCI_STATUS, 
                MCI_STATUS_ITEM, (DWORD) &mciStatusParms); return mciStatusParms.dwReturn;
    }
      

  8.   

    这也是我一直想知道的难点啊:期待中>>>>>>>
      

  9.   

    不知道是不是这个?
    mcisendstring('status cdaudio ready wait',nil,0,handle)?你可以查一下