Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Мультимедиа для Windows

© Александр Фролов, Григорий Фролов
Том 15, М.: Диалог-МИФИ, 1994, 284 стр.

[Назад] [Содеожание] [Дальше]

5.3. Работа с окном MCI

В этом разделе мы научимся создавать приложения для проигрывания файлов мультимедиа и дорожек компакт-дисков (а также для записи звуковых файлов) с использованием окна MCI.

Однако перед тем как приступить к описанию способов работы с этим окном, рассмотрим пример простейшего приложения, использующего окно MCI для проигрывания файлов мультимедиа.

Приложение MCIWND

Приложение MCIWND создает окно MCI (рис. 5.10) и... все!

Рис. 5.10. Окно MCI

Это окно, когда в него ничего не загружено, имеет стандартный заголовок и три органа управления - кнопку воспроизведения, кнопку доступа к меню и полосу просмотра.

Запустите загрузочный модуль этого приложения и нажмите кнопку доступа к меню (рис. 5.11).

Рис. 5.11. Кнопка доступа к меню

На экране появится почти стандартная диалоговая панель "Open", с помощью которой вы сможете выбрать файл мультимедиа для просмотра или прослушивания (рис. 5.12).

Рис. 5.12. Диалоговая панель "Open"

Обратите внимание, что в правом нижнем углу диалоговой панели имеются органы управления (кнопка и полоса просмотра), предназначенные для предварительного просмотра или прослушивания содержимого файла. Это очень удобно, так как при поиске файла не нужно много раз открывать и закрывать диалоговую панель "Open".

После загрузки wav-файла меню приложения модифицируется (рис. 5.13).

Рис. 5.13. Меню для работы с wav-файлом

В нем появляется строка "Close", с помощью которой можно закрыть файл, строка "Copy", позволяющая скопировать содержимое файла в Clipboard, а также строка "Command...". Последняя предназначена для передачи устройству произвольной управляющей строки MCI (соответствующая диалоговая панель показана на рис. 5.14).

Рис. 5.14. Диалоговая панель для передачи управляющей строки MCI

При выборе avi-файлов можно посмотреть их содержимое в небольшом окне (рис. 5.15).

Рис. 5.15. Выбор avi-файла

Для работы с avi-файлами используется расширенное меню (рис. 5.16).

Рис. 5.16. Меню для работы с avi-файлами

Строка "View" предназначена для управления размером окна. С помощью строк "Volume" и "Speed" можно регулировать, соответственно, громкость звука и скорость воспроизведения видео. Строка "Configure..." предназначена для установки параметров проигрывателя. При ее выборе на экране появляется диалоговая панель "Video Playback Options" (рис. 5.17).

Рис. 5.17. Диалоговая панель "Video Playback Options"

В поле "Video Mode" вы можете включить режим отображения видео в окне (переключатель "Window") или на полном экране видеомонитора (переключатель "Full Screen"). Переключатель "Zoom by 2" позволяет уменьшить размер окна в два раза.

Если включен переключатель "Skip video frames if behind", для обеспечения непрерывности звука при необходимости будут пропускаться видеокадры.

Таким образом, приложение MCIWND выполняет довольно много функций. Вы, возможно, будете удивлены тем, что исходный текст приложения занимает не более двух страниц (листинг 5.1).


Листинг 5.1. Файл mciwnd/mciwnd.c


#include <windows.h>
#include <vfw.h>

static char szAppName[]="MCIWnd";
static HWND hwnd;

// =====================================
// Функция WinMain
// =====================================
int PASCAL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpszCmdLine, int nCmdShow)
{
   MSG msg;
   WORD wVersion;

   // Проверяем версию Video for Windows
   wVersion = HIWORD(VideoForWindowsVersion());
   if(wVersion < 0x010a)
   {
     MessageBox(NULL, "Используйте Video for Windows"
        " версии 1.1 или более поздней версии",
        "MCIWnd Error", MB_OK | MB_ICONHAND);
     return FALSE;
   }

   // Создаем окно класса MCIWND
   hwnd = MCIWndCreate(NULL, hInstance,
            MCIWNDF_SHOWNAME | MCIWNDF_SHOWMODE |
            WS_OVERLAPPEDWINDOW | WS_VISIBLE, NULL);

   if(hwnd == NULL)
     return -1;

   // Устанавливаем заголовок окна
   SetWindowText(hwnd, szAppName);

   // Запускаем цикл обработки сообщений
   while(GetMessage(&msg,NULL,0,0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);

      if(!IsWindow(hwnd))
          PostQuitMessage(0);
   }
   return msg.wParam;
}

Исходный текст приложения подготовлен для трансляторов Microsoft C++ версии 7.0 или Microsoft Visual C++ версий 1.0 или 1.5, так как поставляющаяся в составе Video for Windows Development Kit библиотека vfw.lib совместима именно с этими трансляторами.

После файла windows.h в исходный текст необходимо включить файл vfw.h , который поставляется вместе с Video for Windows Development Kit. Он содержит определения всех необходимых констант, структур данных и прототипы функций.

В самом начале работы приложение вызывает функцию VideoForWindowsVersion , возвращающую в старшем слове версию Video for Windows:

wVersion = HIWORD(VideoForWindowsVersion());

Версия Video for Windows должна быть не ниже 1.1.

Далее приложение создает окно MCI, вызывая для этого функцию MCIWndCreate :

hwnd = MCIWndCreate(NULL, hInstance,
         MCIWNDF_SHOWNAME | MCIWNDF_SHOWMODE |
         WS_OVERLAPPEDWINDOW | WS_VISIBLE, NULL);

Функция MCIWndCreate позволяет определить обычные стили окна, такие как WS_OVERLAPPEDWINDOW и WS_VISIBLE, а также специфические для окна MCI - MCIWNDF_SHOWNAME и MCIWNDF_SHOWMODE. Позже мы рассмотрим подробнее эту функцию и дополнительные стили окна.

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

if(!IsWindow(hwnd)) PostQuitMessage(0);

Эта функция проверяет идентификатор окна, передаваемого ей через параметр. Если этот идентификатор правильный, возвращается TRUE. После того как пользователь уничтожит окно MCI, его идентификатор станет недействительным. В этом случае функция IsWindow вернет значение FALSE и будет вызвана функция PostQuitMessage, в результате чего работа приложения завершится.

Вот и все! По сложности исходного текста это приложение напоминает наши первые приложения из 10 тома "Библиотеки системного программиста", однако выполняемые им функции во много раз сложнее. Все дело тут, разумеется, в реализации класса окна MCI.

