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

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

Подскажите метод генерации нового имени RealTime компонента [D7, WinXP]


Страницы:   1 2

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.

А зачем вообще такое понадобилось?


Страницы:   1 2

Наверх

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