...
...

Программирование на VBA в Microsoft Office. Проигрыватель видео файлов

Программирование на VBA в Microsoft Office
Проигрыватель видео файлов

(не для чайников:-(

Как уже было написано в предыдущей статье, для полного контроля над проигрыванием мультимедийных файлов надо запрограммировать работу приложения с MCI — Media Control Interface. Этот интерфейс позволяет практически одинаково воспроизводить мультимедиа-данные различных типов. Все мультимедиа-объекты, такие как AVI-видеофайл, звуковой WAV-файл, музыкальные MIDI-файлы, треки компакт-диска и другие, воспринимаются MCI как устройства, которые можно открыть, воспроизвести и закрыть. Поэтому различия между выводом звуковых и видео-файлов минимальны.
Так как MCI является составной частью Windows и работа с ним программируется с помощью функций WinAPI, то данная статья может представлять интерес и для разработчиков, использующих другие языки программирования.
Рассмотрим пример объекта для проигрывания AVI-видеороликов в окне формы через MCI.
Запустите Word или Excel, откройте документ с примерами первой статьи (КГ № 2(343) "...Создаем свои объекты.") — объектом dlgFileOpen и формой ownMediaPlayer для выбора WAV-файлов. Вышеозначенный пример таблицы Excel с программами на VBA Вы сможете также найти на http://brestmedia.f2s.com/ в разделе "Скачать".
Запустите редактор Visual Basic (для начинающих — комбинация Alt+F11). Далее нам понадобится еще один объект. В окне проекта кликните правой кнопкой мыши и во всплывающем меню выберите пункт "Вставить►" и далее "Модуль класса". В окне свойств назовите класс VideoPlayer.
Теперь в окне исходного текста будем программировать.
Работа с MCI идет через вызов одной-единственной функции WinAPI — mciSendCommand из библиотеки WINMM.DLL.
Для использования на VBA внутри объекта VideoPlayer опишем ее следующим образом:
Private Declare Function mciSendCommand Lib "winmm.dll" _ Alias "mciSendCommand
A" (ByVal wDeviceID As Long, ByVal uMessage As Long, _ ByVal dwParam1 As Long, ByRef dwParam1 A
s Any) As Long
В процессе работы мультимедиа могут возникать различные ошибки — например, отсутствуют соответствующие кодеки либо параметры экрана не позволяют воспроизводить видео и т.д.
Для обработки возможных ошибок воспроизведения воспользуемся еще одной функцией из той же библиотеки:

Private Declare Function mciGetErrorString Lib "winmm.dll" _ Alias "mciGetError
StringA" (ByVal dwError As Long, ByVal lpstrBuffer As String, _ ByVal uLength As Long) As Long 
Вспомогательные переменные опишем как скрытые свойства объекта. ‘Имя видеофайла Private AVIFile As S
tring ‘Ссылка на открытый AVI-файл Private hAVI As Long ‘Код ошибки Private hErr As Long
Так как воспроизведение видео (в отличие от звука;) должно происходить в каком-нибудь окне, то по умолчанию зарегистрированный в Windows проигрыватель создает свое собственное окно. Если надо организовать вывод в окно приложения, надо передать в MCI ссылку на него. В данном примере будем пользоваться окном формы. Оно будет активным, например, в момент нажатия кнопки воспроизведения. Поэтому, чтобы получить ссылку на окно, воспользуемся функцией WinAPI — GetActiveWindow. Она возвращает ссылку на текущее активное окно.

Private Declare Function GetActiveWindow _ Lib "user32" () As Boolean
Для определения размеров области вывода внутри окна опишем еще одну функцию Windows.

Private Declare Function GetClientRect Lib "user32" _ (ByVal hWnd As Long, lpRect As
 RECT) As Long
Теперь перейдем непосредственно к программированию команд MCI. Для этого нам понадобится список всех типов и констант этого интерфейса. В рамках газетной статьи приводить его бессмысленно, т.к. эту информацию легко можно найти в любом серьезном help'е по WinAPI.
А проще всего скачать готовый работающий пример вместе с исходниками с сайта http://brestmedia.f2s.com/.

Свойство-метод Error, возвращающее описание ошибки, используется только для чтения внутри других методов объекта.

Property Get Error() Dim strBuffer As String Dim lngPos As Long Dim lngRet As Long If hErr <
;> 0 Then ‘Создать пустую строку как буфер strBuffer = Space(1024) ‘Получить сообщение по коду ош
ибки Call mciGetErrorString(hErr, strBuffer, 1024) hErr=0 End If Error = Trim(strBuffer) End Propert
y
Свойство-метод Play, при присваивании ему имени AVI-файла начинает воспроизводить видео в текущем активном окне.

Property Let Play(ByVal strAVIFileName As String) ‘Описание переменных для работы с MCI Dim mc
i As MCI_OPEN_PARMS Dim mpp As MCI_PLAY_PARMS Dim mow As MCI_OVLY_WINDOW_PARMS Dim morSource As MCI_
OVLY_RECT_PARMS Dim morDest As MCI_OVLY_RECT_PARMS ‘Описание переменных для работы с окном Dim mhWnd
 As Long Dim rc As RECT mhWnd = 0 ‘Имя видеофайла AVIFile = strAVIFileName 'Открытие мультимедиа-уст
ройства With mci .strDeviceType = "avivideo" .strElementName = strAVIFileName End With If 
hAVI <> 0 Then CloseDevice End If hErr = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE Or MCI_OPEN
_ELEMENT, mci) If hErr = 0 Then hAVI = mci.lngDeviceID Else ‘Вывод сообщения об ошибке Err.Raise hEr
r, "VideoPlayer::Play", Error 'OpenDevice End If 'Установка активного окна для воспроизвед
ения Dim lngFlags As Long If hAVI Then 'Установка флагов по умолчанию lngFlags = MCI_OVLY_WINDOW_HWN
D Or _ MCI_OVLY_WINDOW_ENABLE_STRETCH ' MCI_OVLY_WINDOW_DISABLE_STRETCH ‘Получить ссылку на активное
 окно mhWnd = GetActiveWindow() mow.hWnd = mhWnd 'Установка названия окна 'mow.strText = mstrCaption
 'lngFlags = lngFlags Or MCI_OVLY_WINDOW_TEXT 'Запуск MCI_WINDOW команды ‘для указания окна hErr = m
