Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд) / 21 сообщений из 21, страница 1 из 1
22.02.2022, 21:05
    #40135978
Наталья87
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Добрый день!

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

Код: pascal
1.
2.
3.
4.
5.
for i:=0 to Form1.ComponentCount-1 do begin
   Top := SuperVcl_GetTop(Form1.Components[i]);
   Left := SuperVcl_GetLeft(Form1.Components[i]);
   ..................................
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.
35.
36.
37.
38.
39.
40.
41.
function SuperVcl_GetTop(c: Classes.TComponent): integer;
var
   cn: string; {class_name}
begin
   cn := LowerCase(c.ClassName);
   if cn='tlabel' then
      result := TLabel(c).Top
   else if cn='tbutton' then
      result := TButton(c).Top
   else if cn='tedit' then
      result := TEdit(c).Top
   else if cn='tmemo' then
      result := TMemo(c).Top
   else if cn='tcheckbox' then
      result := TCheckBox(c).Top
   else begin
      raise Exception.Create('Error SuperVcl_GetTop: invalid class ('+cn+')');
   end;
end;

function SuperVcl_GetLeft(c: Classes.TComponent): integer;
var
   cn: string; {class_name}
begin
   cn := LowerCase(c.ClassName);
   if cn='tlabel' then
      result := TLabel(c).Left
   else if cn='tbutton' then
      result := TButton(c).Left
   else if cn='tedit' then
      result := TEdit(c).Left
   else if cn='tmemo' then
      result := TMemo(c).Left
   else if cn='tcheckbox' then
      result := TCheckBox(c).Left
   else begin
      raise Exception.Create('Error SuperVcl_GetLeft: invalid class ('+cn+')');
   end;
end;

...................................




проблема в том, что процедур приходится писать много - одну для обращения к свойству Top, другую для обращения к Left, третью для обращения к Font.Name и т. д.

процедур может быть несколько десятков, при этом 90% кода процедур фактически дублируется, а полезная функция только одна - получение нужного свойства.

есть ли способ решить задачу по-нормальному (чтобы исключить повторяющийся код)?
...
Рейтинг: 0 / 0
22.02.2022, 21:28
    #40135984
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
function SuperVcl_GetTop(c: Classes.TComponent): integer;
begin
  if c is TControl then
    Result := TControl(c).Top
  else
    raise Exception.Create('Error SuperVcl_GetLeft: invalid class ('+c.ClassName+')');
end;

или
Код: pascal
1.
2.
3.
4.
function SuperVcl_GetTop(c: Classes.TComponent): integer;
begin
  Result := (c as TControl).Top
end;
...
Рейтинг: 0 / 0
22.02.2022, 22:25
    #40135993
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
type
THack = class(TControl);

function SuperVcl_GetFont(C: TComponent): TFont;
begin
  if C is TControl
    then Result := THack(C).Font
    else raise Exception.Create('Error SuperVcl_GetFont: invalid class ('+c.ClassName+')');
end;
...
Рейтинг: 0 / 0
22.02.2022, 23:34
    #40136009
Наталья87
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
DimaBr
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
type
THack = class(TControl);

function SuperVcl_GetFont(C: TComponent): TFont;
begin
  if C is TControl
    then Result := THack(C).Font
    else raise Exception.Create('Error SuperVcl_GetFont: invalid class ('+c.ClassName+')');
end;



Спасибо, работает с Top. Но вот с Font.Size не работает.

TControl(C).Font.Size := 8

выдает

Undeclared identidier (font)
...
Рейтинг: 0 / 0
22.02.2022, 23:46
    #40136010
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Наталья87

Код: pascal
1.
TControl(C).Font.Size := 8



Во втором классе есть такая тема "Контрольное списывание"
Цель урока: уметь каллиграфически правильно списывать текст с печатной основы.
...
Рейтинг: 0 / 0
22.02.2022, 23:49
    #40136011
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
...
Рейтинг: 0 / 0
22.02.2022, 23:54
    #40136013
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
DimaBr,

Вообще говоря можно нарваться, когда какой-нибудь компонент объявит новое свойство Font
...
Рейтинг: 0 / 0
23.02.2022, 00:13
    #40136017
Наталья87
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Спасибо, раньше делала

TLabel(component[i]).Font ...

для всех типов компонентов

было множество случайных багов вроде Access Violation в приложении

Теперь даже "злой" менеджер памяти SafeMM для отлова багов в 2 раза меньше стал срабатывать.
...
Рейтинг: 0 / 0
23.02.2022, 00:37
    #40136020
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
_Vasilisk_
DimaBr,
Вообще говоря можно нарваться, когда какой-нибудь компонент объявит новое свойство Font

