2009-05-16 9 views
2

を使用してCDを取り出すためにどのように私はこのコードを試してみました:Delphiは:プログラムでドライブ文字

uses MMSystem; 

mciSendString('Set cdaudio door open wait', nil, 0, handle); 

mciSendString('Set cdaudio door closed wait', nil, 0, handle); 

をしかし、効果はなかったです。私はこれがすべてのシステムで動作しないと聞いています。

Windows XPでドライブを取り出そうとしていますが、複数のドライブを搭載したシステムに必要なドライブ文字でドライブを指定したいと考えています。

答えて

10

これはのDeviceIOControl() API関数を使用してコードでは、WindowsのXP(コンパイルとDelphi 5を使用して試験)に私の作品:

function DeviceIOControlHelper(ADeviceHandle: THandle; 
    ADeviceIOControlCode: DWORD): boolean; 
var 
    BytesReturned: Cardinal; 
begin 
    Result := DeviceIOControl(ADeviceHandle, ADeviceIOControlCode, 
    nil, 0, nil, 0, BytesReturned, nil); 
end; 

function SetDriveDoorOpen(ADriveLetter: char; AValue: boolean): boolean; 
const 
    FILE_DEVICE_FILE_SYSTEM = 9; 
    FILE_ANY_ACCESS = 0; 
    FILE_READ_ACCESS = 1; 
    METHOD_BUFFERED = 0; 
    IOCTL_STORAGE_BASE = $2D; 

(* 
#define CTL_CODE(DeviceType, Function, Method, Access) (    \ 
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ 
*) 

// FSCTL_LOCK_VOLUME = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, 
//        METHOD_BUFFERED, FILE_ANY_ACCESS); 
    FSCTL_LOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) 
         or (FILE_ANY_ACCESS shl 14) 
         or (6 shl 2) or METHOD_BUFFERED; 
// FSCTL_DISMOUNT_VOLUME = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, 
//         METHOD_BUFFERED, FILE_ANY_ACCESS); 
    FSCTL_DISMOUNT_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) 
          or (FILE_ANY_ACCESS shl 14) 
          or (8 shl 2) or METHOD_BUFFERED; 
// IOCTL_STORAGE_EJECT_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, 
//          METHOD_BUFFERED, FILE_READ_ACCESS); 
    IOCTL_STORAGE_EJECT_MEDIA = (IOCTL_STORAGE_BASE shl 16) 
           or (FILE_READ_ACCESS shl 14) 
           or ($0202 shl 2) or METHOD_BUFFERED; 
// IOCTL_STORAGE_LOAD_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, 
//          METHOD_BUFFERED, FILE_READ_ACCESS); 
    IOCTL_STORAGE_LOAD_MEDIA = (IOCTL_STORAGE_BASE shl 16) 
           or (FILE_READ_ACCESS shl 14) 
           or ($0203 shl 2) or METHOD_BUFFERED; 
var 
    DriveCmdStr: string; 
    DriveHandle: THandle; 
begin 
    Result := FALSE; 
    DriveCmdStr := Format('\\.\%s:', [ADriveLetter]); 
    DriveHandle := CreateFile(PChar(DriveCmdStr), GENERIC_READ, FILE_SHARE_WRITE, 
    nil, OPEN_EXISTING, 0, 0); 
    if DriveHandle <> INVALID_HANDLE_VALUE then begin 
    if AValue then begin 
     Result := DeviceIOControlHelper(DriveHandle, FSCTL_LOCK_VOLUME) 
     and DeviceIOControlHelper(DriveHandle, FSCTL_DISMOUNT_VOLUME) 
     and DeviceIOControlHelper(DriveHandle, IOCTL_STORAGE_EJECT_MEDIA); 
    end else 
     Result := DeviceIOControlHelper(DriveHandle, IOCTL_STORAGE_LOAD_MEDIA); 
    CloseHandle(DriveHandle); 
    end; 
end; 

エラーは省略取り扱い。

2

uses ComObj; 

function EjectDrive(const ADriveLetter: string): Boolean; 
var 
    WMP: Variant; 
    CDROMs: Variant; 
    Drive: Variant; 
begin 
    WMP := CreateOleObject('WMPlayer.OCX.7'); 
    CDROMs := WMP.CDROMCollection; 
    Drive := CDROMs.GetByDriveSpecifier(ADriveLetter + ':'); 
    Drive.Eject; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    EjectDrive('Q'); 
end; 

編集:ご覧のとおり、エラー処理コードは書きませんでした。このコードは、無効なドライブが指定されている場合に例外を発生させます。

+0

上記のコードを使用すると、アプリケーションがメインフォームから終了しないようにすることができます。 (プロセスはプロセスリストに残ります) – mtoloo

関連する問題