Page 1 of 1
Дополнения программы (планы)
Posted: Mon Nov 16, 2015 4:33 pm
by Eugene
В связи с появлением альтернативного редактора скриптов, возникла необходимость в организации работы с дополнениями в программе.
Планы:
- Дополнения будут организованы в виде dll-модулей (экспортируемая функция HmsGetAddonList, для C# дополнений необходимо реализовать класс HmsAddonList).
- Работа программы с дополнениями и дополнений с программой будет через интерфейсы.
Предполагаемые типы дополнений:
- Дополнения, реализующие диалоговые функции (т.е. интерфейс с пользователем) - замена стандартных диалоговых окон или добавление кнопок, панелей в основную форму программы.
- Дополнения, реализующие редактирование скриптов, поддерживаемых программой.
- Дополнения, реализующие редактирование и выполнение произвольных скриптов.
- Дополнения, расширяющие список функций встроенных скриптов.
- Дополнения, предоставляющие ресурсы (видео, аудио, изображения) для использования в скриптах.
- Дополнения, расширяющие список файлов, включаемых в базу медиа-ресурсов при сканировании каталогов медиа-ресурсов.
- Дополнения, загружающие метаданные о медиа-ресурсах.
- Дополнения, организующие хранение информации о медиа-ресурсах (база медиа-ресурсов).
- Дополнения - обработчики http-запросов.
...
Большая часть перечисленных функций может быть выполнена и сейчас, но возможно дополнения будут более удобны для их разработчиков и пользователей.

Нет планов по организации проверки, хранения, распространения дополнений, но лицензия программы разрешает сборку и распространение дистрибутивов программы с дополнительными файлами.
- [+] Особенности реализации Microsoft.NET дополнений
- 1. Вместе с файлом дополнения (например, MyHmsAddon.dll) должен идти ini-файл Windows, соответствующий названию модулю дополнения (для MyHmsAddon.dll файл должен называться MyHmsAddon.ini)
Code: Select all
[HmsAddonList]
Platform=Microsoft.NET
ClassName=HmsAddons.HmsAddonList
ClassName должен содержать полное название класса, реализующего интерфейс IHmsAddonList.
2. Вместе с файлом дополнения может быть конфигурационный файл Microsoft.NET (название MyHmsAddon.dll.config для MyHmsAddon.dll).
- [+] Работа программы с дополнениями.
- 1. При сканировании каталога дополнений и его подкаталогов (по-умолчанию Каталог_установки_программы\Addons), программа обрабатывает dll-файлы.
2. Если есть ini-файл и платформа Microsoft.NET, то программа организует Microsoft.NET хост и загружает в него модуль дополнения,
создает объект, реализующий IHmsAddonList интерфейс.
3. Если нет ini-файла, то программа загружает dll-модуль (LoadLibrary) пытается получить (GetProcAddress) адрес экспортируемой функции
HmsGetAddonList, если функция HmsGetAddonList есть, то происходит ее вызов для получения интерфейса IHmsAddonList.
Code: Select all
function HmsGetAddonList (out aAddonList: IHmsAddonList): HResult; stdcall;
4. После получения интерфейса IHmsAddonList, программа получает список (GetCount, GetAddonInfo) идентификаторов классов и интерфейсов,
которые они реализуют. Идентификаторы классов должны быть уникальными, но произвольными (т.е. программа не будет искать класс
с предопределенным идентификатором), идентификаторы интерфесов должны быть известны программе (например, для дополнения-редактора скриптов
идентификатор интерфейса '{B43BB779-379D-4244-A53D-0AAC3863A0FB}').
5. В дальнейшем программа использует IHmsAddonList.GetClassObject для создания объектов, реализующие функции дополнения.
6. IHmsAddonList.CanUnloadNow вызывается перед выгрузкой дополнения.
- [+] Основной интерфейс дополнения - IHmsAddonList
Code: Select all
IHmsAddonList = interface(IDispatch)
['{A8F688A7-441E-4701-9EA0-9C591D0B997A}']
function GetCount(var aCount: Integer): HResult; safecall;
function GetAddonInfo(aIndex: Integer; var aClassID, aInterfaceID: TGUID;
var aTitle, aDescription, aRequiredVersion, aCheckedOnVersion: OleVariant): HResult; safecall;
function GetClassObject(const clsid: TGUID; const iid: TGUID; out pv: OleVariant): HResult; safecall;
function CanUnloadNow: HResult; safecall;
end;
- [+] Предполагаемый интерфейс для дополнения - редактора скриптов.
Code: Select all
{ интерфейс редактора }
const
{ IHmsScriptEditor.GetCapabilities }
ecEditor = 1;
ecStatusBar = 2;
ecMessages = 4;
type
THmsScriptMode = (
smUnknown = 0,
smTranscoding,
smWatchFoldersGroupName,
smMediaInfo,
smProcessMedia,
smCreateFolderItems,
smPodcastItemProperties,
smMediaResourceLink,
smWebMediaItems,
smMimeType,
smProcessMediaEvent,
smCreatePodcastFeeds,
smWebNavigation,
smParsePlaylistFile,
smAutoDetectDeviceType,
smProcessMetadata,
smDIDLLiteDescription,
smHandleHTTPRequest);
IHmsScriptEditor = interface(IDispatch)
['{B43BB779-379D-4244-A53D-0AAC3863A0FB}']
function AddMessage(const aMessage: OleVariant): HResult; safecall;
function CreateEditor(aParent: THandle; const aHmsScripter: IHmsScriptFrame;
aScriptMode: Integer; var aEditor: THandle): HResult; safecall;
function DestroyEditor(aEditor: THandle): HResult; safecall;
function GetCapabilities(var aCapabilities: Integer): HResult; safecall;
function GetCurrentLine(var aLine: Integer): HResult; safecall;
function GetScriptName(var aScriptName: OleVariant): HResult; safecall;
function GetScriptText(var aText: OleVariant): HResult; safecall;
function SetScriptName(const aScriptName: OleVariant): HResult; safecall;
function SetScriptText(const aText: OleVariant): HResult; safecall;
function GetModified(var aModified: LongBool): HResult; safecall;
function InvalidateLine(aLineIndex: Integer): HResult; safecall;
function Repaint: HResult; safecall;
function GetCaretPos(var aLine, aChar: Integer): HResult; safecall;
function SetCaretPos(aLine, aChar: Integer): HResult; safecall;
function SetFocus: HResult; safecall;
function SetRunning(aValue: LongBool): HResult; safecall;
function SetSelText(const aText: OleVariant): HResult; safecall;
function Setup: HResult; safecall;
end;
- [+] Предполагаемый интерфейс программы, который предоставляется редактору
Code: Select all
const
{ IHmsScriptFrame.ProcessCommand }
ecUserFirst = 1001;
ecCompileScript = ecUserFirst + 103;
ecRunLine = ecUserFirst + 100;
ecRunScript = ecUserFirst + 102;
ecToggleBreakpoint = ecUserFirst + 101;
ecEvaluate = ecUserFirst + 104;
ecWatches = ecUserFirst + 105;
type
IHmsScriptFrame = interface(IDispatch)
['{D31B4638-9764-4A9A-9F5A-B4D0B519F402}']
function AddWatch(const aExpression: OleVariant): HResult; safecall;
function ChangeScriptName(const aScriptName: OleVariant): HResult; safecall;
function CompileScript(const aScriptName, aScriptText: OleVariant; var aErrorMessage: OleVariant;
var aErrorLine, aErrorChar: Integer; var aResult: LongBool): HResult; safecall;
function GenerateScriptDescriptions(var aXMLDescriptions: OleVariant): HResult; safecall;
function GetCurrentState(var aRunning: LongBool;
var aCurrentSourceLine, aCurrentSourceChar: Integer): HResult; safecall;
function IsBreakpointLine(aLine: Integer; var aResult: LongBool): HResult; safecall;
function IsExecutableLine(aLine: Integer; var aResult: LongBool): HResult; safecall;
function ProcessCommand(aCommand: Integer): HResult; safecall;
function SolveExpression(const aExpression: OleVariant; var aResult: OleVariant): HResult; safecall;
function ToggleBreakpoint(aLine: Integer): HResult; safecall;
end;
Re: Дополнения программы (планы)
Posted: Sun Dec 06, 2015 12:29 pm
by Eugene
Для вызова формы настройки дополнения и возможности обновления, добавлен интерфейс IHmsAddonTools, реализация необязательна, будет запрашиваться через IHmsAddonList.QueryInterface (т.е. у объекта, реализующего IHmsAddonList, можно добавить реализацию интерфейса IHmsAddonTools)
- [+] Сервисный интерфейс дополнения
Code: Select all
{ IHmsAddonTools.Update flags }
ufCheckExistsOnly = $01; // проверить существование обновления (in)
ufIsHttpLink = $02; // результат - http-ссылка на zip-файл дополнения (out)
ufIsLocalFile = $04; // результат - скаченный zip-файл дополнения (out)
ufIsInfoMessage = $08; // результат - информационное сообщение (например, что обновление прошло успешно) (out)
ufIsErrorMessage = $10; // результат - сообщение об ошибке (out)
ufIsWarningMessage = $20; // результат - сообщение, требующее внимания (например, что требуется перезагрузка программы) (out)
type
IHmsAddonTools = interface(IDispatch)
['{C5B24BFB-1F30-4F8A-91AD-943B82D8A067}']
function Setup(aOwner: THandle; var aReload: LongBool): HResult; safecall;
function Update(var aFlags: Integer; var aResult: OleVariant): HResult; safecall;
end;
Re: Дополнения программы (планы)
Posted: Sun Dec 06, 2015 12:54 pm
by Eugene
- [+] Интерфейс для дополнения - панели в основную форму программы
Code: Select all
IHmsMainFormControl = interface(IDispatch)
['{6E86502E-15BC-4358-A4A1-29D97CDEF073}']
function CreateControl(aParent: THandle; const aReserved: IUnknown; var aControl: THandle): HResult; safecall;
function DestroyControl(aControl: THandle): HResult; safecall;
function GetCaption(var aCaption: OleVariant): HResult; safecall;
function SetFocus: HResult; safecall;
function ExecuteAction(const aActionName: OleVariant; const aActionParameters: OleVariant): HResult; safecall;
function GetActionCount(var aCount: Integer): HResult; safecall;
function GetActionInfo(aIndex: Integer; var aActionName, aActionTitle, aActionDescription: OleVariant): HResult; safecall;
end;
Возможные реализации - проигрыватели медиа-файлов в главной форме программы, загрузчики медиа-файлов, просмотр интернета с использованием "Воспроизвести на...".
В версии 2.04 добавлен вызов IHmsMainFormControl.ExecuteAction с aActionName = 'open' при выборе в главной форме программы "Открыть файл". Дополнение должно вернуть S_OK, если обработало данное действие.
Re: Дополнения программы (планы)
Posted: Fri Dec 11, 2015 4:40 pm
by Eugene
- [+] Интерфейс дополнений, расширяющих список функций встроенных скриптов
Code: Select all
IHmsScriptFunctions = interface(IDispatch)
['{99546421-6D4B-4BEB-B778-285591F25D79}']
function ExecuteFunction(const aFunctionName: OleVariant; var aFunctionParameters, aFunctionResult: OleVariant): HResult; safecall;
function GetFunctionCount(var aCount: Integer): HResult; safecall;
function GetFunctionInfo(aIndex: Integer; var aFunctionName, aFunctionDeclaration, aFunctionCategory, aFunctionDescription: OleVariant): HResult; safecall;
end;
Предопределенные значения для aFunctionCategory:
ctConv - 'Преобразование'
ctFormat - 'Форматирование'
ctDate - 'Дата-время'
ctString - 'Строковые'
ctSystem - 'Системные'
ctMath - 'Математические'
ctOther - 'Другие'
ctAggregate - 'Агрегатные'
Re: Дополнения программы (планы)
Posted: Sat Dec 19, 2015 10:46 am
by Eugene
- [+] Интерфейс дополнений, реализующих диалоговые функции
Code: Select all
IHmsFormProvider = interface(IDispatch)
['{6BC29D8C-77BD-48D2-A310-35C9F1374581}']
function ShowModal(aOwner: THandle; const aFormClassName: OleVariant; var aParameters: OleVariant; var aModalResult: Integer): HResult; safecall;
end;
aParameters - массив именованных параметров (имя_параметра_1, значение_параметра_1, имя_параметра_2, значение_параметра_2, ..., имя_параметра_N, значение_параметра_N);
Функция IHmsFormProvider.ShowModal должна вернуть S_OK, если дополнение обработало указанный класс форм.
const
{ значения для aModalResult }
idOK = 1;
idCancel = 2;
idAbort = 3;
idRetry = 4;
idIgnore = 5;
idYes = 6;
idNo = 7;
idClose = 8;
idHelp = 9;
idTryAgain = 10;
idContinue = 11;
mrNone = 0;
mrOk = idOk;
mrCancel = idCancel;
mrAbort = idAbort;
mrRetry = idRetry;
mrIgnore = idIgnore;
mrYes = idYes;
mrNo = idNo;
mrClose = idClose;
mrHelp = idHelp;
mrTryAgain = idTryAgain;
mrContinue = idContinue;
mrAll = mrContinue + 1;
mrNoToAll = mrAll + 1;
mrYesToAll = mrNoToAll + 1;
Re: Дополнения программы (планы)
Posted: Tue Dec 29, 2015 8:01 pm
by Eugene
Для предоставления доступа к классам (объектам) программы добавлен добавлен интерфейс IHmsAddonInit, реализация необязательна, будет запрашиваться через IHmsAddonList.QueryInterface (т.е. у объекта, реализующего IHmsAddonList, можно добавить реализацию интерфейса IHmsAddonInit)
- [+] Интерфейс для инициализации доступа к объектам программы
Code: Select all
type
IHmsAddonInit = interface(IDispatch)
['{3AB5A0DB-190F-40AA-9FA3-88CC34432365}']
procedure SetApplication(const aApplication: IHmsApplication); safecall;
end;
После получения интерфейса IHmsAddonList программа запрашивает интерфейс IHmsAddonInit, если интерфейс получен, то программа вызывает IHmsAddonInit.SetApplication с ссылкой на интерфейс IHmsApplication
- [+] Интерфейс для доступа объектам программы
Code: Select all
type
IHmsApplication = interface(IBaseInterface)
['{99C4E03E-8044-4431-A53D-B9E999884B2E}']
function GetInterface(const aInterfaceID: TGUID; out aObject: OleVariant): HResult; safecall;
end;
После получения интерфейса IHmsApplication, дополнение может получить доступ к различным классам (объектам) программы через вызов IHmsApplication.GetInterface, на данный момент реализован запрос интерфейсов IHmsScripter - выполнение скриптов программы, IHmsThumbnailsManager - доступ к эскизам медиа-ресурсов.
- [+] Интерфейс IHmsScripter - выполнение скриптов программы
Code: Select all
IHmsScripter = interface(IDispatch)
['{786039DF-E1B1-466C-AF74-A6B1DAB2F8AE}']
function CreateScript(const aClientInfo: OleVariant; aScriptMode: Integer): LongBool; safecall;
function CompileScript(const aScriptName, aScriptText: OleVariant;
var aErrorMessage: OleVariant; var aErrorLine, aErrorChar: Integer): LongBool; safecall;
function ExecuteScript(const aInParameters: OleVariant; var aOutParameters: OleVariant): LongBool; safecall;
end;
aInParameters, aOutParameters - массив именованных параметров (имя_параметра_1, значение_параметра_1, имя_параметра_2, значение_параметра_2, ..., имя_параметра_N, значение_параметра_N); перед выполнением скрипта программа устанавливает значения переменных в aInParameters, после выполнения устанавливает значения переменных в aOutParameters.
- [+] Интерфейс IHmsThumbnailsManager - доступ к эскизам медиа-ресурсов
Code: Select all
IHmsThumbnailsManager = interface(IUnknown)
['{EFBB29E2-C170-4B33-ACAB-832F4443C070}']
function AddThumbnail(const aThumbnailKey, aThumbnailFormat: OleVariant;
aThumbnailWidth, aThumbnailHeight: Integer;
const aThumbnailStream: IStream): LongBool; safecall;
function CreateThumbnail(const aThumbnailKey: OleVariant; var aCreateParameters: OleVariant): LongBool; safecall;
function GetThumbnail(const aThumbnailKey: OleVariant;
const aThumbnailStream: IStream): LongBool; safecall;
function GetThumbnailInfo(const aThumbnailKey: OleVariant;
var aThumbnailFormat: OleVariant;
var aThumbnailWidth, aThumbnailHeight: Integer): LongBool; safecall;
function ThumbnailExists(const aThumbnailKey: OleVariant): LongBool; safecall;
end;
Re: Дополнения программы (планы)
Posted: Tue Dec 29, 2015 8:17 pm
by Eugene
Дополнительные интерфейсы для взаимодействия с дополнениями - провайдерами форм
- [+] Интерфейс медиа-ресурса
Code: Select all
type
IHmsAddonMediaItem = interface(IDispatch)
['{097D84B0-B557-4C03-BDEE-0D6E9E405DE5}']
function GetProperties(const aIndexOrName: OleVariant): OleVariant; safecall;
procedure SetProperties(const aIndexOrName, aPropertyValue: OleVariant); safecall;
function ExecuteMethod(const aMethodName: OleVariant; var aMethodParameters: OleVariant): OleVariant; safecall;
function PropertyExists(const aIndexOrName: OleVariant): LongBool; safecall;
property Properties[const aIndexOrName: OleVariant]: OleVariant read GetProperties write SetProperties; default;
end;
Идентификаторы свойств из скриптов или
'FolderOrigin' - папка-источник для ссылок (IHmsAddonMediaItem)
'FolderSortOrder' - сортировка папки
'FolderType' - тип папки (ftDefaultFolder = 0, ftDynamicFolder, ftTranscodingFolder, ftGroupByFolder, ftPodcastSubFolder, ftDeviceDynamicFolde)
'HideItem' - скрытый медиа-ресурс
'IsArchiveItem' - медиа-ресурс из архива
'IsBdItem' - медиа-ресурс из Bluray-структуры
'IsCueFileItem' - медиа-ресурс из CueSheet
'IsDvbItem' - медиа-ресурс цифрового телевидения
'IsDvdItem' - медиа-ресурс из DVD-структуры
'IsDirectLink' - если True, то на устройство передается оригинальная ссылка на медиа-ресурс
'IsFolder' - True, если элемент является папкой
'IsInternetItem' - True, если элемент в папке Интернет-телевидения или Интернет-радио
'IsInternetRadio' - True, если элемент в папке Интернет-радио
'IsIsoItem' - медиа-ресурс из образа диска
'IsLink' - элемент является ссылкой
'IsMixedItem' - медиа-ресурс в структуре "Каждый фильм в отдельной папке"
'IsOriginalLink' - ссылка на медиа-ресурс в папке Оригинал
'IsPodcast' - элемент в папке подкастов
'IsStreamItem' - IsDvbItem или IsInternetItem или IsPodcast
'IsTempItem' - элемент, который не сохраняется в базе данных (Транскодирование, Динамические папки, Сервисные папки)
'IsUrlItem' - IsInternetItem или путь содержит ://
'IsVirtualVideo' элемент в папке Музыка (Визуализация) или Фото (Слайд-шоу)
'IsWebShot' - путь элемента начинается с webshot:// (снимок Web-страницы)
'ItemBookmarkPath' - путь элемента для закладки
'ItemDate' - дата медиа-ресурса
'ItemExists' - True, есди элемент из архива или файл существует
'ItemID' - идентификатор медиа-ресурса
'ItemIDPath' - путь медиа-ресурса от корня
'ItemImageIndex' - индекс иконки медиа-ресурса
'ItemImagePath' - название файла иконки медиа-ресурса для Web-навигации
'ItemIsoURL' - путь медиа-ресурса в образе диска
'ItemOrigin' - элемент-источник для ссылок (IHmsAddonMediaItem)
'ItemParent' - родительский элемент (IHmsAddonMediaItem)
'ItemPath' - путь элемента (путь файл, интернет-ссылка)
'ItemRotate' - поворот фотографии
'ItemSafeID' - ItemID для сохраняемых элементов, ItemIDPath - для временных элементов
'ItemSize' - размер медиа-ресурса в байтах
'ItemState' - состояние элемента
'ItemTimeLength' - длительность медиа-ресурса
'ItemTitle' - название медиа-ресурса
'MediaResourceSource' - путь медиа-ресурса для транскодирования
'MediaType' - тип медиа-ресурса (mtUnknown, mtAudio, mtImage, mtVideo, mtText, mtIsoDisk, mtCueSheet, mtPlaylist)
'OriginalPath' - путь, сохраненный в базе данных
'RatingsOrigin' - элемент-источник для родительского контроля
'RootItem' - корневой элемент
'ShortItemID' - сокращенный (16 символов) идентификатор элемента
'Transcoding' - True, если элемент в папке Транскодирования или Виртуального видео
'Thumbnail' - эскиз медиа-ресурса
'ThumbnailExists' - True, если эскиз существует или потенциально (видео, фото) существует
'ThumbnailFileName' - имя файла эскиза
'ThumbnailKey' - ключ эскиза в базе эскизов
'ThumbnailOrigin' - элемент-источник для эскиза (IHmsAddonMediaItem)
Интерфейс передается в IHmsFormProvider.ShowModal с названием параметра MediaItem.
- [+] Интерфейс для перемещения по списку медиа-ресурсов
Code: Select all
IHmsAddonMediaItemListNavigator = interface(IDispatch)
['{BAF6D656-D927-4A56-89FF-DF79C258D546}']
procedure GotoBOF; safecall;
procedure GotoPrev; safecall;
procedure GotoNext; safecall;
procedure GotoEOF; safecall;
function IsBOF: LongBool; safecall;
function IsEOF: LongBool; safecall;
function IsTreeList: LongBool; safecall;
function CurrentMediaItem: OleVariant; safecall;
end;
Интерфейс передается в IHmsFormProvider.ShowModal с названием параметра Navigator.