from 
http://www.xploiter.com/programming/delphi/tips4.shtml#tip37
Tip 37 
//Is there any function can detect the current status of the CDROM door, (that is, opened or closed)? //You may use the MediaPlayer for this: 
if MediaPlayer.Mode = mpOpen then 
  CDTrayOpen 
else 
  CDTrayClosed; //Another way is to trap WM_DEVICECHANGE message: procedure WMDeviceChange(var Msg: TMsg); message WM_DEVICECHANGE; procedure TForm1.WMDeviceChange(var Msg: TMsg); 
begin 
    if Msg.wParam = DBT_DEVICEREMOVEPENDING then 
        // user has started to eject CD 
        // Tell Windows it's OK. 
        Msg.Result := True; 
end; (*See also: 
  DBT_DEVICEARRIVAL  
  DBT_DEVICEREMOVECOMPLETE  Where is DBT_DEVICEREMOVEPENDING defined?  --  I can't find any hint 
of this (except in the help files.....) 
Sorry, seems that there isn't any declaration in Delphi. dbt_ 
constants are declared in dbt.h, in Delphi it would be: const 
DBT_QUERYCHANGECONFIG       = $0017; 
DBT_CONFIGCHANGED           = $0018; 
DBT_CONFIGCHANGECANCELED    = $0019; 
DBT_DEVICEARRIVAL           = $8000; 
DBT_DEVICEQUERYREMOVE       = $8001; 
DBT_DEVICEQUERYREMOVEFAILED = $8002; 
DBT_DEVICEREMOVEPENDING     = $8003; 
DBT_DEVICEREMOVECOMPLETE    = $8004; 
DBT_DEVICETYPESPECIFIC      = $8005; 
DBT_USERDEFINED             = $FFFF; 
*) 

