![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Подскажите метод генерации нового имени RealTime компонента [D7, WinXP]
dreamse © (2006-12-12 05:21:00)Создаю кнопки в 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
Не обрабатывает динамически созданые формы и компоненты на них. Как быть ?
Есть ли способ ГЛОБАЛЬНОГО поиска компонент во всём приложении или придёться делать рекрусивную функцию которая будет проверять в цикле ВСЕ контролы в приложении ? ( Что нежалательно )
В общем нужен простой способ сгенерировать новое название кнопки ( не из случайных чисел :) ) учитывая все контролы в приложении ( сколько форм тоже не известно заранее )
Джо (2006-12-12 21:55:00) [1]... или просто ее исходный код.
Джо (2006-12-12 21:55:00) [2]> Просто всегда Application.FindComponent('Button1') = nil
>
> хотя такая кнопка присутствует на форме
Ты посмотрел бы справку по FindComponent, наконец.
MetalFan (2006-12-12 21:55:00) [3]автор! какой на* RealTime??? в стратегии переиграл?
Runtime
dreamse (2006-12-12 21:50:00) [4]Всё не так просто, долго объяснять. Нужнен или поиск глобальный или рекрусивный поиск.
Глобальный Application.find не находит ничего так как кнопки все и форма создаёться в RealTime пожет я что то неправельное делаю при поиске ?
Просто всегда Application.FindComponent('Button1') = nil
хотя такая кнопка присутствует на форме
Наиль (2006-12-12 21:36:00) [5]Хранил бы переменые в массиве, вообще искать не пришлось.
dreamse (2006-12-12 21:33:00) [6]Код рекрусивного поиска представил , в парметрах нужно пердать Application + название икомого компонента , код перебирает все контрлы находит панель TRunpanel после чего перебирает на ней все кнопки и если находит искомую то передаёт ссылку на неё в result
Gothic_Snake (2006-12-12 21:32:00) [7]Аффтар, выпей ййаду!
dreamse (2006-12-12 21:31:00) [8]Что то наподобии такой функции :
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;
Anatoly Podgoretsky (2006-12-12 20:22:00) [9]> dreamse (12.12.2006 15:43:03) [3]
GUID
Наиль (2006-12-12 16:19:00) [10]Забыл упомянуть, что кроме индекса в настройках нужно указывать тип компонента (в любом виде), если они разные.
Во-первых, от этого зависит, как ты будешь работать с компонентом,
а во-вторых, это позволит воссоздать массив динамически.
Наиль (2006-12-12 16:15:00) [11]> Для сохранения параметров кнопки в файл конфигурации. Там
> используються имена для обозначения кнопок и они не должны
> совпадать
Если у тебя имена будут создаваться динамически, то вряд ли тебе удастся добиться соотвествия настроек реальным компонентам.
Поэтому задавать вопрос надо было про то, как правильно сохранять настройки.
> У компонента есть владелец. Это ПАНЕЛЬ которая распологаеться
> на ФОРМЕ
В твоём случае у компоненты есть не владелец (Owner), а родитель (Parent).
Хранить компоненты лучше в массиве или в TList.
Обращаться к ним по индексам. Сохранёный в настройках индекс указывает, к какому компоненту они относятся.
Сохранёная информация о родителе позволяет востановить положение на экране.
А использование имени для динамически создаваемых компонент, только запутывает и замедляет программу.
Elen (2006-12-12 16:08:00) [12]
> dreamse
А почему бы тебе не определить массив типа объект и не хранить в нем ссылки на созданные контролы, и задавать родителя как надо? Тогда в цикле по этому массиву пройдеш все где бы они не были.
Джо (2006-12-12 16:07:00) [13]> [3] dreamse (12.12.06 15:43)
> > Palladin © (12.12.06 05:52) [1]
>
> Вопрос не в том зачем , вопрос в том КАК ?
>
> > Джо © (12.12.06 05:58) [2]
>
> У компонента есть владелец. Это ПАНЕЛЬ которая распологаеться
> на ФОРМЕ
Я не о том. Ты в [0] написал:
> Не обрабатывает динамически созданые формы и компоненты
> на них. Как быть ?
StriderMan (2006-12-12 16:02:00) [14]может пригодится, как обойти рекурсивно компонентов-детей, можно параметром передать Application
procedureDoWithAll(AComponent: TComponent);
var
i: integer;
begin
//делаем что-то с AComponent;
for i := 0 to AComponent.ComponentCount - 1 do
DoWithAll(AComponent.Components[i]); //рекурсия
end;
Gloomer (2006-12-12 15:56:00) [15]А просто так нельзя:
function SetNameUnique(Name: string) : string;
begin
result:=Format('%s%d', [Name, i]);
inc(i);
end;
где i-глобальная?
novill (2006-12-12 15:54:00) [16]А какие вопросы? Ты чьим методом аштвсщьзщтуте пользуешься?
function FindComponent(const AName: string): TComponent;
Indicates whether a given component is owned by the component.
Главное, чтобы у этого владельца не было компонетов с таким именем. Если ты хочешь проверять по всему приложению, остается рекурсивно проверять все формы, компоненты на них и т.д.
dreamse (2006-12-12 15:48:00) [17]> Palladin © (12.12.06 15:46) [4]
Не стоит обижаться на мелочи :) мы тут не для того чтобы обижаться а для того чтобы помогать друг другу.
Palladin (2006-12-12 15:46:00) [18]
> [3] dreamse
это не глупые вопросы, это вопросы для попытки поиска другого более простого решения, но раз ты этого непонимаешь, то удачи... простое решение есть и без использования TComponent.Name...
dreamse (2006-12-12 15:43:00) [19]> Palladin © (12.12.06 05:52) [1]
Вопрос не в том зачем , вопрос в том КАК ?
> Джо © (12.12.06 05:58) [2]
У компонента есть владелец. Это ПАНЕЛЬ которая распологаеться на ФОРМЕ
Просто эта форма и эта же панель и кнопки на ней создаються в RealTime в связи с чем не удаёться узнать точно на какой форме они будут расположены и на какой панели.
Для чего сразу сажу чтобы не задавали глупых вопросов. Для сохранения параметров кнопки в файл конфигурации. Там используються имена для обозначения кнопок и они не должны совпадать
Второй минус что для нахождения нужной кнопки используеться опять поиск методом FindComponent И получаеться что если названия кнопок совпадают то находиться не та кнопка. в общем конфликтуюут.
Решение ?
Джо (2006-12-12 05:58:00) [20]Если у компонента нет владельца (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.
А зачем вообще такое понадобилось?