Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 21.10.2008, 09:43
vinni vinni вне форума
Начинающий
 
Регистрация: 26.01.2006
Сообщения: 135
Репутация: 10
По умолчанию Как получить доступ к динамически созданным объектам?

Доброго времени суток. Делаю следующее.
На форме есть PageControl с нулевым количеством вкладок. При нажатии на кнопку в нем создается вкладка, содержащая два Memo. При нажатии еще раз - еще одна вкладка с двумя Memo (как в QIP).
Как получить доступ к этим Memo? Т.е. нужно получить текст компонента TMemo (например, Memo2.Text) который был динамически создан на динамически созданной вкладке в PageControl :-) Задача несложная, просто никак не соображу как это сделать. Вот код:
Код:
 procedure TForm2.AddPage(PageCap: string);
var
  TSh: TTabSheet;
begin
    begin
      TSh := TTabSheet.Create(Self);
      TSh.Caption := PageCap;
      TSh.Parent := Self;
      TSh.PageControl := PageControl1;
      PageControl1.ActivePage := TSh;

      Memo1 := TMemo.Create(Self);
      Memo2 := TMemo.Create(Self);

      Memo1.Parent := TSh;
      Memo2.Parent := TSh;
end;
 
Ответить с цитированием
  #2  
Старый 21.10.2008, 10:03
Grunch Grunch вне форума
Новичок
 
Регистрация: 08.04.2008
Адрес: Краснодар
Сообщения: 52
Репутация: 10
По умолчанию

Используй TList
тут краткое описание
Ответить с цитированием
  #3  
Старый 21.10.2008, 10:03
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Т.к. переменная TSh у тебя локальная, то при окончании работы процедуры ссылка на нее теряется и доступа к ней ты получить не можешь. Но не будем унывать Вкладки ты создаешь так:
Код:
TSh := TTabSheet.Create(Self);
вопрос правильности/неправильности такого создания мы в данном контексте опустим. Следовательно владельцем вкладки будет являться форма (в твоем случае Form2). А как обратиться к обектам которыми владеет некий известный нам объект? А очень просто, перебором:
Код:
for i:=0 to ComponentCount-1 do
  if Components[i] is TTabSheet then
    <сюда попадет только в том случае если компонент формы будет являться экземпляром класса TTabSheet либо его наследником>
Теперь как мы будет добираться до конкретного листа. Допустим в предыдущем цикле мы выяснили что i=5, тогда для того чтобы обратиться к этому листу следует писать так:
Код:
(Components[5] as TTabSheet).<имя свойства или метода>
вот и все

ЗЫЖ Для Memo - аналогично
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #4  
Старый 21.10.2008, 10:23
vinni vinni вне форума
Начинающий
 
Регистрация: 26.01.2006
Сообщения: 135
Репутация: 10
По умолчанию

Aristarh Dark, следуя твоему совету, должно работать следующее:
Код:
procedure TfrmPrivMsg.acPrivSendExecute(Sender: TObject);
var
  I: integer;
begin
  for I := 0 to PageControl1.ActivePage.ComponentCount - 1 do
    Memo1.Lines.Add(PageControl1.ActivePage.Components[i].Name);
end;
Т.е. в Мемо1 должны появиться названия всех компонентов формы, и среди них Мемо1 и Мемо2. Но ничего не происходит...
Ответить с цитированием
  #5  
Старый 21.10.2008, 11:21
Rat Rat вне форума
Активный
 
Регистрация: 12.09.2008
Сообщения: 391
Репутация: 6078
По умолчанию

Что то я не пойму. Почти аналогично создаю TTabSheet:

Код:
var
  MainForm: TMainForm;
  Tab : TTabSheet;
  REdit: TRichEdit;

procedure TMainForm.ToolButton1Click(Sender: TObject);
begin
  Tab := TTabSheet.Create(PageControl1);
  Tab.Visible := true;
  Tab.Caption := 'Без имени.txt';
  Tab.PageControl := PageControl1;
  Tab.Hint := '';
  Tab.ShowHint := True;
  Tab.PopupMenu := EmptyPopupMenu;
  PageControl1.ActivePageIndex := Tab.TabIndex;
  REdit := TRichEdit.Create(Tab);
  REdit.Parent:= Tab;
  REdit.Align := alClient;
  REdit.PopupMenu := EditPopupMenu;
  Redit.Lines.Clear;
  REdit.Visible := True;
  REdit.SetFocus;
end;

И затем пытаюсь найти активный TTabSheet:

Код:
procedure TMainForm.ToolButton3Click(Sender: TObject);
var
  i : Integer;
begin
  if(SaveDialog1.Execute) then
  begin
    for i:=0 to ComponentCount-1 do
      if Components[i] is TTabSheet then
      begin
        if (Components[i] as TTabSheet).PageIndex = PageControl1.ActivePageIndex then
        begin
          ShowMessage('qwe');
        end;
      end;
    end;
end;

Сколько бы не создавал TTabSheet, ComponentCount у меня всё время равен 31. И ничего не находиться. Любой Components[i] = csInheritable. Что не так?

Последний раз редактировалось Rat, 21.10.2008 в 11:24.
Ответить с цитированием
  #6  
