powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Нужна помощь по динамическому интерфейсуTComponents.
14 сообщений из 14, страница 1 из 1
Нужна помощь по динамическому интерфейсуTComponents.
    #39815649
Фотография Cola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще задача такая, есть интерфейс переведенный на несколько языков и есть БД в которой хранится перевод и к тому же еще свойства некоторых компонентов, которые нужно назначать компонентам при создании формы. Теперь вопрос: Помогите/посоветуйте как написать универсальную процедуру/функцию для записи всех компонент в БД и для присвоения им свойств. Процедура должна быть одна, а вот компоненты везде разные и в этом проблема.
Как я написала запись компонент в ДБ:
пробегаю по форме и ищу компоненты в БД, если их там нет - пишу, если есть - пропускаю.
Код: 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
Нужна помощь по динамическому интерфейсуTComponents.
    #39815654
Hammer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cola,
Можно посмотреть на примере библиотеки OXML (ссылка где-то пробегала на форуме - искать лень)
Модуль OXmlSerialize
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39815664
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет.

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

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

С уважением, Polesov.
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39815683
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39815766
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
for g := 0 to g-1 do
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39815836
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покажите как вы храните данные
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39815849
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В рамках уменьшения потока бреда
Код: 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
Нужна помощь по динамическому интерфейсуTComponents.
    #39816202
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39816496
Фотография Cola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,
Вы сами видели этот пример?
Код: pascal
1.
if Components[i-1].ClassType = TButton then


Чем мне это поможет? А если нет на форме TButton?
Там прямое обращение к свойствам через название классов. Так я и сама могу.
Нужно без ссылок на название класса иначе для каждой формы придется писать свою функцию.
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39816521
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Нужна помощь по динамическому интерфейсуTComponents.
    #39816522
Фотография Cola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,
какая разница как я их храню, вопрос не в этом.
А в том как обратиться к свойству компонента не указывая явно название его класса и что бы это не вызвало ошибку (что именно это свойство у него есть).
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39816537
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Colaкак обратиться к свойству компонента не указывая явно название его класса и что бы это не вызвало ошибку (что именно это свойство у него есть).
тут
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39816596
Фотография Cola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,
Так я просила помочь - объяснить как без именования классов.
...
Рейтинг: 0 / 0
Нужна помощь по динамическому интерфейсуTComponents.
    #39816614
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ColaDimaBr,
Так я просила помочь - объяснить как без именования классов.
Без классов - только через RTTI.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Нужна помощь по динамическому интерфейсуTComponents.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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