解决方案 »

  1.   

    http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=175438
      

  2.   

    我帮你看了,mciSendCommand传入MCI_STATUS可以检测,但普遍反映不好用。
    不过光驱打开或者闭合的时候,系统就会向各个进程广播一条WM_DEVICECHANGE消息,若是闭合,则
    wParam是DBT_DEVICEARRIVAL,打开就是DBT_DEVICEREMOVECOMPLETE,你试试捕获这个消息的参数试试。我要出去玩,不试了。
      

  3.   

    private function isDoorOpen() as Boolean
        dim iRet as long
        iRet=MessageBox("你的光驱门是打开着的吗?",vbYesNo)
        if iRet=vbYes then
              isDoorOpen = true
        else
              isDoorOpen = false
        end if
    end function
    just fun :))
      

  4.   

    你的问题win系统不能给你答复。最简单的例子我的光驱先锋的DVD,吸入式的,没门,你让windows咋办?
      

  5.   

    VBAHZ(凌云(E文词汇量580)) ( ) 信誉:100  2004-11-06 01:35:00  得分: 0  
     
     
       即使没门的光驱,也肯定有一个部件,能感知是否有东西(类似光盘状)进来,然后就会锁定,开始驱动马达,测试是否为有效光盘。
    对于普通光驱,至少能判断门有没有锁定(关上),然后才测试盘片种类。
    任何光驱决不会先驱动马达,看有没有盘,再判断面板有没有锁定的,否则如果为了测试有无碟片FSO就可以办到何必如此费事  
     
      

  6.   

    狂倒!
    To sunsatan(Solomon) :
    只问你一句,光驱在啥状态下才允许驱动马达的?难道门开着也行?这个状态是如何确定的?
    总有一个电子信号吧,难道是FSO给它的?现在只是要取得允许驱动马达的标志信号而已!(这时FSO还没生呢...)
      

  7.   

    '试试这个,在Win2000下测试没问题
    Option Explicit
    Private Declare Function GetVolumeInformation Lib _
            "kernel32" Alias "GetVolumeInformationA" _
            (ByVal lpRootPathName As String, _
            ByVal lpVolumeNameBuffer As String, _
            ByVal nVolumeNameSize As Long, _
            lpVolumeSerialNumber As Long, _
            lpMaximumComponentLength As Long, _
            lpFileSystemFlags As Long, _
            ByVal lpFileSystemNameBuffer As String, _
            ByVal nFileSystemNameSize As Long) As LongPrivate Declare Function GetDriveType Lib "kernel32" _
            Alias "GetDriveTypeA" (ByVal nDrive As String) As Long  Const DRIVE_CDROM = 5
    Sub aaa()    Dim VolName   As String, FSys    As String, erg    As Long
        Dim VolNumber   As Long, MCM    As Long, FSF    As Long
        Dim Drive   As String, DriveType    As Long
        VolName = Space(127)
        FSys = Space(127)
        Drive = "M:\"    'Enter  the  driverletter  you  want
        DriveType& = GetDriveType(Drive$)
        erg& = GetVolumeInformation(Drive$, VolName$, 127&, _
               VolNumber&, MCM&, FSF&, FSys$, 127&)
        Print "·ÖÇøÃû³Æ:" & vbTab & VolName$
        Print "ÐòÁкÅ:" & vbTab & VolNumber&
        Print "×î´óÎļþÃû³Æ³¤:" & vbTab & vbTab & MCM&
        Print "Îļþϵͳ±êÖ¾:" & vbTab & vbTab & FSF&
        Print "ÎļþϵͳÃû³Æ:" & vbTab & FSys$
        Print "ÀàÐÍ:" & vbTab & DriveType&;
        'Is  the  drive  a  CDROM,  if  so,  check  for  a  CD
        If DriveType& = DRIVE_CDROM Then
            Print "  (CDROM,  ";
            If erg& = 0 Then
                Print "ûÓР CD  )"
              Else
                Print "ÓР CD  )"
            End If
          Else
            Print "  (·Ç  CDROM)"
        End If
    End Sub
    Sub ShowDriveList()
        Dim fs, d, dc, s, n, t
        Set fs = CreateObject("Scripting.FileSystemObject")
        Set dc = fs.Drives
        For Each d In dc
            Select Case d.DriveType
              Case 0:   t = "Unknown"
              Case 1:   t = "Removable"
              Case 2:   t = "Fixed"
              Case 3:   t = "Network"
              Case 4:   t = "CD-ROM"
              Case 5:   t = "RAM  Disk"
            End Select
            s = "Drive  " & d.DriveLetter & ":  -  " & t
            If d.IsReady Then
                s = s & vbCrLf & "Drive  is  Ready."
              Else
                s = s & vbCrLf & "Drive  is  not  Ready."
            End If
            MsgBox s
        Next
    End SubPrivate Sub Command1_Click()
        aaa
    End Sub
      

  8.   

    '上面有乱码,看这个
    Option Explicit
    Private Declare Function GetVolumeInformation Lib _
            "kernel32" Alias "GetVolumeInformationA" _
            (ByVal lpRootPathName As String, _
            ByVal lpVolumeNameBuffer As String, _
            ByVal nVolumeNameSize As Long, _
            lpVolumeSerialNumber As Long, _
            lpMaximumComponentLength As Long, _
            lpFileSystemFlags As Long, _
            ByVal lpFileSystemNameBuffer As String, _
            ByVal nFileSystemNameSize As Long) As LongPrivate Declare Function GetDriveType Lib "kernel32" _
            Alias "GetDriveTypeA" (ByVal nDrive As String) As Long  Const DRIVE_CDROM = 5
    Sub aaa()    Dim VolName   As String, FSys    As String, erg    As Long
        Dim VolNumber   As Long, MCM    As Long, FSF    As Long
        Dim Drive   As String, DriveType    As Long
        VolName = Space(127)
        FSys = Space(127)
        Drive = "M:\"    'Enter  the  driverletter  you  want
        DriveType& = GetDriveType(Drive$)
        erg& = GetVolumeInformation(Drive$, VolName$, 127&, _
               VolNumber&, MCM&, FSF&, FSys$, 127&)
        Print "分区名称:" & vbTab & VolName$
        Print "序列号:" & vbTab & VolNumber&
        Print "最大文件名称长:" & vbTab & vbTab & MCM&
        Print "文件系统标志:" & vbTab & vbTab & FSF&
        Print "文件系统名称:" & vbTab & FSys$
        Print "类型:" & vbTab & DriveType&;
        'Is  the  drive  a  CDROM,  if  so,  check  for  a  CD
        If DriveType& = DRIVE_CDROM Then
            Print "  (CDROM,  ";
            If erg& = 0 Then
                Print "没有  CD  )"
              Else
                Print "有  CD  )"
            End If
          Else
            Print "  (非  CDROM)"
        End If
    End Sub
    Sub ShowDriveList()
        Dim fs, d, dc, s, n, t
        Set fs = CreateObject("Scripting.FileSystemObject")
        Set dc = fs.Drives
        For Each d In dc
            Select Case d.DriveType
              Case 0:   t = "Unknown"
              Case 1:   t = "Removable"
              Case 2:   t = "Fixed"
              Case 3:   t = "Network"
              Case 4:   t = "CD-ROM"
              Case 5:   t = "RAM  Disk"
            End Select
            s = "Drive  " & d.DriveLetter & ":  -  " & t
            If d.IsReady Then
                s = s & vbCrLf & "Drive  is  Ready."
              Else
                s = s & vbCrLf & "Drive  is  not  Ready."
            End If
            MsgBox s
        Next
    End SubPrivate Sub Command1_Click()
        aaa
    End Sub
      

  9.   

    只要不放盘,不管门是开还是关,砸掉也好,吃掉也好,永远显示为False,那有啥用???
    虽然与本主题不符,还是谢谢各位关心,继续关注!PWin98+VB5
      

  10.   

    不好意思,我理解错了。
    这是C代码:'MCI_OPEN_PARMS lpOpen;
    'MCI_STATUS_PARMS StatusParms;
    'StatusParms.dwItem = MCI_STATUS_MODE;
    'unsigned int wDeviceID;
    'lpOpen.lpstrDeviceType =  "cdaudio";
    'if(mciSendCommand(NULL,MCI_OPEN,MCI_WAIT|MCI_OPEN_TYPE|MCI_OPEN_SHAREABLE,(DWORD)&lpOpen))
    '{
    '    MessageBox(NULL,"光驱设备打开错误!","错误!",MB_OK);
    '    return 0;
    '}
    'wDeviceID = lpOpen.wDeviceID;
    '
    'if(mciSendCommand(wDeviceID,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID)&StatusParms))
    '        return 0;
    'if(StatusParms.dwReturn == MCI_MODE_OPEN )//MCI_MODE_OPEN 门还是设备打开
    '{
    '    mciSendCommand(wDeviceID,MCI_SET,MCI_SET_DOOR_CLOSED,NULL);
    '}
    'Else
    '{
    '    mciSendCommand(wDeviceID,MCI_SET,MCI_SET_DOOR_OPEN,NULL);
    '}
    'mciSendCommand(wDeviceID,MCI_CLOSE,NULL,NULL);
    'return 0;这是Dephic 程序' program cdinout;
    '    uses mmSystem;
    '
    '    Var
    '    MCIO : TMCI_Open_Parms;
    '    MCIS : TMCI_Status_Parms;
    '
    '    begin
    '
    '    MCIO.lpstrDeviceType := PChar(MCI_DEVTYPE_CD_AUDIO);
    '    if mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE or MCI_OPEN_TYPE_ID or
    '     MCI_OPEN_SHAREABLE, LongInt(@MCIO) )= 0 then
    '     begin
    '     MCIS.dwItem := MCI_STATUS_READY;
    '     mciSendCommand(MCIO.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM
    '     or MCI_WAIT, LongInt(@MCIS));
    '     If MCIS.dwReturn <> 0 Then
    '     mciSendCommand(MCIO.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0)
    '     Else
    '     mciSendCommand(MCIO.wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
    '     mciSendCommand(MCIO.wDeviceID, MCI_CLOSE, MCI_WAIT, 0);
    '     end;
    '    end.我改成VB后,不好使Private Const MCI_OPEN = &H803
    Private Const MCI_OPEN_TYPE = &H2000&
    Private Const MCI_OPEN_TYPE_ID = &H1000&
    Private Const MCI_OPEN_SHAREABLE = &H100&
    Private Const MCI_STATUS_READY = &H7&
    Private Const MCI_STATUS = &H814
    Private Const MCI_STATUS_ITEM = &H100&
    Private Const MCI_WAIT = &H2&
    Private Const MCI_SET = &H80D
    Private Const MCI_SET_DOOR_OPEN = &H100&
    Private Const MCI_SET_DOOR_CLOSED = &H200&
    Private Const MCI_CLOSE = &H804
    Private Const MCI_DEVTYPE_CD_AUDIO = 516
    Private Type MCI_OPEN_PARMS
            dwCallback As Long
            wDeviceID As Long
            lpstrDeviceType As String
            lpstrElementName As String
            lpstrAlias As String
    End TypePrivate Type MCI_STATUS_PARMS
            dwCallback As Long
            dwReturn As Long
            dwItem As Long
            dwTrack As Integer
    End TypePrivate Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Long, ByVal uMessage As Long, ByVal dwParam1 As Long, dwParam2 As Any) As Long
    Private Const MCI_STRING_OFFSET = 512
    Private Const MCI_MODE_OPEN = (MCI_STRING_OFFSET + 18)Private Sub cmdTest_Click()
        Dim MCIO As MCI_OPEN_PARMS
        Dim MCIS As MCI_STATUS_PARMS
        Dim lFlags As Long    MCIO.lpstrDeviceType = "cdaudio"
        MCIO.lpstrElementName = "M:"
        
        lFlags = MCI_OPEN_TYPE Or MCI_OPEN_ELEMENT Or MCI_OPEN_SHAREABLE
        
        If mciSendCommand(0, MCI_OPEN, lFlags, MCIO) = 0 Then
          MCIS.dwItem = MCI_STATUS_READY
          Call mciSendCommand(MCIO.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM Or MCI_WAIT, MCIS)
          MsgBox Str(MCIS.dwReturn)
    '      If MCIS.dwReturn <> 0 Then
    '         'Call mciSendCommand(MCIO.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0)
    '         MsgBox "光驱门关闭"
    '      Else
    '         MsgBox "光驱门打开"
    '         'Call mciSendCommand(MCIO.wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0)
    '         'Call mciSendCommand(MCIO.wDeviceID, MCI_CLOSE, MCI_WAIT, 0)
    '      End If
        End If
    end sub
      

  11.   

    If 检查门()=True Then
      MsgBox("门开着")
    Else
      MsgBox("门关着")
    End IfFunction 检查门() As Boolen
    '问如何编这个函数!!!
    '八个字!!!还不明白???还编程?!
    '光驱里没盘时,并不等于门一定开着(但有盘时一定是关着的)。
    End Function
      

  12.   

    hao dong xi ! ding!!!
      

  13.   

    我是一个学电子的,目前的工作是维修电工。
    对于这个问题,我知道的事实是:光驱内有一个专用的控制芯片,用于管理光驱的“基本功能”,如放CD,进出盒,驱动激光头进行读写等功能。由这个芯片组成的电路叫“控制/伺服电路”。而这个电路有没有对“光驱内是否有光盘”这个“信号”进行硬件上的接口性的设计,我就不知道了。
    至少我从小学玩电脑到现在,共十多年了(今年我22),还没有见过有什么程序能给出“光驱内有无光盘”的提示。这样的功能,在光驱没有接IDE时,一样可以正常工作。而放CD这个功能,也是一样。进/出盒也是。只是,这些功能当中,有没有全部设计为“可编程控制”的呢?我认为,“有无光盘”这个功能应该是没有的。要不,你放一个暴花的盘进去,然后双击光盘,系统应该是提示“此光盘已损坏,无法读取”,而不是现在的“请插入光盘”!!!!
      

  14.   

    http://www.tiantiansoft.com/Article_Show.asp?ArticleID=97
      

  15.   

    演示了一种自动识别光驱弹出和送入状态的能力,并且可以判断出当前的光驱中是否有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;
    }
      

  16.   

    小马哥,请看清楚题目,有没有盘关我啥事?俺啥时说过查盘的问题?!这次彻底晕倒!
    发誓最后一次解释了,各位再不理解的话,拜托先找个小学生来解释一下题目吧。
    (并非针对个人,只是实在是失望,对于编程者来说,连别人的要求都无法理解,那怎么编的出人家要的东东?)【问】决不要开关门!
    解释:不好意思,原题目写了白字(惭愧),这句的意思就是俺不是想做开关光驱门的软件!也不管有无盘,
    解释:光驱中有无盘,我根本不想了解,事实上也不可能全知!(鬼才知道,当光驱门开着的时候,你有没有放盘,或放杯子在光驱托盘上,要是哪个软件能做到:显示出,现在光驱中无盘,放的是亚马逊丛林什么纲什么科什么目什么属的什么食人蚁!???嗯,我出一百块买下,呵呵,当个生物鉴别器也不错^-^ )只想显示当前光驱门的状态,
    解释:多光驱先免了吧,省得大家看不明白。这句的解释嘛,才是最关键的,嗯,实在想不出再白的解释了,请无法理解的朋友找个大于10岁的小朋友解释一下,或许更明白吧
    (动词:显示。显示啥?光驱门!光驱门的啥?状态!啥状态?是开还是关!那盘呢?解释到饿,吃了!那现在干啥?显示,显示啥?光驱门!)如何做?
    解释:唉,这也要解释?实在how do? /How to do?
      

  17.   

    To 小马:
    原来你是学电子的,俺也喜欢呢,只是——不懂诶(惭愧)。
    俺只想说:光驱凭啥驱动光头检测是否为暴花的盘?
    不会是在门开着的时候就去转两圈吧?
    当然啦,可以在光驱拆下门的时候,仍让它转,但也要去动个机关,模拟一下门关上吧?
    呵呵,若你全拆了,只拿个马达套在盘上让它转,那无语 ^-!!至于那个感应门已关上的信号,能否传给操作系统,俺就真不知道了(知道的话还问啥?)
    老兄能否帮忙看一下资料,是否系统真的无法收到这个信号?那俺也就死心了,谢谢!
    To starsoulxp(星魂.NET) :
    谢谢题点,只是俺老菜一个(俺也不想的,所以现在俺尽量少吃菜多吃肉 ^0^)
    看不懂C的代码,能否帮忙改成VB的?先谢谢啦 :)
      

  18.   

    晕.....实在是不好意思,真的是没有注意看过题!!!并不是理解有问题,也不是你的题目写得不清楚,而是我根本就没看题.....汗...至于光驱开关门的问题嘛...我觉得在“开门”和“关门”时有一个信号,是的确传送到了系统里的。理由如下:  我现在的机器是WIN98+WIN2000+WIN2003+LINUX,平时用2003用得最多,玩游戏用98。在2003下,我每次把光盘驱门关上时,在这个“关门”的过程中(门还没关上),系统已经有反应,具体表现为光标上多了一个“小光碟”图形!!
      而打开光驱门时,光标一样是有反应的。所以,可以根据这个得出,在进/出盒时,一定是有事件发生,只是我们还不知道。
      

  19.   

    To  sovom(谍路) & myjian(小马) :
    //晕.....实在是不好意思,真的是没有注意看过题!!!这回看题目了吗?咋又谈开关门啦???谁说一定要拆硬盘数磁道才知道容量?
    不会看状态标签嘛!(不管是贴在盘上的,或开机后显示的,都属于状态显示)要显示光驱门的状态,难道一定要装个微动开关???
    那好吧,明天我去买一个,请你来帮我装,
    装好后,那就能实现本主题了吧?——在电脑上显示光驱门的状态!:)
      

  20.   

    可怜的楼主,我怎么感觉有人是故意打岔啊,应该都能看清楼主的意思啊~~~呵呵,大家都是闲来无聊了吧~~~我赞同DemonLoveLizzy和starsoulxp的思路!
    通过他的方法可以实现捕获盘近盘出的消息的。这样的话如果你的程序运行得比较早,在运行期间用户有弹出或关上光驱的动作的话,你的程序就可以及时地知道当前光驱门的状态。我下面这个程序可以捕获光驱门开关的动作:
    在模块中写入:Public Const GWL_WNDPROC = (-4)
    Public Const WM_DEVICECHANGE As Long = &H219
    Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPublic lpPrevWndProc As LongFunction WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If uMsg = WM_DEVICECHANGE Then
            If wParam And 4 Then
                MsgBox "光驱打开了!在下一次发现关闭之前都是开着的!"
            Else
                MsgBox "光驱关上了!在下一次发现打开之前都是关着的!"
            End If
        End If
        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
    End Function
    在窗体代码中写入:
    Private Sub Form_Load()
        lpPrevWndProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WindowProc)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        SetWindowLong Me.hwnd, GWL_WNDPROC, lpPrevWndProc
    End Sub
    唯一的弊端就是如果软件不是一直运行的,用户没有在这期间开关光驱门,那这个方法就不起作用了。不知道还有什么高招没有。
    不过我还有些“馊主意”可以作为弥补:
    刚运行时,看一下光驱中有没有盘(dir之类的方法)。如果有,这可以说明光驱是关着的。
    如果没有盘,就强行弹出光驱(mciSendString)。呵呵,光驱一弹出来后面就好办了。
      

  21.   

    我搞忘了多光驱的事情。我不知道VB里面怎么用指针好一些,所以只好用了这个比较笨的办法。楼主多参照starsoulxp的回复,他写得比较全面,我这个省略了很多东西,不是很准确。
    模块里面的改为:Public Const GWL_WNDPROC = (-4)
    Public Const WM_DEVICECHANGE As Long = &H219
    Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)Public Type DEV_BROADCAST_VOLUME
        dbcv_size As Long
        dbcv_devicetype As Long
        dbcv_reserved As Long
        dbcv_unitmask As Long
        dbcv_flags As Long
    End TypePublic lpPrevWndProc As Long
    Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If uMsg = WM_DEVICECHANGE Then
            Dim dbv As DEV_BROADCAST_VOLUME
            CopyMemory dbv, lParam, Len(dbv)
            
            Dim i As Byte, m As Long
            i = 64
            m = dbv.dbcv_unitmask
            Do While m
                i = i + 1
                m = m \ 2
            Loop
            
            If wParam And 4 Then
                MsgBox Chr(i) & ":光驱打开了!"
            Else
                MsgBox Chr(i) & ":光驱关上了!"
            End If
        End If
        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
    End Function