Зарегистрирован: Вт сен 16, 2008 7:30 pm Сообщения: 2798
|
В связи с появлением альтернативного редактора скриптов, возникла необходимость в организации работы с дополнениями в программе. Планы: - Дополнения будут организованы в виде dll-модулей (экспортируемая функция HmsGetAddonList, для C# дополнений необходимо реализовать класс HmsAddonList).
- Работа программы с дополнениями и дополнений с программой будет через интерфейсы.
Предполагаемые типы дополнений: - Дополнения, реализующие диалоговые функции (т.е. интерфейс с пользователем) - замена стандартных диалоговых окон или добавление кнопок, панелей в основную форму программы.
- Дополнения, реализующие редактирование скриптов, поддерживаемых программой.
- Дополнения, реализующие редактирование и выполнение произвольных скриптов.
- Дополнения, расширяющие список функций встроенных скриптов.
- Дополнения, предоставляющие ресурсы (видео, аудио, изображения) для использования в скриптах.
- Дополнения, расширяющие список файлов, включаемых в базу медиа-ресурсов при сканировании каталогов медиа-ресурсов.
- Дополнения, загружающие метаданные о медиа-ресурсах.
- Дополнения, организующие хранение информации о медиа-ресурсах (база медиа-ресурсов).
- Дополнения - обработчики http-запросов.
...
Большая часть перечисленных функций может быть выполнена и сейчас, но возможно дополнения будут более удобны для их разработчиков и пользователей.  Нет планов по организации проверки, хранения, распространения дополнений, но лицензия программы разрешает сборку и распространение дистрибутивов программы с дополнительными файлами. - [+] Особенности реализации Microsoft.NET дополнений
- 1. Вместе с файлом дополнения (например, MyHmsAddon.dll) должен идти ini-файл Windows, соответствующий названию модулю дополнения (для MyHmsAddon.dll файл должен называться MyHmsAddon.ini)
Код: [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.
Код: function HmsGetAddonList (out aAddonList: IHmsAddonList): HResult; stdcall;
4. После получения интерфейса IHmsAddonList, программа получает список (GetCount, GetAddonInfo) идентификаторов классов и интерфейсов, которые они реализуют. Идентификаторы классов должны быть уникальными, но произвольными (т.е. программа не будет искать класс с предопределенным идентификатором), идентификаторы интерфесов должны быть известны программе (например, для дополнения-редактора скриптов идентификатор интерфейса '{B43BB779-379D-4244-A53D-0AAC3863A0FB}').
5. В дальнейшем программа использует IHmsAddonList.GetClassObject для создания объектов, реализующие функции дополнения.
6. IHmsAddonList.CanUnloadNow вызывается перед выгрузкой дополнения.
- [+] Основной интерфейс дополнения - IHmsAddonList
Код: 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;
- [+] Предполагаемый интерфейс для дополнения - редактора скриптов.
Код: { интерфейс редактора }
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;
- [+] Предполагаемый интерфейс программы, который предоставляется редактору
Код: 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;
|
|