Четверг, 03.07.2025, 23:36
Приветствую Вас Гость | RSSГлавная | Регистрация | Вход
Меню сайта
Категории раздела
Субклассирование элементов управления [3]
Приёмы субклассирования различных элементов управления для расширения их функциональных возможностей.
Вспомогательные функции [4]
Полезные советы, которые могут пригодиться во всех областях программирования
Мультимедиа [2]
Советы по работе над различными мультимедийными приложениями.
Необычные приложения [1]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » Статьи » Программирование на Visual Basic » Мультимедиа

Открытие и закрытие дисковода

Если вы пишете программу, связанную с мультимедиа, вам наверняка потребуется возможность открывать и закрывать CD-ROM программно. Обычно это рекомендуется делать при помощи API-функции mciSendString из библиотеки winmm.dll. Её декларация:

Declare Function mciSendString Lib "winmm.dll" _
 Alias "mciSendStringA" (ByVal lpstrCommand As String, _
 ByVal lpstrReturnString As String, ByVal uReturnLength As Long, _
 ByVal hwndCallback As Long) As Long

Эта функция посылает командную строку мультимедийным устройствам. Открыть дисковод можно так:

mciSendString "set cdaudio door open", 0, 127, 0

Команда на закрытие дисковода:

mciSendString "set cdaudio door closed", 0, 127, 0

Но что же делать, если у пользователя на компьютере установлено два (как у меня), или более CD-ROM устройства? Предложенные выше функции будут открывать-закрывать только лишь одно устройство. В этом случае на помощь придёт низкоуровневая API-функция DeviceIoControl. Вот её декларация.

Declare Function DeviceIoControl Lib "kernel32" ( _
 ByVal hDevice As Long, ByVal dwIoControlCode As Long, _
 lpInBuffer As Any, ByVal nInBufferSize As Long, _
 lpOutBuffer As Any, ByVal nOutBufferSize As Long, _
 lpBytesReturned As Long, lpOverlapped As Any) As Long

Как видно из декларации, первый параметр функции - это дескриптор нужного нам устройства. Получить его можно с помощью замечательной функции CreateFile.

Declare Function CreateFile Lib "kernel32" _
 Alias "CreateFileA" (ByVal lpFileName As String, _
 ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
 lpSecurityAttributes As Any, _
 ByVal dwCreationDisposition As Long, _
 ByVal dwFlagsAndAttributes As Long, _
 ByVal hTemplateFile As Long) As Long

Полученный дескриптор, когда он больше не будет нужен, обязательно нужно закрыть при помощи функции CloseHandle:

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Есть одна тонкость при вызове CreateFile - к пути дисковода нужно спереди добавить префикс "\\.\", для того, чтобы функция "знала", что мы имеем дело именно с устройством, а не с дисковой папкой. Таким образом, для дисковода с буквой Е, параметр lpFileName будет иметь вид:

lpFileName = "\\.\e:"

Сначала объявим необходимые константы.

Const FILE_SHARE_READ = &H1&
Const FILE_SHARE_WRITE = &H2&
Const OPEN_EXISTING = 3&
Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const INVALID_HANDLE_VALUE = -1

А вот главные, "секретные", константы для DeviceIoControl. Значений этих не найти в заголовочных файлах. Они получены выполнением специальных макросов в среде Visual C++:

Const IOCTL_STORAGE_EJECT_MEDIA = &H2D4808
Const IOCTL_STORAGE_LOAD_MEDIA = &H2D480C

Теперь, когда у нас всё подготовлено, пишем функцию, открывающую дисковод (возвращает в случае неудачи False):

Public Function EjectCD(ByVal drivePath As String) As Boolean
 Dim drFullPath As String
 Dim hDevice As Long, nBytesReturned As Long
 
 'Удаляем на всякий случай лишнюю косую черту,
 'если путь к дисководу её содержит
 drivePath = Replace(drivePath, "\", "")
 
 'Перед буквой диска обязательно вставить
 'эту комбинацию символов
 drFullPath = "\\.\" & LCase(drivePath)
 
 'Получим дескриптор дисковода
 hDevice = CreateFile( _
 drFullPath, _
 GENERIC_READ, _
 FILE_SHARE_READ Or FILE_SHARE_WRITE, _
 ByVal 0&, OPEN_EXISTING, 0, 0)
 
 'Если дескриптор верный, открываем CD-ROM,
 'и возвращаем True для контроля за его состоянием
 If hDevice <> INVALID_HANDLE_VALUE Then
 EjectCD = CBool(DeviceIoControl(hDevice, _
 IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, _
 nBytesReturned, ByVal 0&))
 'Закроем дескриптор, так как он больше не нужен
 CloseHandle hDevice
 End If
End Function 'EjectCD

Функция закрывающая дисковод LoadCD, будет отличаться лишь тем, что вместо константы IOCTL_STORAGE_EJECT_MEDIA подставляем IOCTL_STORAGE_LOAD_MEDIA.

Не очень просто, но ведь работает! После тестирования функций, можно создать класс для работы с дисководами, включить его в проект ActiveX DLL или EXE, откомпилировать, и забыть, как страшный сон.

Будьте осторожны с функцией DeviceIoControl !. С её помощью можно ещё и форматировать диски. Ошибка в константе - и большой привет!

Автор - Цзяофань

Категория: Мультимедиа | Добавил: Xiaofang (21.04.2009)
Просмотров: 9567 | Рейтинг: 4.2/5 |
Всего комментариев: 0
Форма входа
Поиск
Друзья сайта
Антология советской песни
Сайт управляется системой uCoz