Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Нужна помощь по динамическому интерфейсуTComponents. / 14 сообщений из 14, страница 1 из 1
21.05.2019, 09:57
    #39815649
Cola
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
Вообще задача такая, есть интерфейс переведенный на несколько языков и есть БД в которой хранится перевод и к тому же еще свойства некоторых компонентов, которые нужно назначать компонентам при создании формы. Теперь вопрос: Помогите/посоветуйте как написать универсальную процедуру/функцию для записи всех компонент в БД и для присвоения им свойств. Процедура должна быть одна, а вот компоненты везде разные и в этом проблема.
Как я написала запись компонент в ДБ:
пробегаю по форме и ищу компоненты в БД, если их там нет - пишу, если есть - пропускаю.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
Procedure TfrmAdmin.CompToDB(form: String);
var a,z,g,id,idg: integer;   items,parent,hintt,capp: string; Grid, TrGrid: TComponent;
begin
id:=0;

if UniMainModule.FindComDB(form,form,'')=0 then //проверка на наличие формы в БД
    Begin
    UniMainModule.RecCompToDB(0,form,form,'','');  //Пишем в базу форму, если ее там нет
     if UniMainModule.FindComDB(form,form,'')=1 then id:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger;
    End;
 if UniMainModule.FindComDB(form,form,'')=1 then id:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger;
 if UniMainModule.FindComDB(form,form,'')>1 then ShowMEssage('Error '+form+' > 1');
 for z := 0 to ComponentCount-1 do
  begin
   capp:='NULL';
   parent:='NULL';
    if Components[z].ClassName= 'TUniLabel' then
    begin
       capp:=(FindComponent(Components[z].Name) as TUniCustomLabel).Caption;
       parent:= Components[z].GetParentComponent.Name;
    end;
    if Components[z].ClassName= 'TUniTabSheet' then
    begin
       capp:=(FindComponent(Components[z].Name) as TUniTabSheet).Caption;
       parent:= Components[z].GetParentComponent.Name;
    end;
    if Components[z].ClassName= 'TUniButton' then
    begin
       capp:=(FindComponent(Components[z].Name) as TUniButton).Caption;
       hintt:=(FindComponent(Components[z].Name) as TUniButton).Hint;
       parent:= Components[z].GetParentComponent.Name;
    end;
     if Components[z].ClassName='TUniDBGrid' then
    begin
      Grid:=(FindComponent(Components[z].Name));
      g:=(FindComponent(Components[z].Name) as TUniDBGrid).Columns.Count;
      if UniMainModule.FindComDB(form,Components[z].Name,'')=0 then
        UniMainModule.RecCompToDB(id, form, Components[z].Name, '', capp);
      a:=UniMainModule.FindComDB(form,Components[z].Name,items);
      if a=1 then idg:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger;
      if a=0 then idg:=0;

      for g := 0 to g-1 do
       begin
        capp:= (FindComponent(Components[z].Name) as TUniDBGrid).Columns[g].Title.Caption;
        items:= (FindComponent(Components[z].Name) as TUniDBGrid).Columns[g].FieldName;
       //Проверка на существование компонента в БД и запись полей грида
          if UniMainModule.FindComDB(form,Components[z].Name,items)=0 then
              if Components[z].Name<>'' then UniMainModule.RecCompToDB(idg, form, Components[z].Name, items, capp);
       end;
        capp:='NULL';
        parent:='NULL';
    end;
    if Components[z].ClassName='TUniDBTreeGrid' then
    begin
      TrGrid:=(FindComponent(Components[z].Name));
      g:=(FindComponent(Components[z].Name) as TUniDBTreeGrid).Columns.Count;
      if UniMainModule.FindComDB(form,Components[z].Name,'')=0 then
        UniMainModule.RecCompToDB(id, form, Components[z].Name, '', capp);
      a:=UniMainModule.FindComDB(form,Components[z].Name,items);
      if a=1 then idg:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger;
      if a=0 then idg:=0;

      for g := 0 to g-1 do
       begin
        capp:= (FindComponent(Components[z].Name) as TUniDBTreeGrid).Columns[g].Title.Caption;
        items:= (FindComponent(Components[z].Name) as TUniDBTreeGrid).Columns[g].FieldName;
       //Проверка на существование компонента в БД и запись полей грида
          if UniMainModule.FindComDB(form,Components[z].Name,items)=0 then
              if Components[z].Name<>'' then UniMainModule.RecCompToDB(idg, form, Components[z].Name, items, capp);
       end;
        capp:='NULL';
        parent:='NULL';
    end;
     items:='';
    //Проверка на существование компонента в БД и запись найденого компонента
    if UniMainModule.FindComDB(form,Components[z].Name,'')=0 then
        if Components[z].Name<>'' then UniMainModule.RecCompToDB(id, form, Components[z].Name, '', capp);
  end;
end;


