Форум: "Начинающим";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];
ВнизПодскажите метод генерации нового имени RealTime компонента Найти похожие ветки
← →
dreamse (2006-12-12 05:21) [0]Создаю кнопки в RealTime И столкнулся с проблемой генерации нового имени. Проблема заключаеться в чём :
Есть панель : Tpanel на ней генеряться кнопки , написал процедуру создания нового имени для кнопки. Но проблема в том что имя ищеться непосредствено на Tpanel , если же положить на форму ещё одну Tpanel то соответственно функция создания имени не сможет обработать и вторую ( так как неизвестно сколько всего панелей могут быть на форме )
Соответственно получаеться путаница так как может на разных панелях быть по одинаковому названию кнопок :(
Использую следующий код :
// Ãåíåðàöèÿ íîâîãî èìåíè
function SetNameUnique(Name: string) : string;
var
i: Integer;
tempname: string;
begin
i := 1;
Name := Name + "1";
tempname := Name;
while Application.FindComponent(Name) <> nil do
begin
Inc(i);
Name := Format("%s%d", [tempname, i]);
end;
result := Name;
end;
Правда не уверен что он нормально генерирует имена. Минус в том что строка : while Application.FindComponent(Name) <> nil do
Не обрабатывает динамически созданые формы и компоненты на них. Как быть ?
Есть ли способ ГЛОБАЛЬНОГО поиска компонент во всём приложении или придёться делать рекрусивную функцию которая будет проверять в цикле ВСЕ контролы в приложении ? ( Что нежалательно )
В общем нужен простой способ сгенерировать новое название кнопки ( не из случайных чисел :) ) учитывая все контролы в приложении ( сколько форм тоже не известно заранее )
← →
Palladin © (2006-12-12 05:52) [1]Зачем тебе имена?
← →
Джо © (2006-12-12 05:58) [2]Если у компонента нет владельца (Owner = nil), то "найти" его никак нельзя.
Сравни:procedure TForm1.Button1Click(Sender: TObject);
begin
// Вызывает ошибку времени выполнения "Component named Button1 already exists"
TComponent.Create(Self).Name := "Button1";
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Никакой ошибки не будет
TComponent.Create(nil).Name := "Button1";
end;
Такая логика реализована в методеSetName
у TComponent.
А зачем вообще такое понадобилось?
← →
dreamse (2006-12-12 15:43) [3]> Palladin © (12.12.06 05:52) [1]
Вопрос не в том зачем , вопрос в том КАК ?
> Джо © (12.12.06 05:58) [2]
У компонента есть владелец. Это ПАНЕЛЬ которая распологаеться на ФОРМЕ
Просто эта форма и эта же панель и кнопки на ней создаються в RealTime в связи с чем не удаёться узнать точно на какой форме они будут расположены и на какой панели.
Для чего сразу сажу чтобы не задавали глупых вопросов. Для сохранения параметров кнопки в файл конфигурации. Там используються имена для обозначения кнопок и они не должны совпадать
Второй минус что для нахождения нужной кнопки используеться опять поиск методом FindComponent И получаеться что если названия кнопок совпадают то находиться не та кнопка. в общем конфликтуюут.
Решение ?
← →
Palladin © (2006-12-12 15:46) [4]
> [3] dreamse
это не глупые вопросы, это вопросы для попытки поиска другого более простого решения, но раз ты этого непонимаешь, то удачи... простое решение есть и без использования TComponent.Name...
← →
dreamse (2006-12-12 15:48) [5]> Palladin © (12.12.06 15:46) [4]
Не стоит обижаться на мелочи :) мы тут не для того чтобы обижаться а для того чтобы помогать друг другу.
← →
novill © (2006-12-12 15:54) [6]А какие вопросы? Ты чьим методом аштвсщьзщтуте пользуешься?
function FindComponent(const AName: string): TComponent;
Indicates whether a given component is owned by the component.
Главное, чтобы у этого владельца не было компонетов с таким именем. Если ты хочешь проверять по всему приложению, остается рекурсивно проверять все формы, компоненты на них и т.д.
← →
Gloomer © (2006-12-12 15:56) [7]А просто так нельзя:
function SetNameUnique(Name: string) : string;
begin
result:=Format("%s%d", [Name, i]);
inc(i);
end;
где i-глобальная?
← →
StriderMan © (2006-12-12 16:02) [8]может пригодится, как обойти рекурсивно компонентов-детей, можно параметром передать Application
procedure DoWithAll(AComponent: TComponent);
var
i: integer;
begin
//делаем что-то с AComponent;
for i := 0 to AComponent.ComponentCount - 1 do
DoWithAll(AComponent.Components[i]); //рекурсия
end;
← →
Джо © (2006-12-12 16:07) [9]> [3] dreamse (12.12.06 15:43)
> > Palladin © (12.12.06 05:52) [1]
>
> Вопрос не в том зачем , вопрос в том КАК ?
>
> > Джо © (12.12.06 05:58) [2]
>
> У компонента есть владелец. Это ПАНЕЛЬ которая распологаеться
> на ФОРМЕ
Я не о том. Ты в [0] написал:
> Не обрабатывает динамически созданые формы и компоненты
> на них. Как быть ?
← →
Elen © (2006-12-12 16:08) [10]
> dreamse
А почему бы тебе не определить массив типа объект и не хранить в нем ссылки на созданные контролы, и задавать родителя как надо? Тогда в цикле по этому массиву пройдеш все где бы они не были.
← →
Наиль © (2006-12-12 16:15) [11]> Для сохранения параметров кнопки в файл конфигурации. Там
> используються имена для обозначения кнопок и они не должны
> совпадать
Если у тебя имена будут создаваться динамически, то вряд ли тебе удастся добиться соотвествия настроек реальным компонентам.
Поэтому задавать вопрос надо было про то, как правильно сохранять настройки.
> У компонента есть владелец. Это ПАНЕЛЬ которая распологаеться
> на ФОРМЕ
В твоём случае у компоненты есть не владелец (Owner), а родитель (Parent).
Хранить компоненты лучше в массиве или в TList.
Обращаться к ним по индексам. Сохранёный в настройках индекс указывает, к какому компоненту они относятся.
Сохранёная информация о родителе позволяет востановить положение на экране.
А использование имени для динамически создаваемых компонент, только запутывает и замедляет программу.
← →
Наиль © (2006-12-12 16:19) [12]Забыл упомянуть, что кроме индекса в настройках нужно указывать тип компонента (в любом виде), если они разные.
Во-первых, от этого зависит, как ты будешь работать с компонентом,
а во-вторых, это позволит воссоздать массив динамически.
← →
Anatoly Podgoretsky © (2006-12-12 20:22) [13]> dreamse (12.12.2006 15:43:03) [3]
GUID
← →
dreamse (2006-12-12 21:31) [14]Что то наподобии такой функции :
function TRunpanel.ComponentButtonFound(panelcount: TComponent; ButtoonName: string) : TComponent;
var
i,n: integer;
begin
if panelcount = nil then exit;
for i := 0 to panelcount.ComponentCount - 1 do
begin
if (panelcount.Components[i] is TRunpanel) then
for n := 0 to TRunpanel(panelcount.Components[i]).ComponentCount - 1 do
begin
if (TRunpanel(panelcount.Components[i]).Components[n] is TShellRunPanelButton) then
if TShellRunPanelButton(TRunpanel(panelcount.Components[i]).Components[n]).Name = ButtoonName then
begin
result:= TShellRunPanelButton(TRunpanel(panelcount.Components[i]).Components[n]);
break;
end;
end;
end;
if result = nil then
ComponentButtonFound(panelcount.Components[i],ButtoonName);
end;
← →
Gothic_Snake (2006-12-12 21:32) [15]Аффтар, выпей ййаду!
← →
dreamse (2006-12-12 21:33) [16]Код рекрусивного поиска представил , в парметрах нужно пердать Application + название икомого компонента , код перебирает все контрлы находит панель TRunpanel после чего перебирает на ней все кнопки и если находит искомую то передаёт ссылку на неё в result
← →
Наиль © (2006-12-12 21:36) [17]Хранил бы переменые в массиве, вообще искать не пришлось.
← →
dreamse (2006-12-12 21:50) [18]Всё не так просто, долго объяснять. Нужнен или поиск глобальный или рекрусивный поиск.
Глобальный Application.find не находит ничего так как кнопки все и форма создаёться в RealTime пожет я что то неправельное делаю при поиске ?
Просто всегда Application.FindComponent("Button1") = nil
хотя такая кнопка присутствует на форме
← →
MetalFan © (2006-12-12 21:55) [19]автор! какой на* RealTime??? в стратегии переиграл?
Runtime
← →
Джо © (2006-12-12 21:55) [20]> Просто всегда Application.FindComponent("Button1") = nil
>
> хотя такая кнопка присутствует на форме
Ты посмотрел бы справку по FindComponent, наконец.
← →
Джо © (2006-12-12 21:55) [21]... или просто ее исходный код.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.046 c