解决方案 »

  1.   

    我也寻找了好长时间了。但都不能解决这个问题。一些著名的软件也不能解决这个问题。
    如:金山影霸、豪杰超级解霸2001,Power DVD,就连Windows 也只提供了“弹出 CD-ROM”而没有类似的功能,不知道是什么原因。如果有那位知道可一定不要忘了我们这帮兄弟呀。
      

  2.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
    var
      dwTemp1,dwTemp2: DWord;
      NResult: DWORD;
    begin
      new(NResult);
      GetVolumeInformation(PChar('g:\'), Nil, 0, @Result, dwTemp1, dwTemp2, Nil, 0);
      if Result = 0 then
        ShowMessage('CDROM is not Ready!');
    end; 
      

  3.   

    打开光驱
      procedure TForm1.OpenCDRomClick(Sender: TObject);
      begin
      mciSendString('Set cdaudio door open wait', nil, 0, handle);
      end;关闭光驱
      procedure TForm1.CloseCDRomClick(Sender: TObject);
      begin
      mciSendString('Set cdaudio door closed wait', nil, 0, handle);
      end;另外先在uses后加上MMSystem 
      

  4.   

    xueyin(雪莹)的第一个答案只解决了光驱中是否有盘,第二个答案解决了弹出光驱和关光驱。但是这都无法判断光驱是否打开。因为这几个函数都无法返回任何有关光驱的状态信息。
    karma(无为)的答案,只有在开机是光驱就处于关闭状态,再用一个变量记录光驱状态,才可以确定光驱的状态。
    请大家提供一点有用的东西。我是连中断都试过的,这几个函数我也搞过。
      

  5.   

    xueyin(雪莹)的第一个答案只解决了光驱中是否有盘,第二个答案解决了弹出光驱和关光驱。但是这都无法判断光驱是否打开。因为这几个函数都无法返回任何有关光驱的状态信息。
    karma(无为)的答案,只有在开机是光驱就处于关闭状态,再用一个变量记录光驱状态,才可以确定光驱的状态。
    请大家提供一点有用的东西。我是连中断都试过的,这几个函数我也搞过。
      

  6.   

    mioracle(飘血天王) :你还真搞笑!
    不知道,关注!
      

  7.   

    (From 罗云彬的编程乐园,DOS下的)我们在应用程序中常见到用软件控制 CD-ROM 的出、入盒,本文就是实现这种功能的一个例子。主要用到 INT 2FH 的 1510H(Send device driver request) 功能。具体参数详见程序注释。要用到的几个中断说明如下:1. IOCTL input 的格式:偏移量 类型 内容 
    00H 字节 1AH 
    01H 字节 00H 
    02H 字节 03H 
    03H 字节 11 DUP(?) 
    0EH 双字 缓冲区地址 
    12H 字 缓冲区长度 
    14H 字节 6 DUP(?) 2. IOCTL output 的格式:偏移量 类型 内容 
    00H 字节 1AH 
    01H 字节 00H 
    02H 字节 0CH 
    03H 字节 11 DUP(?) 
    0EH 双字 缓冲区地址 
    12H 字 缓冲区长度 
    14H 字节 6 DUP(?) 3. 在缓冲区中填入命令再用 INT 2fH 的 1510H 便可以实现 CD-ROM 的各种功能,缓冲的一些命令格式如下:作用 长度 格式 
    出盒 1 00 
    解锁 2 01,00 
    加锁 2 01,01 
    入盒 1 05 
    取CD-ROM 状态 5 06,0,0,0,0
    返回:06,xx,xx,0,0
    xx,xx为状态字
    位0:1 门开,0门关
    位1:1未锁,0门锁
    位B:1无盘,0有盘 4. 检测 CD-ROM 驱动程序的存在:AX = 1500H
    BX = 0
    INT 2fH
    返回:BX = CD-ROM 个数
          CX = 起始CD-ROM 盘符,0=A:,1=B:等等5. 发送 Device Driver Request:AX = 1510H
    ES:BX=请求头地址
    CX = CD-ROM 的盘号源程序如下:;       CD-ROM eject/load progrm
    ;       Ver 1.20 ------ Jan 6,1996CODE SEGMENT
    ASSUME CS:CODE,DS:CODE
    ORG 100H
    START:
    jmp install
    COPYRIGHT DB 'CD-ROM drive eject/close prg. V1.20',0dh,0ah
    DB 'Copyright (c) by Luo Yun Bin, Jan 6,1996',0dh,0ah
    DB 'http://asm.yeah.net,Email: [email protected]'
    DB 0dh,0ah,0ah,24h
    D_HELP DB 'Usage: EJ [drive:] [/?|/L|/U]',0dh,0ah
    DB '       /?  -------- Display this help',0dh,0ah
    DB '       /L  -------- Lock door',0dh,0ah
    DB '       /U  -------- Unlock door',0dh,0ah,24h
    MESS_WAIT DB '[ENTER] to close, [Esc] to quit.',24h
    MESS_ESC DB 'tray keep open...',0dh,0ah,24h
    MESS_NO_CD DB 'MSCDEX not installed!',0dh,0ah,24h
    MESS_STATUS DB 'There are '
    DRV_NUMBER DB '0 CD-ROM drive(s) starting at '
    DRV DB 'A:',0dh,0ah,24h
    MESS_DRV DB 0dh,'                                  ',0dh
    DB 'drive '
    DRV1 DB 'A: ',24h
    MESS_EJECT DB 'ejecting....',24h
    MESS_CLOSE DB 'closing ....',24h
    MESS_LOCK DB 'locking ....',24h
    MESS_UNLOCK DB 'unlocking...',24h
    MESS_DONE DB ' Done!',0dh,0ah,24h
    CD_DRV DW ?
    FLAG DB ?
    ;======================================================
    REQ_HEAD DB 1ah,0 ;IOCTL input
    REQ_CMD DB 3
    REQ_ERR DW ?
    DB 9 dup (0)
    BUF_OFF DW buffer
    BUF_SEG DW ?
    BUF_LEN DW ?
    DB 6 dup (0)
    ;======================================================
    BUFFER DB 5 dup (0) ;Max used 5 bytes
    CMD_LINE PROC
    mov si,81h ;处理命令行参数
    mov di,80h
    cld
    cmd_reload:
    lodsb
    cmp al,0dh
    jz conv_end ;将命令行小写字母换成大写
    cmp al,'a'
    jb conv_ok
    cmp al,'z'
    ja conv_ok
    sub al,20h
    conv_ok:
    stosb
    jmp short cmd_reload
    conv_end:
    xor al,al
    stosb

    mov si,80h
    cmd_reload1:
    lodsb
    or al,al
    jz cmd_end
    cmp al,'/'
    jz cmd_switch
    cmp al,':'
    jnz cmd_reload1
    mov al,[si-2]
    cmp al,'A'
    jb cmd_end
    cmp al,'Z'
    ja cmd_end
    sub al,'A'
    xor ah,ah
    mov cd_drv,ax
    jmp short cmd_reload1
    cmd_switch:
    lodsb
    cmp al,'?'
    jz cmd_help
    cmp al,'L'
    jz cmd_lock
    cmp al,'U'
    jz cmd_unlock
    jmp short cmd_reload1
    cmd_end:
    ret
    cmd_help:
    mov dx,offset d_help
    call print
    int 20h
    cmd_lock:
    or flag,1
    jmp short cmd_reload1
    cmd_unlock:
    or flag,2
    jmp short cmd_reload1
    CMD_LINE ENDP
    CD_INT PROC
    mov ax,1510h
    mov buf_seg,cs
    mov bx,offset req_head
    mov     cx,cd_drv
    int     2fh

    ret
    CD_INT ENDP
    GET_STATUS PROC
    mov     buffer,6
    mov buf_len,5
    mov req_cmd,3
    call    cd_int
    ret
    GET_STATUS ENDP
    EJECT_DISK PROC
    mov dx,offset mess_drv
    call print
    mov dx,offset mess_eject
    call print
    mov buffer,0
    mov buf_len,1
    mov req_cmd,0ch
    call    cd_int
    mov     dx,offset mess_done
    call    print
    ret
    EJECT_DISK      ENDP
    CLOSE_TRAY      PROC
    mov     dx,offset mess_drv
    call    print
    mov     dx,offset mess_close
    call    print
    mov buffer,5
    mov buf_len,1
    mov req_cmd,0ch
    call cd_int
    mov     dx,offset mess_done
    call    print
    ret
    CLOSE_TRAY      ENDP
    LOCK_DOOR PROC
    mov dx,offset mess_drv
    call print
    mov dx,offset mess_lock
    call print

    mov word ptr buffer,0101h
    mov buf_len,2
    mov req_cmd,0ch
    call cd_int

    mov dx,offset mess_done
    call print
    ret
    LOCK_DOOR ENDP
    UNLOCK_DOOR PROC
    mov dx,offset mess_drv
    call print
    mov dx,offset mess_unlock
    call print

    mov word ptr buffer,0001h
    mov buf_len,2
    mov req_cmd,0ch
    call cd_int

    mov dx,offset mess_done
    call print
    ret
    UNLOCK_DOOR ENDP
    CHECK_CDROM     PROC
    mov     ax,1500h
    xor     bx,bx
    int     2fh
    or      bx,bx ;BX = CD-ROM numbers
    jnz     mscdex_installed
    mov     dx,offset mess_no_cd
    call    print
    int     20h
    mscdex_installed:
    mov     bp,cx
    xor     bh,bh
    add     bp,bx
    dec     bp
    cmp     cd_drv,cx
    jb      re_set
    cmp     cd_drv,bp
    jbe     par_ok
    re_set:
    mov     cd_drv,cx
    par_ok:
    add     drv_number,bl
    add     drv,cl
    mov     cx,cd_drv
    add     drv1,cl
    mov     dx,offset mess_status
    call    print
    ret
    CHECK_CDROM     ENDP
    PRINT PROC
    mov     ah,9
    int     21h
    ret
    PRINT ENDP
    install:
    mov     dx,offset copyright
    call    print
    call cmd_line
    call    check_cdrom ;检测 CD-ROM 状态
    test flag,1 ;如果 /L 参数则 Lock_door
    jz ins1
    call lock_door
    int 20h
    ins1:
    test flag,2 ;如果 /U 参数则 unlock_door
    jz ins2
    call unlock_door
    int 20h
    ins2:
    call    get_status
    test word ptr buffer+1,1 ;如果现在在出盒状态则转入盒
    jnz close_it
    call    eject_disk ;打开 CD-ROM
    mov     dx,offset mess_wait ;等待
    call    print
    xor     ax,ax
    int     16h
    cmp     al,1bh
    jz      _esc_quit
    close_it:
    call    close_tray ;关闭 CD-ROM
    int     20h
    _esc_quit:
    mov     dx,offset mess_drv
    call    print
    mov     dx,offset mess_esc
    call    print
    int     20h
    CODE ENDS
    END START
      

  8.   

    《编程黑马真言》这本书的光盘里有,自己去借光盘来看看。或者我发给你:〉我的邮箱是[email protected]
      

  9.   

    给我一份,我的地址[email protected]
    重申一点我讨论的是光驱的门是不是打开的,而不是弹出打开光驱。