Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как проверить является ли экземпляр потомком класса [D7, WinXP]


Andrey Kononov ©   (2005-06-06 16:58:00) 

Доброго времени суток.

Как можно проверить является ли экземпляр окна, хранимого в ActiveMDIChild потомком некоторого класса?

Есть класс TBaseForm от которого делается несколько дочерних форм в приложении. Есть дочерние приложения сделанные от TForm.

Как мне сделать такую проверку

if not (ActiveMDIChild is TBaseForm) then
begin
 ......
 Exit;
end;

Конструкция всегда показывает, что ActiveMDIChild никогда не бывает наследником TBaseForm, хотя это не так.

Что можно сделать?


Ученик   (2005-06-07 23:57:00) [1]

На всякий случай :-)

function IsClass(A : TObject; const ClassName : string) : Boolean;
var
C : TClass;
begin
C := A.ClassType;
while (C <> nil) and (C.ClassName <> ClassName) do
  C := C.ClassParent;
Result := C <> nil
end;


Abessalom   (2005-06-07 23:35:00) [2]

Использовать формы из длл не очень-то рекомендуется, лучше использовать для этих целей run-time пакеты по многим причинам, в том числе по причине обязательной "одинаковости" реализации классов и значений глобальных переменных, таких как Application. Пачеко+Тексрейра указывают на то, что использовать классы, расположенные и реализованные в длл все-же можно при соблюдении четырех условий (одно из них то, что все методы объекта в длл д.б. виртуальными) - они приведены в главе 6 книги о Д6 Exporting Objects from DLLs - стр.287. Главу (172К) можно скачать здесь: webfile.ru/341948, пример к статье (13К) здесь - webfile.ru/341911


Andrey Kononov   (2005-06-07 17:56:00) [3]

Понятно. Спасибо за участие.


evvcom   (2005-06-07 17:42:00) [4]

Где-то недавно Digitman уже писал такую примерно фразу:
"Класс в exe и класс в dll - это совершенно разные классы!" Да и я уже устал повторять это. Хоть эти классы и имеют идентичный код и один и тот же ClassName, но код класса присутствует и в exe, и в dll, и адреса разные!


Andrey Kononov   (2005-06-07 17:38:00) [5]


> evvcom ©   (07.06.05 14:30) [12]
> А где у тебя TBaseForm реализован? Описан в unit, который
> потом сидит в uses и в exe, и в dll?


Да. Именно так.


> Digitman ©   (07.06.05 13:54) [11]
>
> ниже - то же самое, только чуть "красивей"
>
> if ActiveChildForm.ClassParent = TBASEFORM then
>


Не работает такая конструкция. Пробовал.


evvcom   (2005-06-07 14:30:00) [6]

А где у тебя TBaseForm реализован? Описан в unit, который потом сидит в uses и в exe, и в dll?


Digitman   (2005-06-07 13:54:00) [7]


> Нашел решение. Правда некрасивое, но все-таки...


действительно некрасивое

ниже - то же самое, только чуть "красивей"

if ActiveChildForm.ClassParent = TBASEFORM then

и уж если эти "некрасивое" и "чуть более красивое" решения работают, то должно работать и решение с is, потому как этот оператор неявно обращается все к тому же ClassParent


Andrey Kononov   (2005-06-07 12:30:00) [8]

Нашел решение. Правда некрасивое, но все-таки...


if UpperCase(ActiveChildForm.ClassParent.ClassName) = 'TBASEFORM' then
begin
 ...
end;


evvcom   (2005-06-07 11:05:00) [9]

Че-то мне телепатор более ничего не подсказывает.


Andrey Kononov   (2005-06-07 09:17:00) [10]

> evvcom

> Все должно работать, если это не опять работа с dll без галки "build with run-time packages"

Это работа с dll только с галкой "build with run-time packages"  пакеты "vcl". Здесь можно что-нибудь сделать?

> Abessalom

Пример попробовал - все работает. А в моем приложении не хочет.

Делаю так:



procedure TfrmMain.ItemClick(Sender: TObject);
begin
if ActiveMDIChild is TBaseForm then
  ShowMessage('Is TBaseForm')
else
  ShowMessage('It is not TBaseForm')
end;



Может вопрос действительно в том, что я использую dll?


Abessalom   (2005-06-06 20:36:00) [11]


> Sergey_Masloff   (06.06.05 17:00) [2]

оператор is в конечном счете вызывает этот самый инхериц фром.


> Andrey Kononov ©

Вроде у тебя все правильно, только каким образом ты все-таки определяешь, что у тебя не работает?

if not (ActiveMDIChild is TForm) then
//if not (ActiveMDIChild is TBaseForm) then
begin
  Exit;
end;
//A.: а здесь у тебя, ну, например, сообщение? О чем?


Не в логике ли потери? Создай две формы. Одна со стилем fsMDIForm (Form1), fsMDIChild(Form2). В проект добавь новую форму - наследника TForm2 - это будет TForm3. Обе формы - в список автоматического создания. Нижеприведенный код работает, как часы:

uses Unit2, Unit3;

{$R *.dfm}

procedure TForm1.ToolButton1Click(Sender: TObject);
begin
 if ActiveMDIChild is TForm3 then
   ShowMessage('TForm3')
 else if ActiveMDIChild is TForm2 then
   ShowMessage('TForm2');
end;


evvcom   (2005-06-06 17:29:00) [12]


> Сорри. Дочерние окна.

Не дочерние окна, а дочерние классы. Все должно работать, если это не опять работа с dll без галки "build with run-time packages"


Andrey Kononov   (2005-06-06 17:11:00) [13]

>Digitman

>галиматья какая-то ..

Сорри. Дочерние окна.
Но как быть-то, когда надо проверить? Неужели надо писать все окна от одного класса, или вводить какой-нибудь флаг в главной форме, который будет следить за типом активной формы?


Andrey Kononov   (2005-06-06 17:07:00) [14]

>> Как проверял?

В коде делал комментарии и проверял. Всегда наследник от TForm.

 if not (ActiveMDIChild is TForm) then
//  if not (ActiveMDIChild is TBaseForm) then
 begin
   Exit;
 end;

> Sergey_Masloff:

 Так тоже не работает. Или что-то не так сделал?

 if not ActiveMDIChild.InheritsFrom(TBaseForm) then
 begin
   Exit;
 end;


Digitman   (2005-06-06 17:02:00) [15]


> Есть дочерние приложения сделанные от TForm


галиматья какая-то ..

и немудрено что


> ActiveMDIChild никогда не бывает наследником TBaseForm


Skier   (2005-06-06 17:00:00) [16]


> хотя это не так

Как проверял ?


Sergey_Masloff   (2005-06-06 17:00:00) [17]

TObject:
class function InheritsFrom(AClass: TClass): Boolean;


Наверх

Титульная страница Поиск, карта сайта Написать письмо