Файл описания ресурсов приведен в листинге 5.2.


Листинг 5.2. Файл mciwnd/mciwnd.rc


AppIcon  ICON  mciwnd.ico

Файл определения модуля для приложения MCIWND не имеет никаких особенностей (листинг 5.3).


Листинг 5.3. Файл mciwnd/mciwnd.def


NAME        MCIWNDPL
DESCRIPTION 'Приложение MCIWND, (C) 1994, Frolov A.V.'
EXETYPE     windows
STUB        'winstub.exe'
STACKSIZE   8196
HEAPSIZE    1024
CODE        preload moveable discardable
DATA        preload moveable multiple

Теперь о том, как из исходного текста создать загрузочный модуль приложения MCIWND.

При использовании транслятора Microsoft C++ версии 7.0 вы можете воспользоваться файлом makefile , представленном в листинге 5.3.


Листинг 5.3. Файл mciwnd/makefile


NAME = mciwnd
OBJ  = mciwnd.obj
LIBS = libw slibcew vfw

!if "$(DEBUG)" == "NO"
DEF     =
CLOPT   =
MASMOPT =
LINKOPT =
!else
DEF     = -DDEBUG
CLOPT   = -Zid
MASMOPT = -Zi
LINKOPT = /CO/LI
!endif

CC  = cl -c -W3 -AS -Zp -G2sw -Oxas $(DEF) $(CLOPT) -DWIN31
ASM = masm -Mx $(MASMOPT)
LINK= link /NOE/NOD/LI/MAP/AL:16/ONERROR:NOEXE $(LINKOPT)
RC  = rc 
.c.obj:
        $(CC) $*.c
.asm.obj:
        $(ASM) $*;
goal: $(NAME).exe
$(NAME).exe: $(OBJ) $(NAME).res $(NAME).def makefile
        $(LINK) $(OBJ), $(NAME), $(NAME),$(LIBS), $(NAME).def
        $(RC) -31 $(NAME).res
        -mapsym $(NAME).map
$(NAME).res: $(NAME).rc $(NAME).ico
        $(RC) -r $(NAME).rc
clean:
        del $(NAME).exe
        del *.res
        del *.obj
        del *.map
        del *.sym
        del *.pdb
copy:
        copy $(NAME).exe ..\..\bin
        copy $(NAME).sym ..\..\bin
depend:
        mv makefile makefile.old
        sed "/^# START Dependencies/,/^# END Dependencies/D" makefile.old > makefile
        del makefile.old
        echo # START Dependencies >> makefile
        includes -l *.c *.asm >> makefile
        echo # END Dependencies >> makefile

Особенностью транслятора Microsoft C++ версии 7.0 (а также версии 8.0, входящей в состав Visual C++, и трансляторов более ранних версий, запускаемых в среде MS-DOS) является использование переменных среды. Для правильной установки переменных среды подготовьте bat-файл, содежащий следующие команды (предполагается, что транслятор установлен в каталоге g:msvc, а Video for Windows Development Kit - в каталоге g:\vfwdk):

@echo off
set TOOLROOTDIR=G:\MSVC
set PATH=G:\MSVC\BIN;%PATH%
set INCLUDE=G:\MSVC\INCLUDE;g:\vfwdk\inc;%INCLUDE%
set LIB=G:\MSVC\LIB;g:\vfwdk\lib;g:\windev\lib;%LIB%
set INIT=G:\MSVC;%INIT%

Находясь в среде MS-DOS, сделайте текущим каталог, содержащий все файлы приложения MCIWND, и, после запуска приведенного выше пакетного файла, запустите программу nmake без параметров. В результате будет создан загрузочный модуль приложения.

Для того чтобы загрузочный модуль не содержал отладочной информации, добавьте в начало файла makefile следующую строку:

DEBUG = NO

Можно также запустить программу nmake с параметром DEBUG=NO:

nmake DEBUG=NO

Намного удобнее работать в среде Visual C++. Вместе с исходными текстами приложения MCIWND на дискете поставляется файл проекта mciwnd.mak, предназначенный для системы Visual C++.

Запустите Visual C++ и из меню "Project" выберите строку "Open...". С помощью появившейся диалоговой панели откройте файл проекта mciwnd.mak. Нажмите на самую левую кнопку в полосе инструментов. Появится список файлов, имеющих отношение к проекту. Выберите файл исходного текста. Возможно, что при этом вместо русских букв в окне редактирования вы увидите нечто, не поддающееся прочтению. В этом случае следует установить для редактора шрифт с русскими буквами.

Для изменения шрифта сделайте текущим окно редактирования и выберите в меню "Options" строку "Font...". На экране появится диалоговая панель "Font". Выберите в ней подходящий шрифт, имеющий русские буквы, и нажмите кнопку "Use as Default Font". При этом для всех создаваемыех вновь окон будет использоваться выбранный вами шрифт. Для завершения работы с диалоговой панелью нажмите кнопку "OK".

Не забудьте добавить пути к каталогам vfwdk\inc, wfwdk\lib и windev\lib с помощью диалоговой панели "Directories", которую можно вызвать, если в меню "Options" выбрать строку "Directories...".

После всех этих подготовительных действий выберите из меню "Project" строку "Build MCIWND.EXE". Будет запущен процесс создания загрузочного модуля (в фоновом режиме). После завершения этого процесса можно запустить приложение, выбрав из этого же меню строку "Execute MCIWND.EXE", или перейти в режим отладки, воспользовавшись меню "Debug".

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

Приложение может создать окно MCI, указав его параметры, управлять им с помощью передачи сообщений через удобный в использовании набор макрокоманд и функций, а также удалить окно MCI. Этих функций и макрокоманд так много, что мы не можем описать их все подробно из-за ограниченного объема нашей книги. Рассмотрим некоторые, самые полезные на наш взгляд, функции и макрокоманды, предназначенные для работы с окном MCI. Полную информацию вы сможете найти в документации, которая поставляется вместе с Video for Windows Development Kit.

Создание окна

Для создания окна MCI проще всего воспользоваться функцией MCIWndCreate .

Функция MCIWndCreate

HWND MCIWndCreate(
   HWND hwndParent,     // идентификатор родительского окна
   HINSTANCE hInstance, // идентификатор приложения
   DWORD dwStyle,       // стиль окна
   LPSTR szFile);       // имя устройства или путь к файлу

Параметры функции:

hwndParent