Это проблема какого-нибудь компонента, а точнее его писателя.
...
Рейтинг: 0 / 0
23.02.2022, 01:18
    #40136024
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
DimaBr
Это проблема какого-нибудь компонента, а точнее его писателя.
Да. Но баг будет найти не просто
...
Рейтинг: 0 / 0
23.02.2022, 01:25
    #40136025
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Наталья87есть ли способ решить задачу по-нормальному (чтобы исключить повторяющийся код)?

Надо включить мозг и найти у какого класса в дереве наследования нужное свойство
было опубликовано впервые. Потом прочитать справку по оператору is . Тогда
код сократится до
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
function SuperVcl_GetLeft(c: Classes.TComponent): integer;
begin
    if c is TControl then
       result := TControl(c).Left;
    else begin
       raise Exception.Create('Error SuperVcl_GetLeft: invalid class 
('+c.ClassName+')');
    end;
end;



Или даже более того:
Код: sql
1.
Result := (c as TControl).left;


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.02.2022, 13:39
    #40136072
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
А вообще вменяемые люди для цикла по контролам использую TForm.Controls, а не
Components. Это, конечно, если они извращенцы, которым не хватает Anchors.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.02.2022, 15:21
    #40136089
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Наталья87,

я обычно смотрю, с какого класса появилось определенное свойство, и проверяю
Код: pascal
1.
2.
3.
...
if TObject(Control).InheritsFrom(TControl) then
   TControl(Control[i]).Top:= ....



Можно внутри цикла проверять уже на конкретные классы и даже на конкретные контролы (TObject(Control [i]).[i]Equals
(<мой_контрол>))
...
Рейтинг: 0 / 0
23.02.2022, 15:27
    #40136091
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Док, я тебе открою маленький секрет: в массиве Controls есть только наследники
от TControl, это обеспечивается его объявлением.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.02.2022, 15:56
    #40136096
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Dimitry Sibiryakov,

Дим, ты, как всегда, изъясняешься мудро и потому непонятно. Поэтому, я не буду воспринимать это, как желание меня обидеть ;)

А вообще, в Лазаре с его анкорингом и макетированием на этот счет намного проще
https://wiki.lazarus.freepascal.org/Autosize_/_Layout





...
Рейтинг: 0 / 0
23.02.2022, 16:15
    #40136109
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
ДокПоэтому, я не буду воспринимать это, как желание меня обидеть ;)

А зря. Базовые принципы языка - объектная модель - наследование. Переменная типа
класса-предка может содержать значения только этого класса или любого его
наследника.

TForm.Controls объявлено как массив TControl, соответственно в нём не может быть
ничего, кроме наследников TControl и Controls[i].InheritsFrom(TControl) по
определению true. (Хотя, конечно, свои Control ты мог по глупости объявить как
угодно.)

Кроме того, InheritsFrom в данном случае совершенно равнозначно оператору is и
существует исключительно для совместимости с С++, где такого оператора нет.

Топикстартерша - дура со ста тысячами строк говнокода. Не бери с неё пример.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.02.2022, 16:33
    #40136112
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Dimitry Sibiryakov
TControl, соответственно в нём не может быть
ничего, кроме наследников TControl и Controls[i].InheritsFrom(TControl) по
определению true.

а, вот ты о чем?

Да, ты прав. Но мой пример только для демонстрации возможностей. Но в данном случае, конечно, говнокод :)
...
Рейтинг: 0 / 0
23.02.2022, 16:40
    #40136115
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Dimitry Sibiryakov
Кроме того, InheritsFrom в данном случае совершенно равнозначно оператору is и существует исключительно для совместимости с С++,
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
  LClass: TClass;
begin
  LClass := TIBDataSet;
  Writeln(LClass is TDataSet);  // False
  Writeln(LClass.InheritsFrom(TDataSet));  // True
end;
...
Рейтинг: 0 / 0
23.02.2022, 16:46
    #40136117
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
"Данный случай" покрывает только TObject, а не TClass.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.02.2022, 16:51
    #40136119
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Dimitry Sibiryakov
"Данный случай" покрывает только TObject, а не TClass.
Я к тому, что это не две идентичные операции
...
Рейтинг: 0 / 0
23.02.2022, 17:01
    #40136123
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд)
Ну да. Это прямо написано в документации на них. Но кто ж её читает?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Обращение к свойствам (Top,Left итд) заранее неопределенного класса (TLabel, TButton итд) / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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