![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как проверить является ли экземпляр потомком класса [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;