Через этот параметр приложение передает функции идентификатор родительского окна, то есть окна, создавшего окно MCI. Если родительского окна нет, в качестве этого параметра можно указать NULL

hInstance

Идентификатор приложения, полученных через параметры функции WinMain или LibMain (для DLL-библиотеки)

dwStyle

Стиль создаваемого окна. Можно указывать стили, стандартные для функции CreateWindow, а также дополнительные, список которых приведен ниже. Если стандратные стили не указаны (что допустимо), то если есть родительское окно, используются стили WS_CHILD, WS_BORDER, и WS_VISIBLE. Если же параметр hwndParent указан как NULL, используются стили WS_OVERLAPPEDWINDOW и WS_VISIBLE. Для создания невидимого окна следует использовать один из стандартных стилей, например, WS_CHILD

szFile

Указатель на текстовую строку, содержащую имя устройства (например, "cdaudio") или путь к файлу

Возвращаемое значение:

Идентификатор созданного окна при успешном завершении или NULL при ошибке

Привдем список дополнительных стилей, которые можно использовать при создании окна MCI.

Стиль Описание
MCIWNDF_NOAUTOSIZEWINDOW Размер окна не изменяется при изменении размера изображения
MCIWNDF_NOAUTOSIZEMOVIE При изменении размеров окна не следует выполнять масштабирование изображения для полного заполнения внутренней области окна
MCIWNDF_NOPLAYBAR Если задан этот стиль, не отображается полоса просмотра
MCIWNDF_NOMENU Не отображается кнопка для доступа к меню
MCIWNDF_RECORD Отображается кнопка записи, в меню добавляется строка "New"
MCIWNDF_NOERRORDLG При возникновении ошибки на экран не выводится диалогоая панель с описанием этой ошибки. Приложение может получить описание самой последней возникшей ошибки при помощи функции MCIWndGetError
MCIWNDF_NOTIFYMODE При изменении режима родительское окно получит извещающее сообщение MCIWNDM_NOTIFYMODE
MCIWNDF_NOTIFYPOS При изменении текущей позиции приложение получит извещающее сообщение MCIWNDM_NOTIFYPOS
MCIWNDF_NOTIFYMEDIA При замене носителя данных (например, звукового компакт-диска) приложение получит извещающее сообщение MCIWNDM_NOTIFYMEDIA
MCIWNDF_NOTIFYSIZE Родительское окно получит извещающее сообщение MCIWNDM_NOTIFYSIZE при изменении размера окна MCI
MCIWNDF_NOTIFYERROR При возникновении ошибки родительское окно получит сообщение MCIWNDM_NOTIFYERROR
MCIWNDF_NOTIFYALL Окно MCI будет извещать родительское окно в случае возникновения любых событий
MCIWNDF_SHOWNAME В заголовке окна будет отображаться имя устройства или путь к файлу
MCIWNDF_SHOWPOS В заголовке окна будет отображаться текущая позиция
MCIWNDF_SHOWMODE В заголовке окна будет отображаться текущий режим работы
MCIWNDF_SHOWALL Будут использованы все возможности окна MCI (то есть все органы управления, отображение информации в заголовке и т. д.)

Другой способ создания окна MCI заключается в регистрации класса окна MCIWND_WINDOW_CLASS функцией MCIWndRegisterClass , не имеющей парамеров, и создании на базе этого класса окна функцией CreateWindow . В случае успеха функция MCIWndRegisterClass возвращает значение FALSE.

Удаление окна

Если окно MCI больше не нужно, его можно удалить макрокомандой MCIWndDestroy . Идентификатор удаляемого окна MCI передается этой функции в качестве единственного параметра:

#define MCIWndDestroy(hwnd) (VOID)MCIWndSM(hwnd, WM_CLOSE, 0, 0)

Макро MCIWndSM определяется как функция SendMessage (см. файл mciwnd.h, поставляемый вместе с Video for Windows Development Kit и включаемый в файл vfw.h).

Для того чтобы закрыть устройство, открытое ранее в окне MCI без удаления окна, используйте макрокоманду MCIWndClose, передав ей идентификатор окна.

Загрузка файла или выбор устройства

При создании окна MCI вы можете указать имя устройства или файл мультимедиа, передав указатель на соответствующую текстовую строку через последний параметр функции MCIWndCreate. Можно использовать и другие способы.

Макрокоманда MCIWndOpen позволяет для созданного ранее окна открыть устройство или файл, например:

MCIWndOpen(hwnd, "push.wav", MCIWNDOPENF_NEW);

Через первый параметр передается идентификатор окна MCI, через второй - указатель на строку, содержащую имя устройства или файла. В третьем параметре при создании нового файла нужно указать флаг MCIWNDOPENF_NEW .

Напомним, что закрыть устройство или файл можно с помощью макрокоманды MCIWndClose .

Функция MCIWndOpenDialog позволяет вывести на экран диалоговую панель, с помощью которой пользователь может выбрать файл и загрузить его в окно MCI. В качестве единственного параметра этой функции следует передать идентификатор окна MCI. Функция возвращает значение 0L (размером в двойное слово) в случае успеха или код ошибки.

Для выбора файла можно также использовать функцию GetOpenFileNamePreview , входящую в программный интерфейс Video for Windows и аналогичную функции GetOpenFileName из библиотеки commdlg.dll . Диалоговая панель, появляющаяся на экране при вызове этой функции, содержит окно для предварительного прослушивания или просмотра файла (рис. 5.15).

Новый файл создается макрокомандой MCIWndNew , которой в качестве первого параметра следует передать идентификатор окна MCI, а в качестве второго - указатель на текстовую строку, содержащей имя устройства. Пример использования этой макрокоманды ести в приложении MCIWNDC, которое мы скоро рассмотрим.

Управление проигрыванием

Макрокоманда MCIWndPlay включает режим проигрывания для окна MCI, идентификатор которого передается ей в качестве единственного параметра.

Если вам нужно начать проигрывание с заданной позиции, воспользуйтесь макрокомандой MCIWndPlayFrom . Первый параметр этой макрокоманды задает идентификатор окна MCI, второй (размером в двойное слово) - позицию для начала проигрывания. Есть возможность задать конечную позицию. Макрокоманда MCIWndPlayFromTo , имеющая три параметра, аналогична макрокоманде MCIWndPlayFrom , но позволяет через третий параметр задать конечную позицию, при достижении которой проигрывание будет остановлено.