ciSendCommand(hAVI, MCI_WINDOW, _ lngFlags, mow) If hErr <> 0 Then Err.Raise hErr, "Video
Player::Play", Error End If End If 'Центрирование внутри области вывода окна If Len(strAVIFileN
ame) > 0 And (mhWnd <> 0) Then ' Запуск MCI_WHERE команды для получения ' размера области в
ывода .AVI файла hErr = mciSendCommand(hAVI, MCI_WHERE, _ MCI_OVLY_WHERE_SOURCE, morSource) If hErr 
= 0 Then ' Получить размеры доступной области окна для вывода If CBool(GetClientRect(mhWnd, rc)) The
n ' Центрирование With rc morDest.rc.Top = (.Bottom —.Top — _ morSource.rc.Bottom) / 2 morDest.rc.Le
ft = (.Right —.Left — _ morSource.rc.Right) / 2 End With ' Запуск MCI_PUT команды для размещения ' о
бласти вывода в расчитанной позиции ' указанного окна hErr = mciSendCommand(hAVI, _ MCI_PUT, MCI_OVL
Y_PUT_DESTINATION Or _ MCI_OVLY_RECT, morDest) If hErr <> 0 Then Err.Raise hErr, "VideoPl
ayer::Play", Error End If Else Err.Raise hErr, "VideoPlayer::Play", Error End If Else
 Err.Raise hErr, "VideoPlayer::Play", Error End If End If 'Воспроизведение If hAVI Then hE
