Главная
Новости
Программы
Проекты
Статьи
Ссылки
Контакты
Гостевая
Выпуск №6. Управление CD-ROM

Рад всех приветствовать!

Я уже было совсем забросил заниматься этой рассылкой – шутка ли прошло больше года с момента последнего выпуска. За это время много чего произошло. Я наконец-то закончил учебу в институте, свободного время стало больше, но полениться тоже охота

Вот решил в качестве возрождения сделать небольшой выпуск. Кстати, я рассылку немного переименовал.

Управление CD/DVD приводом.

Итак, в этом выпуске я хотел бы немного рассказать об управлении CD / DVD приводом.

В принципе, тут ничего сложного нет. Есть немного подводных камней, не все из которых мне удалось обойти.

Для управления проводом можно воспользоваться WinAPI функцией mciSendCommand . Эта функция делает много всего хорошего и разного, в том числе может открывать и закрывать привод CD - ROM . С помощью этой функции так же можно определить – есть ли диск в приводе или его там нет. Единственное, что мне не удалось сделать этой функцией – это определить, открыт ли лоток привода или нет. Это не совсем удобно. Возможно есть какой-то хитрый способ. Да что там определение "открытости" лотка, даже чтобы просто открыть лоток пришлось изрядно помучаться

Возможно, для определения того, открыт или закрыт привод можно воспользоваться либо другими функциями, либо еще чем-то. Если кто-то мне подскажет как это сделать, то я буду премного благодарен.

Для управления CD / DVD приводом или несколькими приводами я сваял небольшой класс. Взять его Вы можете здесь. Вот его описание:

CAxCDManager();

Конструктор по умолчанию

CAxCDManager(bool bUseScrlLock);

Этот конструктор не используется .

int GetDrivesCount() const;

Возвращает количество CD / DVD приводов.

TCHAR GetDriveName(int iDrive) const;

Возвращает букву привода по его порядковому номеру. Если указан номер несуществующего привода, то возвращается '?' вместо имени.

TCHAR operator[] (int i) const;

Делает то же самое, что и GetDriveName .

TCHAR GetSelectedDrive() const;

Возвращает букву выбранного привода.

bool SelectDrive(int iDrive);

Выбирает указанный привод в качестве текущего по его номеру.

bool SelectDrive(TCHAR chDrive);

Выбирает указанный привод в качестве текущего по его имени.

bool IsOpened() const;

Возвращает статус – открыт или не открыт. Тут стоит заметить, что как я говорил раньше мне не удалось найти возможность определения такого состояния привода, поэтому эту возможность пришлось эмулировать. Сделано это в виде набора триггеров, соответствующих каждому приводу. Изначально предполагается, что все приводы закрыты и что открытие/закрытие приводов осуществляется через интерфейс класса. Если, например, вручную открыть CD-ROM .

bool IsCDPresent() const;

Возвращает статус – есть ли установленный в приводе диск. Подробнее см. ниже.

bool IsRunning() const;

Класс сделан как multithreaded , эта функция возвращает статус того, есть ли запущенные вторичные потоки.

bool Open();

Открывает текущий выбранный привод.

bool Close(bool bDetectCD = false);

Закрывает текущий выбранный привод. Необязательный параметр указывает на то, что стоит ли определять наличие диска в приводе. Такое определение не всегда удобно, так как может сопровождаться некоторыми задержками и раскручиванием диска.

bool OpenClose ( bool bDetectCD = false );

Обе предыдущие функции, которые объединены в одну. Один вызов открывает привод, другой его закрывает.

void RefreshState();

Обновляет внутреннее состояние класса – сколько приводов, какие буквы они занимают.

Стоит заметить, что для компиляции приведенного класса, ему нужна функция IsCDPresent . Эта функция у меня определена в отдельном файле, где лежат еще кое-какие функции общего назначения (например функция сопоставления маски и строки). Чтобы не загромождать место описанием других функций, я добавил ее определение в файлы определения самого класса.

Использование

Для того, чтобы можно было пользоваться классом AxCDManager , нужно :

  1. Подключить заголовочный файл AxCdManager.h
  2. Добавить к проекту два . cpp -файла: AxCdManager . cpp и AxThread . cpp (поддержка многопоточности)
  3. Включить пространство имен AxWinLib директивой namespace или создать класс по полному квалифицированному имени.

Данный класс можно использовать в любых проектах, как в WTL , так и MFC и WinAPI .

Заключение

Несмотря на то, что казалось бы такое простое действие, как открытие привода CD - ROM должно выполняться элементарно, мне пришлось довольно много порыться в Сети, чтобы наконец понять, как это делается правильно. Когда я наконец нашел работающий пример, то оказалось, что расхождения моем коде (который никак не хотел работать) и примером оказались на уровне 1-2 байт, нюанс был, насколько помню, в форме передачи имени используемого диска.

На сегодня все. До скорой встречи. Надеюсь, не через год

Используются технологии uCoz