使用者電腦常安裝多台光碟機(CD-ROM、DVD、燒錄機、虛擬光碟機)。多媒體播放軟體需動態列出所有光碟機並獨立控制各自的彈出/關閉、播放軌道等。本文結合 GetLogicalDrives 與 GetDriveType 兩個 API,提供完整的掃描、識別、MCI 控制流程。
返回 32 位元位元遮罩,Bit 0 = A:, Bit 1 = B: … Bit 25 = Z:。成功非零,失敗返回 0。
輸入根目錄字串(如 "D:\\"),返回 DRIVE_CDROM 表示光碟機。
CStringArray cdDrives;
DWORD mask = GetLogicalDrives();
for (int i = 0; i < 26; ++i) {
if (mask & (1 << i)) {
TCHAR root[4] = { TCHAR('A' + i), _T(':'), _T('\\'), 0 };
if (GetDriveType(root) == DRIVE_CDROM)
cdDrives.Add(root);
}
}
// cdDrives 現在包含所有光碟機根目錄,如 "D:\\", "E:\\" ...
void EjectCdrom(TCHAR driveLetter, BOOL bOpen)
{
MCI_OPEN_PARMS op = {0};
op.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO;
TCHAR elem[4] = { driveLetter, _T(':'), 0 };
op.lpstrElementName = elem;
DWORD flags = MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT | MCI_OPEN_SHAREABLE;
if (mciSendCommand(0, MCI_OPEN, flags, (DWORD_PTR)&op) == 0) {
mciSendCommand(op.wDeviceID, MCI_SET,
bOpen ? MCI_SET_DOOR_OPEN : MCI_SET_DOOR_CLOSED, 0);
mciSendCommand(op.wDeviceID, MCI_CLOSE, MCI_WAIT, 0);
}
}
// 使用範例:彈出 F 槽
EjectCdrom(_T('F'), TRUE);
MCI_STATUS 讀取目前軌道、播放時間、光碟類型(資料/音樂)。while(DriveTemp)` 邏輯錯誤:右移計數只能得出最高位位置,無法統計實際磁碟機數量。正確做法如上述位元掃描迴圈。mciGetErrorString 取得描述。DRIVE_CDROM,屬正常行為。