Przekazywanie danych miedzy formami i wywołanie procedury formy głównej z formy podrzędnej.

0

Z góry przepraszam jeśli to ju było a zapewne było tylko nie potrafię znaleźć. Jeśli tak to poproszę link i spadam :).
Mam formę główną. Wywołuje formę podrzędną. Form2.show. Na form2 mam listView. Tu wykonują się jakieś zadania. Pojawia się efekt.
Teraz chciałbym wykorzystać ten efekt i przeanalizować dane listview na głównej formie tymi danymi. Po zakończeniu tej analizy i zamknięciu form2 powinna się automatycznie odpalić jedna z procedur na formie głównej.

Wiem jak odwoływać sie do formy podrzędnej. W tym celu w uses wskazuje formę podrzędną i nie ma problem. Niestety odwrotnie to nie działa. Help

0
norbert_kacz napisał(a):

Wiem jak odwoływać sie do formy podrzędnej. W tym celu w uses wskazuje formę podrzędną i nie ma problem. Niestety odwrotnie to nie działa. Help
Oczywiście, że działa. Musisz coś źle robić. Pokaż kod, bo teraz to wróżenie z fusów.

0

form 1

 unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, unit2, Vcl.StdCtrls;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
unit2.Form2.Show;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

end.

form2

 unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

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

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
 unit1.edit1.text := 'Cos'; - to nie działa - 
end;

end.
0

No i teraz jeszcze fajnie by było abyś napisał co Twoim zdaniem oznacza, że nie działa... Bo nie widzę dołączonego unit1 do unit1.

0

Jak to unit1 do unit1? delphi mi nie pozwala ani dolaczyc unit1 (w uses) do unit1 ani do unit2. Mozna jasniej bo mnie zamurowało :)

0

Sposób najprostszy:

unit Unit2;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
 
type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation 

uses Unit1;
 
{$R *.dfm}
 
procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.edit1.text:='Cos';
end;
 
end.

Sposób sensowny:

unit1.pas:

unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses unit2;

{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.MainForm:=Self;
  Form2.Show;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
 
end;
 
end.

unit2.pas:

 unit Unit2;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, unit1;
 
type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
    MainForm:TForm1; // może lepiej setera dodać
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.dfm}
 
procedure TForm2.Button1Click(Sender: TObject);
begin
  MainForm.edit1.text := 'Cos'; - to nie działa - 
end;
 
end.
0

Jestes the best. Szukalem, szukalem i szukalem i nic. Mysle, ze nie ja jeden.
Wszystkie odpowiedzi jakie znalazlem strasznie komplikowaly temat. A to jest takie proste.
BARDZO, BARDZO DZIEKUJĘ!.

0

Im prostszy sposób tym bardziej niebezpieczny (przeważnie) - należy to pamiętać.

0

Niestety wersja uproszczona mi dziala ale sensowna juz nie

MainForm : TForm1; // może lepiej setera dodać - to nie dziala
0

Tak jest! :) Dziekuje

A mozna jeszcze troszkę teorii?
Za co odpowiada Form2.MainForm:=Self; ?

0

Za zmianę składowej: MainForm:TForm1; // może lepiej setera dodać

1

Jako alternatywę, ew. ciekawostkę, przedstawię nieco inny sposób; Z racji tej, że obiekty formularzy i tak są globalne, nie ma sensu ich gdziekolwiek przekazywać; W zamian za to, główny formularz powinien mieć publiczną metodę, która służyć będzie do ustalania tekstu dla komponentu;

Przykład:

unit Unit1;

{..}

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  public
    procedure SetEditText(const AText: String);
  end;

{..}

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show();
end;

procedure TForm1.SetEditText(const AText: String);
begin
  Edit1.Text := AText;
end;
unit Unit2;

{..}

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

{..}

implementation

{$R *.dfm}

uses
  Unit1;

procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.SetEditText('foo bald bar');
end;

Dzięki temu nie trzeba będzie każdej klasie okna potomnego przekazywać referencji do obiektu głównego formularza; Zresztą taki jest właśnie cel domyślnej deklaracji obiektów formularzy jako zmiennych globalnych.

0

Obiekty formularzy są globalne i utworzone w przypadku domyślnej budowy aplikacji , która wtedy tworzy instancję każdej formy zawartej w projekcie w oparciu o jej definicję i deklarację zmiennej w module formy .
Ja tego unikam , i za atomatu tworzę tylko isntancje obiektów niezbędznych do działania apliakcji , np takie jak "datamodule" i formę główną apliakcji , a wszystkie inne formy przywołuję do życia i zwalniam zgodnie z logiką aplikacji

0

Bardzo często stosuję konstrukcję:

unit DlgEdit;

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

type
  TADlgEdit=class(TForm)
    XEdit:TEdit;
  private
    procedure SetData(X:Integer);
    procedure GetData(var X:Integer);
  public
    class function Execute(var X:Integer):Boolean;
  end;

var ADlgEdit:TADlgEdit;

implementation

{$R *.DFM}

class function TADlgEdit.Execute(var X:Integer):Boolean;
begin
  with Create(Application) do
  begin
    try
      SetData(X);
      Result:=(ShowModal=mrOk);
      if Result then GetData(X);
    finally
      Free;
    end;
  end;
end;

procedure TADlgEdit.SetData(X:Integer);
begin
  XEdit.Text:=IntToStr(X);
end;

procedure TADlgEdit.GetData(var X:Integer);
begin
  X:=StrToIntDef(XEdit.Text,0);
end;

end.

Zamiast X:Integer przeważnie jakiś: TDataRecord=record ... end;

Użycie:

procedure TAMainForm.BtnCallDlgEditClick(Sender:TObject);
var X:Integer;
begin
  X:=0;
  if TADlgEdit.Execute(X) then
  begin
    Caption:=IntToStr(X);
  end;
end;

W przypadku kiedy potrzebuję CallBack'a to robię to poprzez zadeklarowane nazwane komunikaty.

1 użytkowników online, w tym zalogowanych: 0, gości: 1