Интерфейс управления устройствами MCI (Media Control Interface) - mciSendCommand() и CD-ROM

ОГЛАВЛЕНИЕ

mciSendCommand() и CD-ROM

Помимо функции mciSendString(), мы упоминали функцию mciSendCommand(). И сейчас ею конкретно займемся. Этот проект будет достаточно насыщенный, так что держитесь. Устройство выберем самое распространенное - CD-ROM.

Первым делом, прежде чем воспользоваться устройством, нам надо его открыть (это логично), т.е. узнать его ID. Нам понадобится для этого структура MCI_OPEN_PARMS:

typedef struct {
DWORD dwCallback;
MCIDEVICEID wDeviceID;
LPCTSTR lpstrDeviceType;
LPCTSTR lpstrElementName;
LPCTSTR lpstrAlias;
} MCI_OPEN_PARMS;

где:

  • dwCallback - для функции "возврата"
  • wDeviceID - возвращаемый идентификатор устройства
  • lpstrDeviceType - указатель на имя устройства
  • lpstrElementName - обычно путь до файла
  • lpstrAlias - указатель на буфер, содержащий alias устройство

После того, как мы узнали идентификатор устройства следующим действием следует проверить его на готовность. Для этого мы используем структуру MCI_STATUS_PARMS:

typedef struct {
DWORD dwCallback;
DWORD dwReturn;
DWORD dwItem;
DWORD dwTrack;
} MCI_STATUS_PARMS;

где:

  • dwCallback - смотрите выше
  • dwReturn - возвращаемая информация
  • dwItem - опрашиваемое свойство
  • dwTrack - параметр трека

Эта структура используется довольно часто. Скоро Вы в этом убедитесь.

Далее мы будем собирать информацию о диске. Для начала узнаем сколько треков на нем содержится, потом длину каждого трека (это нам понадобиться, чтобы определить его длительность в минутах и секундах) и, естественно, проверить тип трека, т.е. какую информацию он несет: цифровую или аудио. И в заключение определить длительность каждого трека.

Начнем с первого пункта. Открываем наше устройство:

// Объявляем структуру
MCI_OPEN_PARMS mciOpenParms;

// Присваиваем значение типа устройства
mciOpenParms.lpstrDeviceType = "cdaudio";

// Устанавливаем флаги, которые укажут интерфейсу, как нужно
// интерпретировать информацию в структуре mciOpenParms.
// В данном случае мы сообщаем MCI о том, что передаем ему тип
// устройства.

DWORD flags = MCI_OPEN_TYPE;

// Давайте рассмотрим, как эта функция будет использовать ту
// информацию, которую мы заложили. Начнем с первого параметра - 0.
// Так как мы не знаем еще идентификатор нашего устройства, поэтому
// просто устанавливаем его в 0. Второй параметр говорит MCI, что мы
// хотим открыть устройство, имя которого она извлечет из структуры
// mciOpenParms. По поводу третьего параметра смотрите выше. И,
// наконец, последним параметром нашей функции будет указатель на
// структуру из которой она извлечет необходимые ей данные. В данном
// случае, как я уже говорил, имя устройства.


DWORD resume = mciSendCommand(0, MCI_OPEN, flags,
(DWORD) (LPVOID)& mciOpenParms);

// Если все было в порядке, получаем идентификатор устройства
if (resume == 0)
wDeviceID = mciOpenParms.wDeviceID;

Следующее, что мы должны сделать по списку, это проверить устройство на готовность:

// Т.к. мы опрашиваем устройство, то заполняем соответствующий
// элемент структуры MCI_STATUS_PARMS - dwItem. Флаг
// MCI_STATUS_READY как раз и определяет устройство на готовность.

mciStatusParms.dwItem = MCI_STATUS_READY;

// В качестве первого параметра передаем идентификатор устройства.
// Второй параметр - это команда, которая связана со структурой
// MCI_STATUS_PARMS и которая извлекает информацию об устройстве.
// Третий параметр, даже не знаю как сказать...подтверждает то,
// что информация, которой мы заполнили структуру, относиться
// только к свойствам устройства. Ну и последним параметром мы
// передаем указатель на структуру MCI_STATUS_PARMS.

mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)& mciStatusParms);

Если устройство у нас готово, то переходим к третьему пункту. Узнаем количество треков. Код я приводить не буду, т.к. далее все идет по аналогии. Опять мы хотим получить интересующую нас информацию. По этому будем продолжать использовать структуру MCI_STATUS_PARMS, только команда у нас поменяется и станет MCI_STATUS_NUMBER_OF_TRACKS, которую мы отправим в dwItem.

Теперь давайте определим длину каждого трека. Как я уже говорил это нам нужно, что бы узнать время проигрывания трека. Для того, что бы определить длину ,к примеру n-ого трека, нам следует обратиться по номеру этого трека. Как Вы уже догадались этот номер мы поместим в dwTrack структуры MCI_STATUS_PARMS, а команду определения длинны трека -MCI_STATUS_LENGTH в dwItem. Здесь мы уже начали работать непосредственно с треками, и я прошу акцентировать ваше внимание на третьем пераметре функции mciSendCommand(). В этом случае необходимо к флагу MCI_STATUS_ITEM добавить еще и флаг MCI_TRACK. Это очень важно.

Проверим информацию о типе трека. Записываем номер трека в dwTrack, а в dwItam команду проверки трека - MCI_CDA_STATUS_TYPE_TRACK. После извлекаем из структуры результат, который храниться в dwReturn и сравниваем с MCI_CDA_TRACK_AUDIO. Если значения равны, то трек к которому мы обратились несет аудио информацию.

И последнее, что нам осталось - это определить время проигрывания треков. Для этого воспользуемся функциями MCI_MSF_MINUTE() и MCI_MSF_SECOND(). Передаваемым значением является длинна трека.