Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Доступ к компонентам динамической формы


Автор: harakiri 28.11.2013, 08:42
Здравствуйте. Интересует такой вопрос: есть две формы которые создаются динамически.
Код

var
  f1 : TForm1;
  f2 : TForm2;
...
  f1 := TForm1.Create(Self);
  f1.ShowModal;
...
  f2 := TForm2.Create(Self);
  f2.ShowModal;



На форме f1 есть label1. Как из формы f2 изменить f1.label1.Caption? Заранее спасибо. 

Автор: Poseidon 28.11.2013, 11:01
На строке f1.ShowModal выполнение кода остановится до тех пор, пока не будет закрыта эта форма, поэтому f2 даже не создастся. После того, как f1 будет закрыта, создастся f2, но нет смысла уже что-то менять на f1 т.к. она уже ведь закрыта. Не совсем ясно что конкретно должно получиться, но пока очевидна ошибка в архитектуре программы.  

Автор: harakiri 28.11.2013, 11:40
Poseidon, извините, я неправильно выразился. Есть форма f1 созданная динамически из главной формы. На форме f1 есть кнопка, которая создает и отображает форму f2. Нужно из формы f2(например, при закрытии) изменить label1.Caption который находиться на форме f1.

Автор: Poseidon 28.11.2013, 11:58
В таком случае f1.label1.Caption. Что не получается? Приведите "боевой" код, а то не понятно что не так. 

Автор: harakiri 28.11.2013, 16:25
Главная форма:
Код

unit SDIMAIN;

interface

uses Windows, Classes, Graphics, Forms, Controls, Menus,
  Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, ImgList, StdActns,
  ActnList, ToolWin;