А это вычитывание из БД и присвоение компонентам свойств:
я сначала ищу компонент на форме/фрейме, а потом ищу его в БД и присваиваю свойства. Я могу это сделать если заранее известно, что это за компонент, тогда я могу добраться к его свойствам.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
procedure TfrmAdmin.UniButton4Click(Sender: TObject);
var
  dbstrr,dbstr,EditName,BottonName: string;
  EditFound,BottonFound,MenuFound: TComponent;
  i: integer;
begin
  UniMainModule.PgQuery1.Active:=false;
  UniMainModule.PgQuery1.SQL.Clear;
  UniMainModule.PgQuery1.SQL.Append('SELECT * FROM getinterface(''MainForm'','+inttostr(UniMainModule.UserRecord.idLang)+') AS t1;');
  UniMemo1.Lines:=UniMainModule.PgQuery1.SQL;
  UniMainModule.PgQuery1.Active:=True;
  UniMainModule.PgDataSource1.DataSet.First;
  ShowMessage('First='+inttostr(UniMainModule.PgDataSource1.DataSet.RecordCount));
while UniMainModule.PgDataSource1.DataSet.Eof=false do
 begin
  dbstr:=UniMainModule.PgDataSource1.DataSet.FieldByName('Component').AsString;
  dbstrr:=UniMainModule.PgDataSource1.DataSet.FieldByName('Text').AsString;
  MenuFound:=FindComponent(dbstr);
  if MenuFound <> nil then
   begin
     ShowMessage('если это меню');
     i:=UniMainModule.PgDataSource1.DataSet.FieldByName('items').AsInteger;
     //MainForm.UniTreeMenu1.Items.Add(nil,dbstrr);
     if UniMainModule.PgDataSource1.DataSet.FieldByName('Caption').AsString <> '' then
       dbstrr:=UniMainModule.PgDataSource1.DataSet.FieldByName('Caption').AsString;
     if UniMainModule.PgDataSource1.DataSet.FieldByName('Text').AsString <> '' then
       dbstrr:=UniMainModule.PgDataSource1.DataSet.FieldByName('Text').AsString;
     if UniMainModule.PgDataSource1.DataSet.FieldByName('Text').AsString = '' then
       dbstrr:=UniMainModule.PgDataSource1.DataSet.FieldByName('Caption').AsString;
     MainForm.UniTreeMenu1.Items.Item[i].Text:=dbstrr;
   end;
   UniMainModule.PgDataSource1.DataSet.Next;
 end;
end;



Но тут есть проблема - нельзя указывать компонент, который не используется в конкретном фрейме (ошибка, что компонент/Класс не найден) и этот код нужно повторять в каждом юните перечисляя только те классы/компоненты, которые там есть. А я хочу универсальные процедуры/функции для всех фреймов и форм.
Посоветуйте - плиииз! Всем заранее спасибо за ответы!
...
Рейтинг: 0 / 0
21.05.2019, 10:03
    #39815654
Hammer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
Cola,
Можно посмотреть на примере библиотеки OXML (ссылка где-то пробегала на форуме - искать лень)
Модуль OXmlSerialize
...
Рейтинг: 0 / 0
21.05.2019, 10:29
    #39815664
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
Привет.

Colaуниверсальные процедуры/функции для всех фреймов и форм

Для компонентов формы/фрейма: ComponentCount, Components[i]
Для свойств компонента: GetPropList

С уважением, Polesov.
...
Рейтинг: 0 / 0
21.05.2019, 10:53
    #39815683
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
...
Рейтинг: 0 / 0
21.05.2019, 13:13
    #39815766
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
Код: pascal
1.
for g := 0 to g-1 do
...
Рейтинг: 0 / 0
21.05.2019, 14:38
    #39815836
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
Покажите как вы храните данные
...
Рейтинг: 0 / 0
21.05.2019, 14:56
    #39815849
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
В рамках уменьшения потока бреда
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
зrocedure TfrmAdmin.CompToDB(const form: String);
var
  a,z,g,id,idg: integer;
  items,parent,hintt,capp: string;
  Comp: TComponent;
  Grid: TUniDBGrid absolute Comp;
  TrGrid: TUniDBTreeGrid absolute Comp;
  FindComRes: Integer;
