Добавление собственных функций
Для добавления функций, которые понадобятся для решения ваших задач необходимо выполнить ряд простых шагов:
1. | В методе GetIdsOfNames проанализировать имя запрашиваемой функции и определить, может ли она быть вызвана для объекта, на который ссылается FOwner |
2. | Если функция может быть вызвана, Вы должны вернуть уникальный DispID, в противном случае – присвоить Result := DISP_E_UNKNOWNNAME |
3. | В методе Invoke необходимо обнаружить свой DispID, проверить корректность переданных параметров, получить их значения и выполнить действие. |
Обработка событий в компонентах VCL
Важным дополнением к реализуемой функциональности является возможность ассоциировать процедуру на VBScript с событием в компоненте VCL, таким, как OnEnter, OnClick или OnTimer. Для этого добавим в компонент TVCLScriptControl методы, которые будут служить обработчиками созданных в коде скрипта компонентов
Code: |
TVCLScriptControl = class(TScriptControl) … published procedure OnChangeHandler(Sender: TObject); procedure OnClickHandler(Sender: TObject); procedure OnEnterHandler(Sender: TObject); procedure OnExitHandler(Sender: TObject); procedure OnTimerHandler(Sender: TObject); end; |
В методе DoCreateControl, который вызывается из DoInvoke при обработке метода «Add», реализуем подключение соответствующих обработчиков событий создаваемого компонента к созданным методам
Code: |
procedure TVCLProxy.DoCreateControl(AName, AClassName: WideString; WithEvents: Boolean);
procedure SetHandler(Control: TPersistent; Owner: TObject; Name: String); // Функция устанавливает обработчик события Name на метод формы // с именем Name + 'Handler' var Method: TMethod; PropInfo: PPropInfo; begin // Получаем информацию RTTI PropInfo := GetPropInfo(Control.ClassInfo, Name); if Assigned(PropInfo) then begin // Получаем адрес обработчика Method.Code := FScriptControl.MethodAddress(Name + 'Handler'); if Assigned(Method.Code) then begin // Обработчик есть Method.Data := FScriptControl; // Устанавливаем обработчик SetMethodProp(Control, PropInfo, Method); end; end; end; var ThisClass: TControlClass; C: TComponent; NewOwner: TCustomForm; begin // Назначаем свойство Owner на форму if not (FOwner is TCustomForm) then NewOwner := GetParentForm(FOwner as TControl) else NewOwner := FOwner as TCustomForm; // Получаем класс создаваемого компонента ThisClass := TControlClass(GetClass(AClassName)); // Создаем компонент C := ThisClass.Create(NewOwner); // Назначаем имя C.Name := AName; if C is TControl then // Назначаем свойство Parent TControl(C).Parent := FOwner as TWinControl; if WithEvents then begin // Устанавливаем обработчики SetHandler(C, NewOwner, 'OnClick'); SetHandler(C, NewOwner, 'OnChange'); SetHandler(C, NewOwner, 'OnEnter'); SetHandler(C, NewOwner, 'OnExit'); SetHandler(C, NewOwner, 'OnTimer'); end; // Создаем класс реализующий интерфейс IDispatch и добавляем его // в пространство имен TScriptControl FScriptControl.RegisterClass(AName, C); end; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!