Вы даже можете запустить проигрывние в обратную сторону - от конца к началу файла (если драйвер устройства позволит вам это сделать). Достаточно вызвать макрокоманду MCIWndPlayReverse . Она имеет один параметр (идентификатор окна MCI) и запускает проигрывание от текущей позиции к началу файла.

Макрокоманда MCIWndSetRepeat позволяет включить режим циклического проигрывания. Через первый параметр этой макрокоманде передается идентификатор окна MCI, через второй для включение режима циклического проигрывания нужно передать значение TRUE.

Макрокоманды MCIWndStop и MCIWndPause предназначены для выполнения, соответственно, останова и временного останова проигрывания. Для того чтобы продолжить проигрывание после временного останова, используйте макрокоманду MCIWndResume . Все три макрокоманды имеют только один параметр - идентификатор окна MCI.

Управление записью и сохранение данных

Для включения режима записи с текущей позиции предназначена макрокоманда MCIWndRecord . В качестве единственного параметра ей нужно передать идентификатор окна MCI. С помощью этой макрокоманды вы сможете организовать запись звуковых данных (как это сделано в нашем приложении MCIWNDC, которое мы рассмотрим чуть позже).

С помощью окна MCI вы не можете записывать avi-файлы, для этого предназначено окно класса AVICap.

Для сохранения записанных данных можно воспользоваться макрокомандами MCIWndSave или MCIWndSaveDialog .

Макрокоманда MCIWndSave имеет два параметра - идентификатор окна MCI и указатель на текстовую строку, в которой должен находиться путь к файлу. Записанные данные будут сохранены в этом файле.

При вызове макрокоманды MCIWndSaveDialog , имеющий один параметр (идентификатор окна MCI) на экран выводится диалоговая панель, позволяющая пользователю сохранить данные в файле. Это модифицированная диалоговая панель "Save As..." с возможностью предварительного просмотра или прослушивания содержимого файлов мультимедиа. Кстати, эту же панель вы можете вывести и отдельно с помощью функции GetSaveFileNaamePreview , аналогичной функции GetSaveFileName из библиотеки commdlg.dll.

Позиционирование

Макрокоманда MCIWndSeek позволяет установить новую позицию для окна MCI, идентификатор которого передается ей в качестве первого параметра (здесь имеется в виду не расположение окна MCI на экране, а текущая позиция при проигрывании мультимедиа-файла). Через второй параметр передается значение новой позиции в формате двойного слова.

Макрокоманды MCIWndHome и MCIWndEnd позволяют установить текущую позицию, соотетственно, в начало и конец. Обе эти макрокоманды имеют только один параметр - идентификатор окна MCI.

С помощью макрокоманды MCIWndStep можно выполнить продвижение текущей позиции на один шаг. Величина шага задается в формате двойного слова в качестве второго параметра. Первый параметр - как всегда, идентификатор окна MCI.

Другие макрокоманды

Перечислим некоторые другие полезные макрокоманды, имеющие отношение к окну MCI.

Макрокоманды MCIWndCanConfig , MCIWndCanEject , MCIWndCanPlay , MCIWndCanRecord , MCIWndCanSave , MCIWndCanWindow позволяют определить, соответственно, возможность конфигурирования, автоматической смены носителя, проигрывания, записи, сохранения и проигрывания в окне. Все эти макрокоманды имеют один параметр - идентификатор окна MCI. Если та или иная возможность поддерживается, соответствующая макрокоманда возвращает значение TRUE, в противном случае FALSE.

В любой момент времени приложение может изменить стиль окна MCI, вызвав макрокоманду MCIWndChangeStyles . Пример испльзования этой макрокоманды есть в приложении MCIWNDC (см. ниже). Для определения текущего стиля окна MCI можно воспользоваться макрокомандой MCIGetStyles .

Несколько макрокоманд предназначены для определения характеристик файла или такого носителя данных, как звуковой компакт-диск, загруженного в окно MCI. С помощью макрокоманд MCIWndGetLength , MCIWndGetStart , MCIWndGetEnd , MCIWndGetPosition , MCIWndGetPositionString приложение может определить, соотетственно, длину файла, начальную позицию, конечную позицию, текущую позицию и текущую позицию в виде текстовой строки.

Приложение может установить скорость проигрывания, громкость и размеры окна MCI, вызвав, соответственно, макрокоманды MCIWndSetSpeed , MCIWndSetVolume , MCIWndSetZoom . Есть макрокоманды, с помощью которых можно определить текущее значение для скорости проигрывания, громкости и размеров окна MCI - MCIWndGetSpeed , MCIWndGetVolume и MCIWndGetZoom .

Есть макрокоманды для изменения формата времени и определени текущего формата времени (MCIWndSetTimeFormat , MCIWndGetTimeFormat , MCIWndUseFrames , MCIWndUseTime ), для обновления информации о позиции при замене носителя данных (MCIWndValidateMedia ), для работы с таймером, палитрами и некоторые другие.

Если же этого обширного списка все же не хватит, то с помощью макрокоманды MCIWndSendString вы сможете передать окну любую команду MCI, лишь бы ее поддерживало используемое устройство. Ответ драйвера на посланную команду можно получить в виде текстовой строки при помощи макрокоманды MCIWndReturnString .

Извещения для родительского окна

При создании окна MCI вы можете указать (определив соответствующие стили), что в случае возникновения ошибки, замены носителя данных, изменения режима, текущей позиции или размера окна отображения родительское окно должно получать извещающие сообщения. Рассмотрим эти сообщения.

MCIWNDM_NOTIFYERROR

Сообщение MCIWNDM_NOTIFYERROR передается родительскому окну при возникновении ошибки. Параметр wParam содержит идентификатор окна MCI, параметр lParam - указатель на текстовую строку с описанием ошибки.

MCIWNDM_NOTIFYMEDIA

При изменении носителя данных (устройства или файла) родительское окно получает сообщение MCIWNDM_NOTIFYMEDIA . Параметр lParam содержит указатель на текстовую строку с именем файла или устройства. Если устройство или файл закрыты, этот параметр имеет значение NULL. Параметр wParam не используется.

MCIWNDM_NOTIFYMODE

При изменении режима работы родительское окно получает сообщение MCIWNDM_NOTIFYMODE , причем код нового режима находится в параметре lParam. Параметр wParam не используется.

MCIWNDM_NOTIFYPOS

Сообщение MCIWNDM_NOTIFYPOS передается родительскому окну при изменении текущей позиции. Новая позиция находится в параметре lParam. Параметр wParam не используется.

MCIWNDM_NOTIFYSIZE

Если пользователь изменил размер окна MCI, родительское окно получает сообщение MCIWNDM_NOTIFYSIZE . Параметр wParam содержит идентификатор окна MCI, параметр lParam не используется и равен нулю.

Приложение MCIWNDC

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

Приложение MCIWNDC (рис. 5.18) может проигрывать avi- и wav-файлы, файлы в стандарте MIDI, а также дорожки звуковых компакт-дисков. Кроме этого, приложение может записывать wav-файлы.

Рис. 5.18. Меню "File" приложения MCIWNDC

Для проигрывания файлов мультимедиа их следует открыть при помощи строки "Open..." меню "File". При этом на экран будет выведена диалоговая панель "Open" с возможностью предварительного просмотра или прослушивания содержимого файла (рис. 5.19).

Рис. 5.19. Диалоговая панель "Open" приложения MCIWNDC

Меню "Movie" (рис. 5.20) и "Styles" (рис. 5.22) предназначены для управления окном MCI.

Рис. 5.20. Меню "Movie" приложения MCIWNDC

Строки "Play", "Play Reverse", "Record" и "Stop" предназначены, соответственно, для проигрывания, проигрывания в обратном направлении, записи и выполнения останова.

С помощью строк "Home" и "End" выполняется позиционирование на начало и конец файла. Строки "Step Fwrd" и "Step Back" дают возможность выполнять пошаговое перемещение вперед и назад.

Выбрав строку "Info...", вы увидите на экране диалоговую панель "Media Info" (рис. 5.21), в которой будет отображено имя устройства, путь к загруженному в окно MCI файлу и размер этого файла.

Рис. 5.21. Диалоговая панель "Media Info"

С помощью строки "Play Bar" меню "Styles" (рис. 5.22) вы можете убрать или возвратить на место органы управления окном MCI.

Рис. 5.22. Меню "Styles" приложения MCIWNDC

Диалоговая панель, используемая при сохранении записанных wav-файлов, содержит средства предварительного просмотра или прослушивания (рис. 5.23).

Рис. 5.23. Диалоговая панель "Save As..." приложения MCIWNDC

Приложение MCIWNDC способно также проигрывать дорожки звуковых компакт-дисков. Внешний вид окна MCI, которое используется для этого, показан на рис. 5.24.

Рис. 5.24. Окно MCI для проигрывания дорожек звукового компакт-диска

Несмотря на обилие возможностей, исходный текст приложения MCIWNDC занимает немного места (листинг 5.4).


Листинг 5.4. Файл mciwndc/mciwndc.cpp


// ------------------------------------------------
// Приложение MCIWNDC
// Использование класса окна MCIWnd для 
// проигрывания и записи файлов мультимедиа
// ------------------------------------------------

#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <memory.h>
#include <vfw.h>
#include "mciwndc.h"

// Прототипы функций
BOOL    InitApp(HINSTANCE);
LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL mciwndSelectFile(LPSTR lpszFileName);

// Глобальные переменные
char const szClassName[]   = "MCIWNDCClass";
char const szMovieClass[]  = MCIWND_WINDOW_CLASS;
char const szWindowTitle[] = "MCIWnd Player & Recorder";
HINSTANCE  hInst;
HWND hwndMovie = NULL;

