GoldenSoftwareLtd / gedemin

22 stars 13 forks source link

Корректировка новых свойств форм из Delphi7 #4414

Open gsbelarus opened 1 year ago

gsbelarus commented 1 year ago

в нескольких местах используется один и тот же код. надо оформить его в функцию. и меня смущает как этот код перекрывает шрифты это для чего сделано?

  {$IFDEF DELPHI7}
  for I := 0 to ComponentCount -1 do
  begin
    PropInfo := GetPropInfo(TComponent(Components[I]).ClassInfo, 'Ctl3D');
    if PropInfo <> nil then
      SetOrdProp(TComponent(Components[I]), PropInfo, Integer(True));
    PropInfo := GetPropInfo(TComponent(Components[I]).ClassInfo, 'Font');
    if PropInfo <> nil then
    begin
      F := TFont.Create;
      F := TFont(GetObjectProp(TComponent(Components[I]), 'Font', TFont));
      F.Name := 'Tahoma';
      SetObjectProp(TComponent(Components[I]), PropInfo, F);
    end;
    if (Components[I] is TgsCustomDBGrid) then
      for C := 0 to TgsCustomDBGrid(Components[I]).Columns.Count - 1 do
      begin
        TgsCustomDBGrid(Components[I]).Columns[C].Font.Name := 'Tahoma';
        TgsCustomDBGrid(Components[I]).Columns[C].Title.Font.Name := 'Tahoma';
      end;
    if (Components[I] is TPageControl) then
    begin
      THask(TPageControl(Components[I])).Color := clSkyBlue;
      THask(TPageControl(Components[I])).Color := clBtnFace;
    end;
  end;
  {$ENDIF}
gsbelarus commented 1 year ago

А почему мы вручную вызываем этот код для нескольких только классов? Что мешает его вызвать один раз на уровне TCreatableForm?

Polfath commented 1 year ago

Я перенес его в procedure TgdcCreateableForm.SetComponentProperties

gsbelarus commented 1 year ago

я вижу что перенесли. вопрос в том, почему не вызвать этот код на уровне TgdcCreateableForm?

Polfath commented 1 year ago

Он не для каждой формы нужен

Polfath commented 1 year ago

Могут быть формы, у которых свои специфические свойства

gsbelarus commented 1 year ago

тут явно ошибка. вы создали объект типа TFornt и тут же потеряли его, потому что поверх переписали:

      F := TFont.Create;
      F := TFont(GetObjectProp(TComponent(Components[I]), 'Font', TFont));
      F.Name := 'Tahoma';
      SetObjectProp(TComponent(Components[I]), PropInfo, F);
Polfath commented 1 year ago

Я объекту TFont присвоил все те же свойства, что и были у загружаемого. Потом поменял только Name, остальные свойства не изменились (Style, Hieght и т.п.) и переприсвоил этот TFont исходному. Все свойства у него останутся теми же кроме Name.

gsbelarus commented 1 year ago
      F := TFont.Create;
      ^^^^^^^^^^^^
      создан объект, ссылка сохранена в переменной F

      F := TFont(GetObjectProp(TComponent(Components[I]), 'Font', TFont));
      ^^^^^^^^^^^^
      в переменную F записана ссылка на другой объект. тот объект который был создан ранее навсегда останется в оперативной памяти!!!

      F.Name := 'Tahoma';
      SetObjectProp(TComponent(Components[I]), PropInfo, F);
gsbelarus commented 1 year ago

что вообще мешает вам написать так:

  F := TFont(GetObjectProp(TComponent(Components[I]), 'Font', TFont));
  if F is TFont then
    TFont(F).Name := 'Tahoma';

или вы не понимаете как в памяти располагаются объекты и что хранит переменная типа объект?

Polfath commented 1 year ago

Вы правы. Косяк. Поправил

gsbelarus commented 1 year ago

напишите так, как я показал выше!

в моем случае, если в компоненте встретится свойство названное 'Font', но оно будет другого типа, то код отработает корректно. в вашем случае -- кинет ошибку Access Violation!

gsbelarus commented 1 year ago
  F: TObject;

  ...

  F := GetObjectProp(TComponent(Components[I]), 'Font', TFont));
  if F is TFont then
    TFont(F).Name := 'Tahoma';
gsbelarus commented 1 year ago

как вы поняли что именно в эти формы надо добавить обработку, а в остальные не надо? по какому критерию?

gsbelarus commented 1 year ago

настройте микрофон. надо голосом переговорить.

gsbelarus commented 1 year ago

по-прежнему нет ответа почему нельзя этот код вызвать вообще для всех наследников TgdcCreateableForm? Какую именно проблему решает этот код? Можно ли ее решить по другому? Как были определены те формы, куда добавлен вызов этой процедуры?

Polfath commented 1 year ago

1. Почему нельзя этот код вызвать вообще для всех наследников TgdcCreateableForm?

После начала тестирования появился первый баг о том, что слетают предустановленные изначально настройки компонентов формы. Я пытался исполнит п.3. Прогуглил весь интернет и по конкретно Delphi 7, и по каждой компоненте в частности. Что-то пишут про VCL Style, про WindowsXP manifest, но как это применить в конкретном приложении, не нашел. По крайней мере дл D7 (для Delphi от 10 вроде как есть возможности).

2. Какую именно проблему решает этот код?

П.1. Тестировщики жалуются на измененный, непривычный глазу интерфейс форм. Шрифт не тот, закладки не того цвета, едиты не вдавленные и т.п.

3. Можно ли ее решить по другому?

Пытался найти какое-нибудь более простое решение (п.1)

4. Как были определены те формы?

Формы (базовые) определялись после возникновения багов у коллег по результатам тестирования.

5. Куда добавлен вызов этой процедуры?

Вызов добавлялся соответственно классу, на который жаловались коллеги (Tgdc_dlgAttrUserDefined, Tgdc_dlgUserComplexDocument, Tgdc_frmAttrUserDefined...)

_Я побоялся сразу переносить этот метод в базовый класс из-за того, что не был уверен в том, что эти настройки будут актуальны для всех наследников. Еще было сомнение в потере производительнсти, если для каждой открываемой формы будут перекрываться свойства ее компонент. Посмотрел сейчас. Наследников TgdcCreateableForm всего 22 (конечно не считая наследников наследников). В любом случае в проекте их сравниетельно меньше, чем от TForm, а с TForm как раз все в поряде.

Сделаю вызов для всех наследников TgdcCreateableForm, будем дальше отслеживать замечания коллег по этому._

Polfath commented 1 year ago

Сделал