Старый 21.10.2008, 11:46
Rat Rat вне форума
Активный
 
Регистрация: 12.09.2008
Сообщения: 391
Репутация: 6078
По умолчанию

Всё. Понял. Сделал так:

Код:
procedure TMainForm.ToolButton3Click(Sender: TObject);
var
  i : Integer;
begin
  SaveDialog1.FileName := PageControl1.Pages[PageControl1.ActivePageIndex].Caption;

  if(SaveDialog1.Execute) then
  begin
    for i:=0 to PageControl1.ActivePage.ComponentCount-1 do
      if  PageControl1.ActivePage.Components[i] is TRichEdit then
      begin
        (PageControl1.ActivePage.Components[i] as TRichEdit).Lines.SaveToFile(SaveDialog1.FileName);
      end;
    end;
end;
Ответить с цитированием
  #7  
Старый 21.10.2008, 11:53
Rat Rat вне форума
Активный
 
Регистрация: 12.09.2008
Сообщения: 391
Репутация: 6078
По умолчанию

vinni. В Memo добавляются пустые строки. Т.к. Name = ''.

Можно сделать так:
Код:
Memo1.Lines.Add(PageControl1.ActivePage.Components[i].ClassName);
Ответить с цитированием
  #8  
Старый 21.10.2008, 13:26
vinni vinni вне форума
Начинающий
 
Регистрация: 26.01.2006
Сообщения: 135
Репутация: 10
По умолчанию

Вот именно, что даже пустые не добавляются. И при использовании ClassName тоже ничего не происходит.
Почему имена могут быть пустыми, ведь имя обязательно при создании:
Код:
 Memo1 := TMemo.Create(Self);
      Memo2 := TMemo.Create(Self);
Ответить с цитированием
  #9  
Старый 21.10.2008, 13:54
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

vinni, извинине, но Вы лопух.
Ясно было сказано:
Цитата:
Следовательно владельцем вкладки будет являться форма (в твоем случае Form2).
а Вы ищите их где?
Цитата:
for I := 0 to PageControl1.ActivePage.ComponentCount - 1 do
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #10  
Старый 21.10.2008, 14:00
vinni vinni вне форума
Начинающий
 
Регистрация: 26.01.2006
Сообщения: 135
Репутация: 10
По умолчанию

Rat, спасибо, сделал как у тебя. Ошибка была в том, что в качестве собственника я указывал Self и присваивал родителя (тоже Self). А нужно было в качестве собственника указать Tab (типа TTabSheet), а родителя не трогать вообще. И потом перебором при нахождении нужного типа берем нужные данные.
Ответить с цитированием
  #11  
Старый 21.10.2008, 14:03
Rat Rat вне форума
Активный
 
Регистрация: 12.09.2008
Сообщения: 391
Репутация: 6078
По умолчанию

Во первых сделай так:
Код:
Memo1 := TMemo.Create(TSh);
Memo2 := TMemo.Create(Tsh);

Во вторых имя не подставляется. Егу нужно указывать если ты создаешь динамически:
Код:
Memo1.Name := 'Name1';

Имя должно быть уникальным.
Ответить с цитированием
  #12  
Старый 21.10.2008, 14:08
Rat Rat вне форума
Активный
 
Регистрация: 12.09.2008
Сообщения: 391
Репутация: 6078
По умолчанию

Может кому пригодиться... В общем я бы обращался вот так:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    PageControl1: TPageControl;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  TSh: TTabSheet;
  Memo1, Memo2 : TMemo;
begin
      TSh := TTabSheet.Create(Self);
      TSh.Caption := 'PageCaption';
      TSh.Parent := Self;
      TSh.PageControl := PageControl1;
      PageControl1.ActivePage := TSh;
      Memo1 := TMemo.Create(TSh);
      Memo2 := TMemo.Create(Tsh);

      Memo1.Parent := TSh;
      Memo1.Align:= alTop;
      Memo1.Height := TSh.Height div 2;

      Memo2.Parent := TSh;
      Memo2.Align:= alBottom;
      Memo2.Height := TSh.Height div 2;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i : Integer;
begin
  for i:=0 to PageControl1.ActivePage.ComponentCount-1 do
  begin
    if PageControl1.ActivePage.Components[i] is TMemo then
    begin
      if (PageControl1.ActivePage.Components[i] as TMemo).ComponentIndex = 0 then
      begin
        (PageControl1.ActivePage.Components[i] as TMemo).Lines.Add('one');
      end;
    end;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i : Integer;
begin
  for i:=0 to PageControl1.ActivePage.ComponentCount-1 do
  begin
    if PageControl1.ActivePage.Components[i] is TMemo then
    begin
      if (PageControl1.ActivePage.Components[i] as TMemo).ComponentIndex = 1 then
      begin
        (PageControl1.ActivePage.Components[i] as TMemo).Lines.Add('two');
      end;
    end;
  end;
end;

end.

На форме должно быть три кнопки и один TPageControl.

Цитата:
вопрос правильности/неправильности такого создания мы в данном контексте опустим.
Aristarh Dark а как все таки правильно создавать?

Последний раз редактировалось Rat, 21.10.2008 в 14:10.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 16:00.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter