Создание полученного компонента обработчика носителей
В этой главе описываются процесс создания полученного компонента обработчика носителей. Это обеспечивает пример создания полученного компонента обработчика носителей и определяет его компонент и флаги запроса. Функциональный интерфейс, который должен поддерживать Ваш полученный компонент обработчика носителей, описан в Полученной Поддержке Обработчика Носителей.
Прежде, чем считать этот раздел, необходимо быть знакомы с тем, как создать компоненты.
Apple определил MediaHandlerType значение типа компонента ('mhlr') для компонентов обработчика носителей. Все компоненты этого типа имеют то же значение типа.
Apple также определил функциональный интерфейс для полученных компонентов обработчика носителей. Для получения информации о функциях, которые должен поддерживать Ваш компонент, посмотрите Полученную Поддержку Обработчика Носителей.
Демонстрационный полученный компонент обработчика носителей
Этот раздел предоставляет пример программы, реализующий полученный компонент обработчика носителей для изображений PICT.
Реализация требуемых функций компонента
Перечисление 2-1 предоставляет диспетчеров компонента для компонента обработчика носителей для изображений PICT вместе с требуемыми функциями.
Перечисление 2-1 Реализовывая требуемые компонентные функции обработчика носителей
typedef struct { |
ComponentInstance self; |
ComponentInstance parent; |
ComponentInstance delegateComponent; |
Fixed width; |
Fixed height; |
MatrixRecord matrix; |
Media media; |
Track track; |
} PictGlobalsRecord, *PictGlobals; |
pascal ComponentResult PictMediaDispatch (ComponentParameters *params, |
Handle storage) |
{ |
OSErr err = badComponentSelector; |
ComponentFunction componentProc = 0; |
switch (params->what) { |
case kComponentOpenSelect: |
componentProc = PictOpen; break; |
case kComponentCloseSelect: |
componentProc = PictClose; break; |
case kComponentCanDoSelect: |
componentProc = PictCanDo; break; |
case kComponentVersionSelect: |
componentProc = PictVersion; break; |
case kComponentTargetSelect: |
componentProc = PictVersion; break; |
case kMediaInitializeSelect: |
componentProc = PictInitialize; break; |
case kMediaIdleSelect: |
componentProc = PictIdle; break; |
case kMediaSetDimensionsSelect: |
componentProc = PictSetDimensions; break; |
case kMediaSetMatrixSelect: |
componentProc = PictSetMatrix; break; |
} |
if (componentProc) |
err = CallComponentFunctionWithStorage (storage, params, |
componentProc); |
else |
err = DelegateComponentCall (params, ((PictGlobals) |
storage)->delegateComponent); |
return err; |
} |
pascal ComponentResult PictCanDo (PictGlobals globals, |
short ftnNumber) |
{ |
switch (ftnNumber) { |
case kComponentOpenSelect: |
case kComponentCloseSelect: |
case kComponentCanDoSelect: |
case kComponentVersionSelect: |
case kComponentTargetSelect: |
case kMediaInitializeSelect: |
case kMediaIdleSelect: |
case kMediaSetDimensionsSelect: |
case kMediaSetMatrixSelect: |
return true; |
default: |
return ComponentFunctionImplemented |
(globals->delegateComponent, ftnNumber); |
} |
} |
pascal ComponentResult PictVersion (PictGlobals globals) |
{ |
return 0x00020001; |
} |
pascal ComponentResult PictOpen(PictGlobals globals, |
ComponentInstance self) |
{ |
OSErr err; |
/* allocate storage */ |
globals = (PictGlobals)NewPtrClear(sizeof(PictGlobalsRecord)); |
if (err = MemError()) return err; |
SetComponentInstanceStorage(self, (Handle)globals); |
globals->self = self; |
globals->parent = self; |
/* find a base media handler to serve as a delegate */ |
globals->delegateComponent = |
OpenDefaultComponent (MediaHandlerType, |
BaseMediaType); |
if (globals->delegateComponent) |
PictTarget(globals, self); /* set up the calling chain */ |
else { |
DisposePtr((Ptr)globals); |
err = cantOpenHandler; |
} |
return err; |
} |
pascal ComponentResult PictClose (PictGlobals globals, |
ComponentInstance self) |
{ |
if (globals) { |
if (globals->delegateComponent) |
CloseComponent(globals->delegateComponent); |
DisposePtr((Ptr)globals); |
} |
return noErr; |
} |
pascal ComponentResult PictTarget(PictGlobals store, |
ComponentInstance parentComponent) |
{ |
/* remember who is at the top of your calling chain */ |
store->parent = parentComponent; |
/* and inform your delegate component of the change */ |
ComponentSetTarget(store->delegateComponent, parentComponent); |
return noErr; |
} |
Инициализация полученного компонента обработчика носителей
Полученный компонент обработчика носителей инициализируется вызовом Панели инструментов Фильма MediaInitialize функция. Необходимо тогда сообщить о полученных возможностях обработчика носителей основному обработчику носителей, прежде чем Панель инструментов Фильма начнет работать с носителями путем вызова MediaSetHandlerCapabilities функция от Вашего MediaInitialize функция.
Перечисление 2-2 является функцией инициализации для полученного обработчика носителей. PictInitialize функционируйте хранит начальную высоту, ширину, матрицу фильма дорожки, носители и дорожку полученного компонента обработчика носителей. От PictInitialize, MediaSetHandlerCapabilities функция вызвана для информирования основного обработчика носителей о ее существовании и функциях.
Перечисление 2-2 , Инициализирующее полученный обработчик носителей
pascal ComponentResult PictInitialize (PictGlobals store, |
GetMovieCompleteParams *gmc) |
{ |
/* remember some useful parameters */ |
store->width = gmc->width; |
store->height = gmc->height; |
store->matrix = gmc->trackMovieMatrix; |
store->media = gmc->theMedia; |
store->track = gmc->theTrack; |
/* tell the base media handler about your derived |
media handler */ |
MediaSetHandlerCapabilities(store->delegateComponent, |
handlerHasSpatial, handlerHasSpatial); |
return noErr; |
} |
Рисование выборки носителей
Панель инструментов Фильма обеспечивает время обработки для Вашего полученного обработчика носителей для отображения выборок путем вызова MediaIdle функция. Ваш обработчик носителей может использовать это время для игры его выборки носителей. Код в Перечислении 2-3 позволяет полученному компоненту обработчика носителей рисовать текущую выборку носителей (в этом случае, изображение PICT).
Перечисление 2-3 , Получающее выборку носителей
pascal ComponentResult PictIdle (PictGlobals store, |
TimeValue atMediaTime, |
long flagsIn, long *flagsOut, |
const TimeValue *tr) |
{ |
OSErr err; |
Rect r; |
Handle sample = NewHandle (0); |
if (err = MemError()) goto bail; |
/* get the current sample */ |
err = GetMediaSample (store->media, sample, 0, nil, |
atMediaTime, nil, 0, 0, 0, 0, 0, 0); |
if (err) goto bail; |
/* draw it using the current matrix */ |
SetRect (&r, 0, 0, FixRound (store->width), |
FixRound (store->height)); |
TransformRect (&store->matrix, &r, nil); |
EraseRect (&r); |
DrawPicture ((PicHandle)sample, &r); |
bail: |
DisposeHandle (sample); |
*flagsOut |= mDidDraw; /* let Movie Toolbox know you drew |
something */ |
return err; |
} |
pascal ComponentResult PictSetDimensions (PictGlobals store, |
Fixed width, |
Fixed height) |
{ |
/* remember the new track */ |
store->width = width; |
store->height = height; |
return noErr; |
} |
pascal ComponentResult PictSetMatrix (PictGlobals store, |
MatrixRecord *trackMovieMatrix) |
{ |
/* remember the new display matrix */ |
store->matrix = *trackMovieMatrix; |
return noErr; |
} |
Обработка запросов
Поскольку Ваш полученный обработчик носителей основывается на основном компоненте обработчика носителей, Вы избегаете многих подробных данных, вовлеченных в создание обработчика носителей. Однако Ваш полученный обработчик носителей должен соблюсти несколько правил при обработке запросов на обслуживание. Эти правила следующие:
Когда Вы получаете открытый запрос от Менеджера компонентов, в дополнение к другой обработке Вас выполняют от Вашего собственного имени, необходимо также открыть соединение с основным компонентом обработчика носителей. Необходимо сохранить экземпляр компонента, возвращающийся Менеджером компонентов так, чтобы обработчик носителей мог использовать службы основного обработчика носителей.
Основной обработчик носителей имеет тип компонента
MediaHandlerType(который установлен в'mhlr') и подтип компонентаBaseMediaType(который установлен в'gnrc'). Можно использовать эти значения с Менеджером компонентовOpenDefaultComponentфункционируйте для открытия соединения с основным обработчиком носителей.В это время необходимо также сказать основному обработчику носителей, что обработчик получен из него. Используйте Менеджер компонентов
OpenComponentфункция для создания экземпляра компонента обработчика носителей как потомок основного обработчика носителей. После вызывания той функции необходимо отправитьkComponentSetTargetSelectзапросите к основному обработчику носителей, так, чтобы он знал, что Ваш обработчик носителей получен из него. Используйте Менеджер компонентовComponentSetTargetфункция для отправления целевого запроса.Когда Вы получаете близкий запрос от Менеджера компонентов, убедиться закрыть соединение Вашего обработчика с основным компонентом обработчика носителей. Используйте Менеджер компонентов
CloseComponentфункция.Ваш полученный обработчик носителей должен поддерживать целевой запрос, так, чтобы Ваш компонент мог использоваться другими обработчиками носителей.
Обязательно передайте все неподдерживаемые запросы на обслуживание основному компоненту обработчика носителей. Используйте Менеджер компонентов
DelegateComponentCallфункционируйте для передачи этих запросов основному обработчику носителей.Если Ваш компонент обработчика носителей конкурирует за потенциально недостаточные системные ресурсы, Ваш компонент должен высвободить те средства, когда Вы не используете их. Например, если Вы создаете обработчик носителей, использующий звук, Вы могли бы использовать звуковые каналы. Поскольку существует ограниченное количество доступных звуковых каналов, Ваш компонент должен освободить свои каналы каждый раз, когда Ваши носители не играют или были остановлены. Когда Вы начинаете играть или Ваш компонент, можно перераспределить каналы
MediaPrerollфункция вызвана.