Я уже было совсем забросил заниматься этой рассылкой - шутка ли прошло больше года с момента последнего выпуска. За это время много чего произошло. Я наконец-то закончил учебу в институте, свободного время стало больше, но полениться тоже охота :)
Вот решил в качестве возрождения сделать небольшой выпуск. Кстати, я рассылку немного переименовал.
Управление 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 . Эта функция у меня определена в отдельном файле, где лежат еще кое-какие функции общего назначения (например функция сопоставления маски и строки). Чтобы не загромождать место описанием других функций, приведу описание лишь самой IsCDPresent , вот оно:
Для того, чтобы можно было пользоваться классом AxCDManager , нужно :
Подключить заголовочный файл AxCdManager.h
Добавить к проекту два . cpp -файла: AxCdManager . cpp и AxThread . cpp (поддержка многопоточности)
Включить пространство имен AxWinLib директивой namespace или создать класс по полному квалифицированному имени.
Данный класс можно использовать в любых проектах, как в WTL , так и MFC и WinAPI .
Заключение
Несмотря на то, что казалось бы такое простое действие, как открытие привода CD - ROM должно выполняться элементарно, мне пришлось довольно много порыться в Сети, чтобы наконец понять, как это делается правильно. Когда я наконец нашел работающий пример, то оказалось, что расхождения моем коде (который никак не хотел работать) и примером оказались на уровне 1-2 байт, нюанс был, насколько помню, в форме передачи имени используемого диска.
На сегодня все. До скорой встречи. Надеюсь, не через год :)