begin
  id:=0;
  FindComRes := UniMainModule.FindComDB(form, form, '');
  if FindComRes = 0 then begin //проверка на наличие формы в БД
    UniMainModule.RecCompToDB(0,form,form,'','');  //Пишем в базу форму, если ее там нет
    FindComRes := UniMainModule.FindComDB(form, form, '');
  End;
  if FindComRes = 1 then
    id:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger
  else if FindComRes > 1 then
    raise Exception.Create('Error '+form+' > 1');
  for z := 0 to ComponentCount-1 do begin
    capp:='NULL';
    parent:='NULL';
    Comp := Components[z];
    if Comp is TUniCustomLabel then begin
       capp:=TUniCustomLabel(Comp).Caption;
       parent:= Comp.GetParentComponent.Name;
    end else if Comp is TUniTabSheet then begin
       capp:=TUniTabSheet(Comp).Caption;
       parent:= Comp.GetParentComponent.Name;
    end else if Comp is TUniButton then begin
       capp:=TUniButton(Comp).Caption;
       hintt:=TUniButton(Comp).Hint;
       parent:= Comp.GetParentComponent.Name;
    end if Comp is TUniDBGrid then
    begin
      g:=Frid.Columns.Count;
      if UniMainModule.FindComDB(form, Comp.Name,'')=0 then
        UniMainModule.RecCompToDB(id, form, Comp.Name, '', capp);
      a:=UniMainModule.FindComDB(form,Comp.Name,items);
      case a of
        0: idg:=0;
        1: idg:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger;
      else
         ?????????
      end;

      for g := 0 to g-1 do begin  // ??????????
        capp:= Grid.Columns[g].Title.Caption;
        items:= Grid.Columns[g].FieldName;
        //Проверка на существование компонента в БД и запись полей грида
        if (Comp.Name<>'') and (UniMainModule.FindComDB(form,Comp.Name,items)=0) then
          UniMainModule.RecCompToDB(idg, form, Comp.Name, items, capp);
      end;
      capp:='NULL';
      parent:='NULL';
    end else if Comp is TUniDBTreeGrid then begin
      g:=TrGrid.Columns.Count;
      if UniMainModule.FindComDB(form,Comp.Name,'')=0 then
        UniMainModule.RecCompToDB(id, form, Comp.Name, '', capp);
      a:=UniMainModule.FindComDB(form,Comp.Name,items);
      case a of
        0: idg:=0;
        1: idg:=UniMainModule.PgDataSource1.DataSet.FieldByName('id').AsInteger;
      else
         ?????????
      end;

      for g := 0 to g-1 do  // ?????
       begin
        capp:= TrGrid.Columns[g].Title.Caption;
        items:= TrGrid.Columns[g].FieldName;
       //Проверка на существование компонента в БД и запись полей грида
        if (Comp.Name<>'') and (UniMainModule.FindComDB(form,Comp.Name,items)=0) then
          UniMainModule.RecCompToDB(idg, form, Components[z].Name, items, capp);
       end;
        capp:='NULL';
        parent:='NULL';
    end;
    items:='';
    //Проверка на существование компонента в БД и запись найденого компонента
    if (Comp.Name<>'') and (UniMainModule.FindComDB(form,Comp.Name,'')=0) then
      UniMainModule.RecCompToDB(id, form, Comp.Name, '', capp);
  end;
end;

...
Рейтинг: 0 / 0
22.05.2019, 09:46
    #39816202
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
...
Рейтинг: 0 / 0
22.05.2019, 14:17
    #39816496
Cola
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
DimaBr,
Вы сами видели этот пример?
Код: pascal
1.
if Components[i-1].ClassType = TButton then


Чем мне это поможет? А если нет на форме TButton?
Там прямое обращение к свойствам через название классов. Так я и сама могу.
Нужно без ссылок на название класса иначе для каждой формы придется писать свою функцию.
...
Рейтинг: 0 / 0
22.05.2019, 14:38
    #39816521
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
ColaDimaBr,
Вы сами видели этот пример?
Код: pascal
1.
if Components[i-1].ClassType = TButton then


Чем мне это поможет? А если нет на форме TButton?
Там прямое обращение к свойствам через название классов. Так я и сама могу.
Нужно без ссылок на название класса иначе для каждой формы придется писать свою функцию.
Ну нет на форме TButton и что ?
У вас тоже прямое обращение к свойствам через классы
Код: pascal
1.
2.
3.
4.
5.
6.
if Components[z].ClassName= 'TUniButton' then
    begin
       capp:=(FindComponent(Components[z].Name) as TUniButton).Caption;
       hintt:=(FindComponent(Components[z].Name) as TUniButton).Hint;
       parent:= Components[z].GetParentComponent.Name;
    end;



Хотите без классов - RTTI
...
Рейтинг: 0 / 0
22.05.2019, 14:38
    #39816522
Cola
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
DimaBr,
какая разница как я их храню, вопрос не в этом.
А в том как обратиться к свойству компонента не указывая явно название его класса и что бы это не вызвало ошибку (что именно это свойство у него есть).
...
Рейтинг: 0 / 0
22.05.2019, 14:45
    #39816537
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
Colaкак обратиться к свойству компонента не указывая явно название его класса и что бы это не вызвало ошибку (что именно это свойство у него есть).
тут
...
Рейтинг: 0 / 0
22.05.2019, 15:41
    #39816596
Cola
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
DimaBr,
Так я просила помочь - объяснить как без именования классов.
...
Рейтинг: 0 / 0
22.05.2019, 15:56
    #39816614
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь по динамическому интерфейсуTComponents.
ColaDimaBr,
Так я просила помочь - объяснить как без именования классов.
Без классов - только через RTTI.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Нужна помощь по динамическому интерфейсуTComponents. / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]