type
  TSDIAppForm = class(TForm)
    OpenDialog: TOpenDialog;
    SaveDialog: TSaveDialog;
    ToolBar1: TToolBar;
    ToolButton9: TToolButton;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ActionList1: TActionList;
    FileNew1: TAction;
    FileOpen1: TAction;
    FileSave1: TAction;
    FileSaveAs1: TAction;
    FileExit1: TAction;
    EditCut1: TEditCut;
    EditCopy1: TEditCopy;
    EditPaste1: TEditPaste;
    HelpAbout1: TAction;
    StatusBar: TStatusBar;
    ImageList1: TImageList;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    FileNewItem: TMenuItem;
    FileOpenItem: TMenuItem;
    FileSaveItem: TMenuItem;
    FileSaveAsItem: TMenuItem;
    N1: TMenuItem;
    FileExitItem: TMenuItem;
    Edit1: TMenuItem;
    CutItem: TMenuItem;
    CopyItem: TMenuItem;
    PasteItem: TMenuItem;
    Help1: TMenuItem;
    HelpAboutItem: TMenuItem;
    Button1: TButton;
    procedure FileNew1Execute(Sender: TObject);
    procedure FileOpen1Execute(Sender: TObject);
    procedure FileSave1Execute(Sender: TObject);
    procedure FileExit1Execute(Sender: TObject);
    procedure HelpAbout1Execute(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  SDIAppForm: TSDIAppForm;

implementation

uses about, fmForm1;

{$R *.dfm}

procedure TSDIAppForm.FileNew1Execute(Sender: TObject);
begin
  { Do nothing }
end;

procedure TSDIAppForm.FileOpen1Execute(Sender: TObject);
begin
  OpenDialog.Execute;
end;

procedure TSDIAppForm.FileSave1Execute(Sender: TObject);
begin
  SaveDialog.Execute;
end;

procedure TSDIAppForm.Button1Click(Sender: TObject);
var
  f1:TForm1;
begin
  f1 := TForm1.Create(Self);
  f1.ShowModal;
end;


procedure TSDIAppForm.FileExit1Execute(Sender: TObject);
begin
  Close;
end;

procedure TSDIAppForm.HelpAbout1Execute(Sender: TObject);
begin
  AboutBox.ShowModal;
end;

end.

Форма на которой расположен Label, Caption которого нужно изменить:
Код

unit fmForm1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
  public

  end;

var
  Form1: TForm1;

implementation

uses fmForm2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  f2:TForm2;
begin
  f2 := TForm2.Create(Self);
  f2.ShowModal;
end;

end.

Форма из которой нужно изменить Caption:
Код

unit fmForm2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses fmForm1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  form1.Label1.Caption := 'asdasd';
end;

end.

При нажатии на TForm2.Button1 ошибка - Access violationat adress...

Автор: БелАмор 28.11.2013, 17:16
Цитата(harakiri @  28.11.2013,  17:25 Найти цитируемый пост)

var
  Form1: TForm1;

implementation


Цитата(harakiri @  28.11.2013,  17:25 Найти цитируемый пост)
procedure TForm1.Button1Click(Sender: TObject);
var
  f2:TForm2;
begin
  f2 := TForm2.Create(Self);
  f2.ShowModal;
end;


Цитата(harakiri @  28.11.2013,  17:25 Найти цитируемый пост)
procedure TForm2.Button1Click(Sender: TObject);
begin
  form1.Label1.Caption := 'asdasd';
end;


Цитата(harakiri @  28.11.2013,  17:25 Найти цитируемый пост)
При нажатии на TForm2.Button1 ошибка - Access violationat adress...


Логично.

Если вам из form2 в form1 кроме Label1 ничего не надо, то можно в form2 сделать поле типа TLabel, и при создании form2 сразу присваивать ему ссылку на соответствующий label, и обращаться к нему потом через это поле, вообще не интересуясь, где он находится.

Автор: harakiri 28.11.2013, 18:07
Цитата(БелАмор @ 28.11.2013,  17:16)
Логично.

Если вам из form2 в form1 кроме Label1 ничего не надо, то можно в form2 сделать поле типа TLabel, и при создании form2 сразу присваивать ему ссылку на соответствующий label, и обращаться к нему потом через это поле, вообще не интересуясь, где он находится.

Если Вам не трудно, можете немножко подробнее объяснить.

Автор: БелАмор 28.11.2013, 19:54
Цитата(harakiri @  28.11.2013,  19:07 Найти цитируемый пост)
Если Вам не трудно, можете немножко подробнее объяснить.


Есть важный принцип, которого следует придерживаться, и не отходить от него без очень веских на то оснований.
Принцип следующий:

1. Вызывающий должен знать вызываемого.
2. Вызываемый не должен знать вызывающего.
3. Все необходимые исходные данные вызываемому передаются либо через параметры, либо заранее сообщаются через его свойства.
4. Если нужно вернуть результат, то вызываемый это делает через возвращаемое значение, либо самостоятельно кладёт его туда, куда ему указали через параметры или свойства.

В соответствии с этим принципом, Form2 ничего не должна знать о Form1, в том числе то, что там есть Label1.
Однако, если  Form2 должна что-то писать в Form1.Label1, то ей нужен некий минимум информации. Этот минимум - ссылка на этот самый TLabel. Знать, что он расположен на форме Form1 совершенно не обязательно, более того, при необходимости можно будет выводить в любой нужный TLabel на любой нужной форме, не привязываясь ни к чему конкретному заранее. Поэтому достаточно каким-либо образом сообщить Form2, куда она должна будет выводить своё сообщение. Это можно сделать примерно так:

Код

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FOutputLabel: TLabel;
  public
     property OutputLabel: TLabel read FOutputLabel write FOutputLabel ;
 end;


Код

procedure TForm1.Button1Click(Sender: TObject);
var
  f2:TForm2;
begin
  f2 := TForm2.Create(Self);
  f2.OutputLabel := Label1;
  f2.ShowModal;
end;


Код

procedure TForm2.Button1Click(Sender: TObject);
begin
  if Assigned(FOutputLabel) then
    FOutputLabel.Caption := 'asdasd';
end;


Автор: Агрох 2.12.2013, 09:39
Так у вас же форма, у которой надо Label1.Caption поменять, называется не form1 а f1. Т.е. и вызвать надо не 
Код

form1.Label1.Caption := 'asdasd';
 а 
Код

f1.Label1.Caption := 'asdasd';


Я не удивлюсь если вы form1 вообще не создавали, т.к. она, судя по всему, вам не нужна. Т.е. вам нужно создавать её только динамически.

Кстати, Poseidon это сразу написал, ещё не видя вашего кода.

Автор: harakiri 15.12.2013, 13:55
БелАмор, огромное спасибо. Все получилось, не все еще пока понятно, но будем читать. Еще раз спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)