// =====================================
// Функция WinMain
// =====================================
int PASCAL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpszCmdLine, int nCmdShow)
{
  MSG  msg;      // структура для работы с сообщениями
  HWND hwnd;     // идентификатор главного окна приложения
  WORD wVersion; // версия Video for Windows

  if(hPrevInstance)
    return FALSE;

  // Проверяем версию Video for Windows
  wVersion = HIWORD(VideoForWindowsVersion());
  if(wVersion < 0x010a)
  {
    MessageBox(NULL, "Используйте Video for Windows"
        " версии 1.1 или более поздней версии",
        "MCIWnd Error", MB_OK | MB_ICONHAND);
    return FALSE;
  }

  if(!InitApp(hInstance))
    return FALSE;
    
  hInst = hInstance;

  hwnd = CreateWindow(
    szClassName,         // имя класса окна
    szWindowTitle,       // заголовок окна
    WS_OVERLAPPEDWINDOW, // стиль окна
    CW_USEDEFAULT,       // размеры и расположение окна
    CW_USEDEFAULT,       
    400, 350, 0, 0, hInstance, NULL);
                       
  if(!hwnd)
    return FALSE;

  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  while(GetMessage(&msg, 0, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

// =====================================
// Функция InitApp
// Выполняет регистрацию класса окна
// =====================================

BOOL InitApp(HINSTANCE hInstance)
{
  ATOM aWndClass; // атом для кода возврата
  WNDCLASS wc;    // структура для регистрации

  memset(&wc, 0, sizeof(wc));
  wc.lpszMenuName  = "APP_MENU";
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = (WNDPROC) WndProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon(hInstance, "APPICON");
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wc.lpszClassName = (LPSTR)szClassName;

  aWndClass = RegisterClass(&wc);
  return (aWndClass != 0);
}

// =====================================
// Функция WndProc
// =====================================

LRESULT CALLBACK _export
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
  {
// ------------------------------------------------------------
// WM_INITMENU
// Инициализация меню
// ------------------------------------------------------------
    case WM_INITMENU:
    {                                       
      // Определяем стиль окна MCI  
      WORD wStyles = MCIWndGetStyles(hwndMovie);
      
      // Если окно MCI имеет панель управления,
      // отмечаем строку "Play Bar" меню "Styles"
      CheckMenuItem(GetMenu(hwnd), CM_STPBAR, 
        (wStyles & MCIWNDF_NOPLAYBAR) ? MF_UNCHECKED : MF_CHECKED);
      return 0;
    }

// ------------------------------------------------------------
// WM_COMMAND
// Обработка сообщений от меню
// ------------------------------------------------------------
    case WM_COMMAND:
    {
      switch (wParam)
      {
        // -------------------------------------------------
        // Строка "About" меню "Help"
        // -------------------------------------------------
        case CM_HELPABOUT:
        {
          MessageBox(hwnd,
            "MCIWnd Player & Recorder, v.1.0\n"
            "(C) Frolov A.V., 1994",
            "About MCIWNDC", MB_OK | MB_ICONINFORMATION);
          return 0;
        }

        // -------------------------------------------------
        // Строка "New Waveaudio" меню "File"
        // -------------------------------------------------
        case CM_FILENEW:
        {
          // Если окно MCI уже было создано, удаляем его
          if(hwndMovie)
            MCIWndDestroy(hwndMovie);

          // Создаем новое окно для записи звука,
          // открываем драйвер устройства waveaudio
          hwndMovie = MCIWndCreate(
            hwnd, hInst,
            WS_VISIBLE | WS_CHILD | WS_BORDER |
            MCIWNDF_RECORD, 
            (LPSTR)"waveaudio");
             
          // Создаем новый файл
          MCIWndNew(hwndMovie, "waveaudio");
          return 0;
        }

        // -------------------------------------------------
        // Строка "Save Waveaudio As..." меню "File"
        // -------------------------------------------------
        case CM_FILESAVEAS:
        {
          // Создаем диалоговую панель "Save As..." для
          // сохранения файла
          MCIWndSaveDialog(hwndMovie);
          return 0;
        }

        // -------------------------------------------------
        // Строка "CD Audio" меню "File"
        // -------------------------------------------------
        case CM_FILECDAUDIO:
        {
          // Если окно MCI уже было создано, удаляем его
          if(hwndMovie)
            MCIWndDestroy(hwndMovie);

          // Создаем новое окно для проигрывания CD,
          // открываем драйвер устройства cdaudio
          hwndMovie = MCIWndCreate(
            hwnd, hInst,
            WS_VISIBLE | WS_CHILD | WS_BORDER |
            MCIWNDF_RECORD, 
            (LPSTR)"cdaudio");
          return 0;
        }

        // -------------------------------------------------
        // Строка "Open" меню "File"
        // -------------------------------------------------
        case CM_FILEOPEN:
        {
          char szBuff[256];
          
          // Если окно MCI уже было создано, удаляем его
          if(hwndMovie)
            MCIWndDestroy(hwndMovie);
          
          // Выбираем файл для загрузки в окно MCI
          if(mciwndSelectFile(szBuff))
          {
             // Создаем окно MCI
             hwndMovie = MCIWndCreate(
               hwnd, hInst,
               WS_VISIBLE | WS_CHILD | WS_BORDER |
               MCIWNDF_RECORD,
               (LPSTR)szBuff);
          }
          return 0;
        }

        // -------------------------------------------------
        // Строка "Close" меню "File"
        // -------------------------------------------------
        case CM_FILECLOSE:
        {
          // Удаляем окно MCI
          MCIWndDestroy(hwndMovie);
          hwndMovie = NULL;
          return 0;
        }

        // -------------------------------------------------
        // Меню "Movie"
        // -------------------------------------------------
        case CM_MVIPLAY:    // "Play"
        {
          // Проигрывание
          MCIWndPlay(hwndMovie);
          return 0;
        }

        case CM_MVIRPLAY:   // "Play Reverse"
        {
          // Проигрывание в обратном направлении
          MCIWndPlayReverse(hwndMovie);
          return 0;
        }

        case CM_MVISTOP:    // "Stop"
        {
          // Останов
          MCIWndStop(hwndMovie);
          return 0;
        }

        case CM_MVIRECORD:  // "Record"
        {
          // Запись
          MCIWndRecord(hwndMovie);
          return 0;
        }             
        
        case CM_MVIHOME:    // "Home"
        {
          // Позиционирование в начало
          MCIWndHome(hwndMovie);
          return 0;
        }

        case CM_MVIEND:     // "End"
        {
          // Позиционирование в конец
          MCIWndEnd(hwndMovie);
          return 0;
        }

        case CM_MVISTEP:    // "Step Fwrd"
        {
          // Шаг вперед
          MCIWndStep(hwndMovie, 1);
          return 0;
        }

        case CM_MVIRSTEP:   // "Step Back"
        {
          // Шаг назад
          MCIWndStep(hwndMovie, -1);
          return 0;
        }

        case CM_MVIINFO:    // "Info..."
        {              
          char szBuff[512], szBuff1[256];
          long dwSize;
          
          // Если окно MCI создано, выводим информацию
          // о загруженном в него файле
          if(hwndMovie)
          {
            // Имя устройства
            MCIWndGetDevice(hwndMovie, (LPSTR)szBuff, 512);
            lstrcat(szBuff, (LPSTR)"\n");
          
            // Путь к файлу или имя устройства
            MCIWndGetFileName(hwndMovie, (LPSTR)szBuff1, 256);
            lstrcat(szBuff, (LPSTR)szBuff1);
            lstrcat(szBuff, (LPSTR)"\n");

            // Размер файла
            dwSize = MCIWndGetLength(hwndMovie);
            wsprintf(szBuff1, "Size: %ld ", (long)dwSize);
            lstrcat(szBuff, (LPSTR)szBuff1);

            // Формат времени
            MCIWndGetTimeFormat(hwndMovie, (LPSTR)szBuff1, 256);
            lstrcat(szBuff, (LPSTR)szBuff1);

            MessageBox(hwnd, szBuff,
              "Media Info", MB_OK | MB_ICONINFORMATION);
          }
          return 0;
        }
        // -------------------------------------------------
        // Меню "Styles"
        // -------------------------------------------------
        case CM_STPBAR:     // "Play Bar"
        {
          // Определяем стили окна MCI
          WORD wStyles = MCIWndGetStyles(hwndMovie);
      
          // Инвертируем состояние стиля MCIWNDF_NOPLAYBAR
          MCIWndChangeStyles(hwndMovie, MCIWNDF_NOPLAYBAR, 
            (wStyles & MCIWNDF_NOPLAYBAR) ? 0 : MCIWNDF_NOPLAYBAR);
          return 0;
        }

        // -------------------------------------------------
        // Строка "Exit" меню "File"
        // Завершение работы приложения
        // -------------------------------------------------
        case CM_FILEEXIT:
        {
          DestroyWindow(hwnd);
          return 0;
        }
        default:
          return 0;
      }
    }

    // Отслеживаем изменения в системной палитре
    case WM_PALETTECHANGED:
    {
      SendMessage(hwndMovie, msg, wParam, lParam);
      break;
    }
    case WM_QUERYNEWPALETTE:
    {
      return SendMessage(hwndMovie, msg, wParam, lParam);
    }

// ------------------------------------------------------------
// WM_DESTROY
// Уничтожение главного окна приложения
// ------------------------------------------------------------
    case WM_DESTROY:
    {
      PostQuitMessage(0);
      return 0;
    }
    default:
      break;
  }
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

//-----------------------------------------------------
// mciwndSelectFile
// Выбор файла
//-----------------------------------------------------
BOOL mciwndSelectFile(LPSTR lpszFileName)
{
  OPENFILENAME ofn;

  char szFile[256];
  char szFileTitle[256];
  char szFilter[256] =
     "Video Files\0*.avi\0"
     "Waveaudio Files\0*.wav\0"
     "MIDI Files\0*.mid;*.rmi\0"
     "Any Files\0*.*\0";
  szFile[0] = '\0';
  memset(&ofn, 0, sizeof(OPENFILENAME));

  // Инициализируем нужные нам поля
  ofn.lStructSize       = sizeof(OPENFILENAME);
  ofn.hwndOwner         = NULL;
  ofn.lpstrFilter       = szFilter;
  ofn.nFilterIndex      = 1;
  ofn.lpstrFile         = szFile;
  ofn.nMaxFile          = sizeof(szFile);
  ofn.lpstrFileTitle    = szFileTitle;
  ofn.nMaxFileTitle     = sizeof(szFileTitle);
  ofn.lpstrInitialDir   = NULL;
  ofn.Flags =   OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST
               | OFN_HIDEREADONLY;
  // Выбираем входной файл
  if (GetOpenFileNamePreview(&ofn))
  {
    // Копируем путь к выбранному файлу
    lstrcpy(lpszFileName, (LPSTR)szFile);
    return TRUE;
  }
  else
    return FALSE;
}

После проверки версии Video for Windows функция WinMain создает обычным образом главное окно приложения MCIWNDC и запускает цикл обработки сообщений. Эта часть приложения не имеет каких-либо особенностей.

При выборе строки "New Waveaudio" из меню "File" проверяется содержимое глобальной переменной hwndMovie, в которой хранится идентификатор окна MCI. Сразу после запуска приложения эта переменная содержит нулевое значение.

Если же окно MCI было создано ранее, оно удаляется при помощи макрокоманды MCIWndDestroy:

if(hwndMovie)
  MCIWndDestroy(hwndMovie);

Далее создается окно MCI, причем одновременно открывается устройство waveaudio:

hwndMovie = MCIWndCreate(
  hwnd, hInst,
  WS_VISIBLE | WS_CHILD | WS_BORDER |
  MCIWNDF_RECORD, 
  (LPSTR)"waveaudio");

Создаваемое при этом окно MCI является видимым, дочерним и имеет рамку. Среди органов управления присутствует кнопка записи, так как указан стиль окна MCIWNDF_RECORD.

Затем создается новый файл, для чего используется макрокоманда MCIWndNew:

MCIWndNew(hwndMovie, "waveaudio");

Сохранение записанных звуковых данных выполняется очень просто - с помощью макрокоманды MCIWndSaveDialog, позволяющей пользователю выбрать путь и имя файла:

MCIWndSaveDialog(hwndMovie);

При выборе строки "CD Audio" в меню "File" окно MCI создается следующим образом:

hwndMovie = MCIWndCreate(
  hwnd, hInst,
  WS_VISIBLE | WS_CHILD | WS_BORDER |
  MCIWNDF_RECORD, 
  (LPSTR)"cdaudio");

Обратите внимание, что указан стиль MCIWNDF_RECORD. Так как драйвер устройства чтения компакт-дисков не поддерживает (увы!) операцию записи, среди органов управления окна MCI кнопка записи так и не появится. Поэтому при создании собственного приложения для проигрывания компакт-дисков средствами окна MCI вам не нужно указывать этот стиль.

Если приложение MCIWNDC используется для проигрывания файла, окно MCI создается при выборе строки "Open..." в меню "File". В этом случае приложение вызывает функцию mciwndSelectFile, которая позволяет пользователю выбрать файл и записывает путь к файлу в переменную szBuff. Далее окно MCI создается следующим образом:

hwndMovie = MCIWndCreate(
  hwnd, hInst,
  WS_VISIBLE | WS_CHILD | WS_BORDER |
  MCIWNDF_RECORD,
  (LPSTR)szBuff);

При создании окна MCI указан стиль MCIWNDF_RECORD, однако кнопка записи появится только при загрузке wav-файла, так как запись средствами окна MCI возможна только для устройства "waveaudio".

При выборе из меню "File" строки "Close" окно MCI удаляется функцией MCIWndDestroy.

Обработка сообщений от меню "Movie" сводится в основном к вызову соответствующей макрокоманды. Например, при выборе из этого меню строки "Play" вызывается макрокоманда MCIWndPlay:

case CM_MVIPLAY:    // "Play"
{
  MCIWndPlay(hwndMovie);
  return 0;
}

Аналогичным образом обрабатываются остальные команды, за исключением команд позиционирования на один шаг вперед и один шаг назад:

case CM_MVISTEP:    // "Step Fwrd"
{
  MCIWndStep(hwndMovie, 1);
  return 0;
}
case CM_MVIRSTEP:   // "Step Back"
{
  MCIWndStep(hwndMovie, -1);
  return 0;
}

Второй параметр макрокоманды MCIWndStep указывает величину шага в миллисекундах или кадрах (в зависимости от текущего формата времени), причем отрицательным значениям соответствует позиционирование в обратном направлении.

При выборе из меню "Movie" строки "Info..." приложение определяет и выводит на экран информацию об используемом устройстве и загруженном файле.

Для определения имени устройства используется макрокоманда MCIWndGetDevice :

MCIWndGetDevice(hwndMovie, (LPSTR)szBuff, 512);

Через первый параметр этой макрокоманде передается идентификатор окна MCI. Второй параметр - указатель на буфер, в который следует записать имя устройства. Третий параметр - размер буфера.

Путь к загруженному устройству или имя устройства (если файл не используется) определяется с помощью макрокоманды MCIWndGetFileName аналогичным образом:

MCIWndGetFileName(hwndMovie, (LPSTR)szBuff1, 256);

Размер файла вычисляется макрокомандой MCIWndGetLength , возвращающей значение в формате двойного слова:

dwSize = MCIWndGetLength(hwndMovie);

Единица измерения размера зависит от текущего формата времени, который определяется в виде текстовой строки при помощи макрокоманды MCIWndGetTimeFormat :

MCIWndGetTimeFormat(hwndMovie, (LPSTR)szBuff1, 256);

Теперь о меню "Styles".

При выборе из этого меню строки "Play Bar" приложение определяет текущий стили окна, и затем инвертирует стиль MCIWNDF_NOPLAYBAR:

case CM_STPBAR:     // "Play Bar"
{
  WORD wStyles = MCIWndGetStyles(hwndMovie);
  MCIWndChangeStyles(hwndMovie, MCIWNDF_NOPLAYBAR, 
    (wStyles & MCIWNDF_NOPLAYBAR) ? 0 : MCIWNDF_NOPLAYBAR);
  return 0;
}

Правильную отметку строки "Play Bar" в меню обеспечивает обработчик сообщения WM_INITMENU:

case WM_INITMENU:
{                                       
  WORD wStyles = MCIWndGetStyles(hwndMovie);
  CheckMenuItem(GetMenu(hwnd), CM_STPBAR, 
    (wStyles & MCIWNDF_NOPLAYBAR) ? MF_UNCHECKED : MF_CHECKED);
  return 0;
}

Этот обработчик отмечает или нет строку "Play Bar" меню "Styles" в зависимости от того, имеет ли окно MCI стиль MCIWNDF_NOPLAYBAR, или нет.

Обработка сообщений об изменении системной палитры WM_PALETTECHANGED и о необходимости реализации палитры WM_QUERYNEWPALETTE заключается в непосредственной передаче соответствующих сообщений окну MCI, поэтому выполняется очень просто:

case WM_PALETTECHANGED:
{
  SendMessage(hwndMovie, msg, wParam, lParam);
  break;
}
case WM_QUERYNEWPALETTE:
{
  return SendMessage(hwndMovie, msg, wParam, lParam);
}

Файл mciwndc.h (листинг 5.5) содержит определения констант, используемых в приложении MCIWNDC.


Листинг 5.5. Файл mciwndc/mciwndc.h


#define CM_HELPABOUT   301
#define CM_FILEEXIT    302
#define CM_FILEOPEN    303
#define CM_FILECLOSE   304
#define CM_FILENEW     305
#define CM_FILESAVEAS  306
#define CM_FILECDAUDIO 307

#define CM_MVIPLAY     401
#define CM_MVIRPLAY    402
#define CM_MVIHOME     403
#define CM_MVIEND      404
#define CM_MVISTEP     405
#define CM_MVIRSTEP    406
#define CM_MVISTOP     407
#define CM_MVIRECORD   408
#define CM_MVIINFO     409

#define CM_STPBAR      501

Файл определения ресурсов приложения представлен в листинге 5.6.


Листинг 5.6. Файл mciwndc/mciwndc.rc


#include "mciwndc.h"
AppIcon ICON mciwndc.ico
APP_MENU MENU 
BEGIN
  POPUP "&File"
    BEGIN
      MENUITEM "&Open...",       CM_FILEOPEN
      MENUITEM "&Close",         CM_FILECLOSE
      MENUITEM SEPARATOR
      MENUITEM "&New Waveaudio", CM_FILENEW
      MENUITEM "Save Waveaudio &As...", CM_FILESAVEAS
      MENUITEM SEPARATOR
      MENUITEM "CD Audio",       CM_FILECDAUDIO
      MENUITEM SEPARATOR
      MENUITEM "E&xit",          CM_FILEEXIT
    END

  POPUP "&Movie"
    BEGIN
      MENUITEM "&Play",         CM_MVIPLAY
      MENUITEM "Play &Reverse", CM_MVIRPLAY
      MENUITEM "R&ecord",       CM_MVIRECORD
      MENUITEM "&Stop",         CM_MVISTOP
      MENUITEM SEPARATOR
      MENUITEM "&Home",         CM_MVIHOME
      MENUITEM "&End",          CM_MVIEND
      MENUITEM SEPARATOR
      MENUITEM "Step &Fwrd",    CM_MVISTEP
      MENUITEM "Step &Back",    CM_MVIRSTEP
      MENUITEM SEPARATOR
      MENUITEM "&Info...",      CM_MVIINFO
    END
  POPUP "St&yles"
    BEGIN
      MENUITEM "&Play Bar",     CM_STPBAR
    END

  POPUP "&Help"
    BEGIN
      MENUITEM "&About...", CM_HELPABOUT
    END
END

Файл определения модуля приложения MCIWNDC представлен в листинге 5.7.


Листинг 5.7. Файл mciwndc/mciwndc.def


NAME        MCIWNDC
DESCRIPTION 'Приложение MCIWNDC, (C) 1994, Frolov A.V.'
EXETYPE     windows
STUB        'winstub.exe'
STACKSIZE   10240
HEAPSIZE    1024
CODE        preload moveable discardable
DATA        preload moveable multiple

Для трансляции приложения в среде MS-DOS системой Microsoft C++ версии 7.0 или 8.0 (входящий в Visual C++ версии 1.0) вы можете использовать makefile, представленный в листинге 5.8.


Листинг 5.8. Файл mciwndc/makefile


NAME = mciwndc
OBJ  = mciwndc.obj
LIBS = libw slibcew commdlg vfw

!if "$(DEBUG)" == "NO"
DEF     =
CLOPT   =
MASMOPT =
LINKOPT =
!else
DEF     = -DDEBUG
CLOPT   = -Zid
MASMOPT = -Zi
LINKOPT = /CO/LI
!endif

CC  = cl -c -W3 -AS -Zp -G2sw -Oxas $(DEF) $(CLOPT) -DWIN31
ASM = masm -Mx $(MASMOPT)
LINK= link /NOE/NOD/LI/MAP/AL:16/ONERROR:NOEXE $(LINKOPT)
RC  = rc 
.c.obj:
        $(CC) $*.c
.asm.obj:
        $(ASM) $*;
goal: $(NAME).exe
$(NAME).exe: $(OBJ) $(NAME).res $(NAME).def makefile
        $(LINK) $(OBJ), $(NAME), $(NAME),$(LIBS), $(NAME).def
        $(RC) -31 $(NAME).res
        -mapsym $(NAME).map
$(NAME).res: $(NAME).rc
        $(RC) -r $(NAME).rc
clean:
        del $(NAME).exe
        del *.res
        del *.obj
        del *.map
        del *.sym
        del *.pdb
copy:
        copy $(NAME).exe ..\..\bin
        copy $(NAME).sym ..\..\bin
depend:
        mv makefile makefile.old
        sed "/^# START Dependencies/,/^# END Dependencies/D" makefile.old > makefile
        del makefile.old
        echo # START Dependencies >> makefile
        includes -l *.c *.asm >> makefile
        echo # END Dependencies >> makefile

[Назад] [Содеожание] [Дальше]