rr = mciSendCommand(hAVI, MCI_PLAY, 0&, 0&) If hErr <> 0 Then Err.Raise hErr, "VideoPlaye
r::Play", Error End If End If End Property ‘Метод закрывает мультимедиа-устройство ‘Доступен дл
я вызова из других объектов Public Sub CloseDevice() If hAVI Then ' Если видео воспроизводится — ост
ановить If IsPlaying Then StopPlaying End If ' Закрыть устройство hErr = mciSendCommand(hAVI, MCI_CL
OSE, 0&, 0&) If hErr = 0 Then hAVI = 0 Else Err.Raise hErr, "VideoPlayer::CloseDevice", Er
ror End If End If End Sub ‘Метод прерывает воспроизведение ‘Доступен для вызова из других объектов P
ublic Sub StopPlaying() If hAVI Then hErr = mciSendCommand(hAVI, MCI_STOP, 0&, 0&) If hErr <> 
0 Then Err.Raise hErr, "VideoPlayer::StopPlaying", Error End If End If End Sub ‘Свойство-м
етод, возвращает истину ‘если идет воспроизведение Property Get IsPlaying() As Boolean Dim mst As MC
I_STATUS_PARMS If hAVI Then With mst .lngItem = MCI_STATUS_MODE .lngTrack = 0 End With ‘Получить сос
тояние устройства hErr = mciSendCommand(hAVI, MCI_STATUS, _ MCI_STATUS_ITEM, mst) If hErr = 0 Then I
sPlaying = (mst.lngReturn = MCI_MODE_PLAY) Else Err.Raise hErr, "VideoPlayer::IsPlaying", 
Error End If End If End Property ‘Удаление класса Private Sub Class_Terminate() CloseDevice End Sub
Для использования VideoPlayer в редакторе Visual Basic откройте для редактирования форму ownMediaPlayer.
Добавьте кнопку проигрывания видео и двойным щелчком мыши по форме перейдите в окно редактирования исходного текста формы.
В разделе описаний добавьте строку:

Dim AVIPlayer As VideoPlayer ‘— объект типа VideoPlayer ‘Метод инициализации формы уже будет в
ыглядеть так: Private Sub UserForm_Initialize() ‘Создание экземпляра объекта Set AVIPlayer = New Vid
eoPlayer Set dlgFiler = New dlgFileOpen End Sub ‘Метод обработки события — ‘нажатия кнопки выбора фа
йла Private Sub CommandButton2_Click() TextBox1.Value = dlgFiler.OpenFile("AVI-Файлы" & vb
NullChar & "*.AVI",,, "Выбирайте видеозапись") End Sub ‘Нажатие кнопки проигрыва
ния видео Private Sub CommandButton1_Click() AVIPlayer.Play = TextBox1.Value End Sub Метод UserForm_
QueryClose выполняется перед закрытием формы, поэтому воспроизведение видео необходимо прервать и за
крыть устройство. Private Sub UserForm_QueryClose(Cancel As Integer, _ CloseMode As Integer) AVIPlay
er.CloseDevice End Sub
Сохраните набранные программы, перейдите в таблицу Excel и нажмите кнопку запуска формы. Нажмите кнопку выбора файла и укажите AVI-файл. В поле ввода формы появится его полное имя. Теперь нажмите кнопку воспроизведения и откиньтесь на спинку кресла...
Приведенная методика проигрывания видео работает на всех версиях Windows, начиная с 95, независимо от установленных компонентов. Все остальные компоненты и объекты, облегчающие применение мультимедиа при разработке приложений в таких средах, как Delphi или C++, так или иначе используют те же приемы, но требуют дополнительно наличия соответствующих .OCX или .DLL файлов. Поэтому, может, надежней сделать самому?
Пример таблицы Excel с описанными программами на VBA Вы сможете найти на http://brestmedia.f2s.com/ .
to be continued...

Виктор Маковчик makovchik@tut.by



© Компьютерная газета

полезные ссылки
IP камеры видеонаблюдения