Форум: "Компоненты";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
ВнизTools API, написание эксперта Найти похожие ветки
← →
Meson © (2004-12-27 17:01) [0]Мне необходимо изменить значение свойства у компонента
(пишется эксперт для Delphi6)
Component: IOTAComponent;
Например, установить свойство DataSet у DataSource.
Я делаю так:
var
CurrentForm: IOTAFormEditor;
DataSetComponent: IOTAComponent;
DataSourceComponent: IOTAComponent;
begin
CurrentForm := GxOtaGetFormEditorFromModule(GxOtaGetCurrentModule);
DataSetComponent := CurrentForm.FindComponent("MyDataSet");
Assert(Assigned(DataSetComponent));
DataSourceComponent := CurrentForm.FindComponent("MyDataSource");
Assert(Assigned(DataSourceComponent));
ComponentDataSource.SetPropByName("DataSet",
DataSetComponent);
// Не работает
ComponentDataSource.SetPropByName("DataSet",
"MyDataSet");
// тоже не работает
А как правильно?
← →
Petr V. Abramov © (2004-12-27 21:49) [1]Зачем устанавливать св-во через IOTA? Ну, допустим, просто нужно.
Что такое GxOtaGetFormEditorFromModule?
← →
Meson © (2004-12-27 22:33) [2]to Petr V. Abramov
Вы совершенно правы, я не дал достаточных пояснений.
1. не просто нужно. Пишется эксперт на базе GExperts
(www.gexprts.net).
2. GxOtaGetCurrentModule - Функция, возвращающая интерфейс
актульного модуля
3. Мой вопрос адресован к тем, кто знаком с проектом
www.gexprts.net
← →
Meson © (2004-12-28 00:21) [3]Вопрос снят, спасибо
← →
Юрий Зотов © (2004-12-28 08:22) [4]> Meson
Хотел ответить еще вчера, но не было возможности. Но, как говорится, лучше поздно, чем никогда.
Для этой задачи вовсе не требуется использование расширений IDE типа GExperts и других, все можно сделать стандартными средствами ToolsAPI. Вот пример, перечисляющий компоненты на текущей редактируемой форме, модуле данных или фрейме.
type
TEnumComponentProc = procedure(AComponent: TComponent);
procedure EnumComponents(Proc: TEnumComponentProc);
var
Module: IOTAModule;
FormEditor: IOTAFormEditor;
Root: INTAComponent;
i: integer;
begin
// 1. Получаем текущий модуль
Module := (BorlandIDEServices as IOTAModuleServices).CurrentModule;
// 2. Если он содержит форму, модуль данных или фрейм, то
// получаем ссылку на нее (него) и перечисляем компоненты.
if (Module <> nil) and
(Module.CurrentEditor.QueryInterface(IOTAFormEditor, FormEditor) = S_OK) and
(FormEditor.GetRootComponent.QueryInterface(INTAComponent, Root) = S_OK) then
with Root.GetComponent do
for i := 0 to ComponentCount - 1 do
Proc(Components[i])
end;
Как видим, для каждого компонента вызывается callback-функция. Ну а в ней уже можно хоть свойства менять, хоть что угодно еще делать, это не проблема.
← →
Meson © (2004-12-29 16:36) [5]> Юрий Зотов
1. Я очень расчитывал на Ваш ответ. Спасибо.
2. Уточните, пожалуйста, как нужно вызывать функцию EnumComponents.
И в каком режиме (RunTime или Design)?
- В RunTime это, по-моему, не имеет смысла (или я ошибаюсь?).
Однако я попробовал так:uses ToolsAPI;
procedure proc(Component: TComponent);
begin
MessageDlg(Component.Name, mtInformation, [mbOK], 0);
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
EnumComponents(proc);
end;
Возникает AccessViolation уже при выполнении
Module := (BorlandIDEServices as IOTAModuleServices).CurrentModule;
- В Design mode (в моем случае предполагалось именно расширение IDE)?
Как это сделать без использования эксперта?
3. По существу моего вопроса.
Я делаю три вещи. (Используется библиотека DOA – www.allroundautomations.com)
- Добавляю в активную форму компонент dbSession: TOracleSession,
- настраиваю его на нужную базу данных и
- всем компонентам формы, имеющим свойство Session,
устанавливаю значение Session := dbSession.
Т.е. необходимо изменить свойство, имеющее тип Class.
Как это делается средствами ToolsAPI?
Я перечисляю компоненты TComponent.
Проверяю, не является ли текущий компонент одним из тех, которые я ищу, иcase ComponentKind of
сkOracleDataSet:
TOracleDataSet(Comp).Session := TOracleSession(PropertyComp);
Это решение исправно работает. Мне в нем не нравится то, что
- приходится выходить за рамки ToolsAPI и
- использовать перечисляемый тип (сейчас ComponentKind содержит 8 типов,
а что будет в следующей версии библиотеки - не известно.)
Иначе говоря – решение является не достаточно общим.
← →
Юрий Зотов © (2004-12-29 17:29) [6]> Meson © (29.12.04 16:36) [5]
> 2. Уточните, пожалуйста, как нужно вызывать функцию
> EnumComponents.
Вызывать - как Вы и вызываете, просто передав ей callback в параметре. Конечно, только в design-time (переменная BorlandIDEServices инициализируется самой IDE, а в run-time она остается nil - отсюда и Access Violation).
> 3. По существу моего вопроса.
Изменение свойства делается средствами RTTI, а не ToolsAPI. (посмотрите IsPublishedProp и SetObjectProp в модуле TypInfo). Причем делается вполне универсально, никакой собственный перечислимый тип для этого не нужен.
А ToolsAPI здесь требуется только для того, чтобы отловить добавление dbSession на форму. Как это сделать - навскидку не скажу, надо копаться в ToolsAPI. Но есть и гораздо более простой способ, без всяких ToolAPI - объявить свой класс формы, перекрыть у него Notification, поместить в пакет и наследовать рабочие формы от него. Вот в этом Notification все и делается, и даже очень просто.
procedure TMyForm.Notification(AComponent: TComponent; Operation: TOperation);
procedure SetSession(Target, Value: TOracleSession);
var
P: PPropInfo;
begin
P := GetPropInfo(Target.ClassInfo, "Session", [tkClass]);
if P <> nil then
SetObjectProp(Target, P, Value, True)
end;
var
i: integer;
begin
inherited;
if Operation = opInsert then
begin
if AComponent is TOracleDataSet then
for i := 0 to ComponentCount - 1 do
SetSession(Components[i], AComponent)
else
for i := 0 to ComponentCount - 1 do
if Components[i] is TOracleDataSet then
begin
SetSession(AComponent, Components[i]);
Break
end
end
end;
← →
Юрий Зотов © (2004-12-30 01:07) [7]Сорри, описка вышла. Конечно же, надо так:
procedure SetSession(Target, Value: TComponent);
или так:
procedure SetSession(Target, Value: TObject);
← →
Meson © (2005-01-02 19:14) [8]> Юрий Зотов © (30.12.04 01:07) [7]
Спасибо огромное за помощь, разобрался.
Всего Вам доброго, Юрий!
Успехов в Новом году.
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.04 c