Форум: "Основная";
Текущий архив: 2005.02.13;
Скачать: [xml.tar.bz2];
ВнизКак обратиться к объекту, если еасть его имя. Найти похожие ветки
← →
tazik © (2005-01-25 21:01) [0]Здравствуйте!
Пишу такую прогу. Есть уменя на форме объекты определенных типов. Хочу составить дерево этих объектов, подобно Object Explorer
пример кода:
procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
var Comp: TComponent;
begin
Comp := TComponent(FindComponent(node.Text));
if Assigned(Comp) then
begin
if Comp.ClassName = "TTabSheet" then (*)
showMessage(comp.name);
...
Но когда выполяется (*) выскакивает Access violation. Что делать?
← →
Gero © (2005-01-25 21:08) [1]Вероятно Comp = nil.
← →
tazik © (2005-01-25 21:10) [2]Но почему, ведь я переменной comp явно назначаю значение. Может с помощью указателя?
← →
Gero © (2005-01-25 21:11) [3]
> Но почему, ведь я переменной comp явно назначаю значение
Вероятно FindComponent(node.Text) возвращает nil.
← →
begin...end © (2005-01-25 21:12) [4]> [3] Gero © (25.01.05 21:11)
Хм, но ведь тогда не выполнилась бы ветка if Assigned(Comp) then ...
← →
tazik © (2005-01-25 21:13) [5]И как этого избежать?
← →
tazik © (2005-01-25 21:14) [6]to begin...end
Вот и я про тоже! Может есть в АПИ какая-то ф-я&
← →
begin...end © (2005-01-25 21:17) [7]> tazik © (25.01.05 21:01)
> Comp := TComponent(FindComponent(node.Text));
Кстати, а зачем здесь приведение типа к TComponent?
Можно ведь и попроще: Comp := FindComponent(node.Text).
← →
Gero © (2005-01-25 21:17) [8]А ты уверен, что AV выскакивает именно на этой строчке?
← →
tazik © (2005-01-25 21:21) [9]Дело в том, что если убрать проверку
,
if Assigned(Comp) then
то AV выскакивает именно в строке (*)
← →
tazik © (2005-01-25 21:22) [10]пробовал и так:
Comp := FindComponent(node.Text)
Разницы нет. Всеравно AV!
← →
begin...end © (2005-01-25 21:23) [11]> [9] tazik © (25.01.05 21:21)
Т.е. что с проверкой, что без проверки - AV на одной и той же строчке?
← →
tazik © (2005-01-25 21:24) [12]Нет, не совсем. Если поставить проверку, то AV не возникает.
← →
Gero © (2005-01-25 21:26) [13]
> Если поставить проверку, то AV не возникает.
На мысли не наталкивает?
Смотри [1] в общем.
← →
Gero © (2005-01-25 21:26) [14]Проще говоря, скажи чему у тебя равно node.Text.
← →
begin...end © (2005-01-25 21:27) [15]> [12] tazik © (25.01.05 21:24)
Теперь уже я ничего не понимаю. Сначала (Ваш первый пост) Вы говорили, что AV в строке "*" возникает, если есть проверка на Assigned. Теперь говорите, что в случае наличия проверки AV не возникает. Как это понимать?
← →
tazik © (2005-01-25 21:28) [16]Node.text - имя объекта.
← →
tazik © (2005-01-25 21:30) [17]> to begin...end
Ситуация изначально такая. Если проверку поставить, то av не возникает. Если не поставить, то возникает.
← →
Gero © (2005-01-25 21:30) [18]
> tazik © (25.01.05 21:28
Значение свойства какое?
← →
Gero © (2005-01-25 21:32) [19]
> tazik © (25.01.05 21:30)
У тебя нет объекта с именем Node.text, если ты еще не понял.
← →
begin...end © (2005-01-25 21:32) [20]> [17] tazik © (25.01.05 21:30)
Эта проверка НУЖНА, понимаете?
← →
tazik © (2005-01-25 21:35) [21]> to Gero.
Подождите, дерево я строю по имеющимся объектам. Потом, когда щелкаю по node в treeView, пытаясь получить инфу об объекте, получаю такие новости, типа AV.
← →
Gero © (2005-01-25 21:39) [22]
> tazik © (25.01.05 21:35)
Я не знаю, как ты строишь дерево, зато вижу что FindComponent возвращает nil.
← →
tazik © (2005-01-25 21:42) [23]> Gero
Дерево строю посредством процедур, выписанных в отдельном файле.
← →
Gero © (2005-01-25 21:43) [24]
> tazik © (25.01.05 21:42)
Ответь на [18].
← →
tazik © (2005-01-25 21:44) [25]> Gero
Значение какого свойства, вы хотете узнать?
← →
Gero © (2005-01-25 21:46) [26]Node.text
← →
tazik © (2005-01-25 21:48) [27]> Gero
У меня Node.text := TabSheet.name;
В конкретном случае Node.text := "Tab1";
← →
Gero © (2005-01-25 21:50) [28]
> tazik © (25.01.05 21:48)
И ты уверен, что у тебя имеется компонент с именем Tab1?
← →
Gero © (2005-01-25 21:51) [29]> procedure TreeView1Change
Ты уверен, что в твоем исходнике все именно так?
← →
begin...end © (2005-01-25 21:51) [30]> [27] tazik © (25.01.05 21:48)
Чему равно свойство Owner для TabSheet?
Т.е. проверьте (ещё при создании дерева), чему равно Tab1.Owner.Name.
← →
tazik © (2005-01-25 21:54) [31]Ну а как же! Вот кусок процедуры по созданию TabSheet:
procedure CrtTab(Caption: string; ParentPC: TPageControl);
var Tab: TTabSheet;
begin
tab := TTabSheet.Create(ParentPC);
tab.PageControl := ParentPC;
tab.Caption := Caption;
tab.Name := Caption;
ParentPC.ActivePage := tab;
...
← →
tazik © (2005-01-25 21:57) [32]> [29] Gero
Абсолютно уверен. Дело в том, что у меня перед собой открытый исходник, я от туда все беру.
← →
begin...end © (2005-01-25 21:57) [33]> [31] tazik © (25.01.05 21:54)
> ParentPC: TPageControl
> tab := TTabSheet.Create(ParentPC)
А почему же Вы потом ищете этот компонент в списке Components формы, а не компонента-владельца - ParentPC?
← →
tazik © (2005-01-25 22:00) [34]> begin...end[33]
Дело в том, что у меня эта процедура выписана в отдельном файле.
← →
begin...end © (2005-01-25 22:04) [35]> [34] tazik © (25.01.05 22:00)
Ну и что?
← →
tazik © (2005-01-25 22:09) [36]>begin...end
Так ведь в качестве аргумента конструктора нужно списывать PageControl. и свойству PageControl тоже нужно указывать на PageControl
tab := TTabSheet.Create(ParentPC);
tab.PageControl := ParentPC;
← →
tazik © (2005-01-25 22:11) [37]>begin...end
Так ведь в качестве аргумента конструктора нужно списывать PageControl. и свойству PageControl тоже нужно указывать на PageControl
tab := TTabSheet.Create(ParentPC);
tab.PageControl := ParentPC;
← →
begin...end © (2005-01-25 22:11) [38]> [36] tazik © (25.01.05 22:09)
Почему же? Можно написать, например, так:tab := TTabSheet.Create({имя формы, на которой находится ParentPC});
tab.PageControl := ParentPC;
← →
tazik © (2005-01-25 22:17) [39]>begin...end
Как это? Ведь TabSheet создается на PageCtrl!!!
← →
tazik © (2005-01-25 22:27) [40]ЛАДНО! ВСЕМ БОЛЬШОЕ СПАСИБО ЗА ВНИМАНИЕ!!!! МНЕ ПОРА!!!!!
← →
Gero © (2005-01-25 22:51) [41]
> Абсолютно уверен. Дело в том, что у меня перед собой открытый
> исходник, я от туда все беру.
Тогда что такое FindComponent?
← →
tazik © (2005-01-26 09:05) [42]> Gero
FindComponent - это стандартная функция, типа TComponent, возращающая Component по его имени.
Form.FindComponent("SomeComponent").свойства
← →
ЮЮ © (2005-01-26 09:19) [43]TComponent.FindComponent
Indicates whether a given component is owned by the component.
Чей FindComponent работает в так нызываемом "примере кода"?
← →
ЮЮ © (2005-01-26 09:22) [44]Коль ты строишт дерево объектов, то это должен быть не Form.FindComponent, а <Компонент, соответствующий узлу дерева, содержащий текуший>.FindComponent
← →
begin...end © (2005-01-26 11:27) [45]> tazik
У каждого компонента (экземпляра класса TComponent или его потомка) есть свойства Owner (владелец) и Parent (родитель).
Владелец отвечает за уничтожение компонента. Т.е. если, например, указать в качестве владельца какого-нибудь создаваемого компонента форму, то она, когда будет уничтожаться сама, автоматически уничтожит и этот компонент. Владельца при создании экземпляра можно вообще не указывать, но в этом случае об уничтожении объекта нужно заботиться самостоятельно.
Свойство Parent влияет на то, кто будет управлять данным компонентом (отображать его).
У каждого компонента есть также свойство-массив Components - в него заносятся все компоненты, для которых родителем является данный компонент.
Метод FindComponent компонента просто ищет в списке Components компонент с нужным именем.
Вот Вы пишете:
> tab := TTabSheet.Create(ParentPC);
> tab.PageControl := ParentPC;
В первой строке Вы указываете, кто будет владельцем tab - ParentPC. Это означает, что за уничтожение tab будет отвечать ParentPC. И что после создания tab ссылка на неё окажется именно в массиве ParentPC.Components. Вместо ParentPC можно было указать, например, форму, или объект Application, т.е. любой компонент, или вообще NIL.
Во второй строке, фактически, происходит назначение свойства tab.Parent (см. в исходниках VCL реализацию метода tab.SetPageControl).
Поэтому теперь есть два варианта:
1. Оставить создание tab в том виде, в каком оно было до сих пор. Но учесть то, что владельцем (owner"ом) этой tab будет не форма, а ParentPC. И потом искать tab не в списке компонентов формы, как Вы это делали до сих пор, а в списке ParentPC.Components, т.е. вызывать метод ParentPC.FindComponent.
2. Назначать владельцем tab форму, а не ParentPC. Искать также, как Вы искали раньше, т.е. среди компонентов формы.
← →
tazik © (2005-01-26 21:54) [46]> to begin...end
Милый Вы мой человек! Спасибо Вам большое! Я давно ждал такого пояснения ситуации! Теперь я понял, что к чему! Побольше бы таких ответов! Еще раз, спасибо Вам!
← →
Юрий Зотов © (2005-01-26 22:14) [47]> begin...end © (26.01.05 11:27) [45]
Весьма достойно. Уважаю. Искренне.
← →
Skier © (2005-01-27 06:53) [48]
> У каждого компонента есть также свойство-массив Components
> - в него заносятся все компоненты, для которых родителем
> является данный компонент.
TComponent.Components - Lists all components owned by the component.
← →
begin...end © (2005-01-27 08:41) [49]> [48] Skier © (27.01.05 06:53)
Спасибо за поправку. Я как раз пытался показать разницу между родителем и владельцем, и...
В общем, читать следует так:
У каждого компонента есть также свойство-массив Components - в него заносятся все компоненты, для которых владельцем (owner"ом) является данный компонент.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.02.13;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.315 c