Przesyłanie zmiennych między formularzami

intol

Często pisząc programy w C++ Builderze zastanawiałem się, jak przesyłać zmienne pomiędzy dwoma różnymi formularzami. Do tej pory posługiwałem się rozwiązaniem, które polegało na deklarowaniu zmiennej w pierwszym formularzu jako globalną, a w drugim ponownie deklarowaną, z tą że różnicą, iż tym razem ze słówkiem extern, które informowało kompilator, że zmienna znajduje się gdzieś poza plikiem. Oczywiście wtedy do drugiego formularza należało dołączyć plik nagłówkowy pierwszego. To rozwiązanie miało kilka swoich minusów i było raczej niewygodne. Przy kilku formularzach można było pogubić się która zmienna należała do którego.

 Może to brzmi jak to tej pory trochę zawile, ale postaram się przedstawić Wam sposób prostszy. 

 Otóż jak wszyscy wiemy (a jak nie wiemy to powinniśmy!), formularz w C++ Builderze to obiekt. Jak większość obiektów w C++ ma swoje właściwości, takie jak np. wysokość, szerokość i nazwa. Większość (znowu to słowo, no ale chodzi o to że nie wszystkie) właściwości to zwykłe wartości typu int , czy char. No a czym są nasze zmienne które chcemy przekazywać? Również wartościami typu int czy char, choć mogą to i być obiekty klasy AnsiString. Przechodzimy więc do setna sprawy. Aby móc sprawnie korzystać ze zmiennych jednego formularza w drugim, wystarczy zadeklarować je w sekcji public formularza. W tym celu otwieramy plik nagłówka pierwszego formularza (rozszerzenie .h) - np. klikając prawym klawiszem na kodzie źródłowym pliku CPP i z menu kontekstowego wybierając "Open Source / Header File" i odnajdujemy w nim sekcję public: . Po niej dopisujemy np. 
int rower;
int koza;
AnsiString radiowoz;
 

przykładowy wygląd pliku unit1.h

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations

int rower;
int koza;
AnsiString radiowoz;

__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif  
 Pamiętaj aby nie definiować zmiennych (nie przypisywać im wartości) w tym miejscu, ponieważ kompilator uzna to za błąd. Możesz je zdefiniować w konstruktorze formularza (funkcji, znajdującej się w pliku .cpp, która nazywa się jak klasa tworzonego obiektu, czyli np. TForm). Po zadeklarowaniu zmiennych w formularzu w którym to zrobiliśmy, możemy odwoływać się do nich jak do zwykłych zmiennych globalnych. 

przykład definicji zmiennych w pliku Unit1.cpp wcześniej zadeklarowanych w pliku Unit1.h

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
rower = 1;
koza = 2;
radiowoz = "Policja";
}
//--------------------------------------------------------------------------- 
 Jeżeli teraz chcemy odczytać/zapisać coś z/do zmiennej zdefiniowanej ,załóżmy, w formularzu o nazwie Form1, odnosimy się do nich w taki sposób: 

Form1->nazwa_zmiennej
czyli np.

Form1-&gt;rower = 10;

Trzeba jednak pamiętać, aby w formularzu w którym odnosimy się do zmiennej z Form1 załączyć plik nagłówkowy tego formularza (Form1). Bez tego kompilator zaprotestuje.

przykład użycia w formularzu 2 zmiennych z formularza 1

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void TForm2::JakasFunkcja
{
Form1-&gt;rower = 5;
Form1-&gt;koza = 2;
Form1-&gt;radiowoz = "Straż";
}  
 Mam nadzieję że przedstawiony tu sposób korzystania ze zmiennych z jednego formularza w innym przyda się Wam, przynajmniej początkującym programistom piszącym w C++ Builderze (choć ten już powoli odchodzi :-( ). W zasadzie jednak w Delphi i X Builderze to też powinno działać. 

--
Autor: Mariusz Żurawek (INTOL)
WWW: www.zurawek.com
Wszelkie prawa zastrzeżone.

7 komentarzy

Form1->rower = 5;

to po prostu błąd kodowania. Wiadomo,ze jest tam strzałka -_-

Form1->rower = 5;

NIEDZIALA !! WYchodzi ze gt jest niezdefiniowanie !!!! Poradzi ktos cos ??

Tego właśnie potrzebowalem... Musze to teraz wytestowac :D

można przeciążyć konstrutor formularza i w nim przekazac parametry ale tylko jeśli formularz ten jest tworzony pozniej niz ten z ktorego chcemy przekazać dane. Jeśli jest na odwrót czyli np form1 to okno glowne a form 2 to okno opcji i chcemu przekazać dane z form2 do form1 to konstruktor tu nie pomoże.

A nie latwiej przeciazyc konstruktor formularza i w nim przekazac parametr, jak np.:

__fastcall TForm1::TForm1(TComponent* Owner, int ALiczba)
: TForm(Owner), FLiczba(ALiczba)
{
}

Wtedy FLiczba moze byc skladowa public albo private TForm1.

acha i mała uwaga... w Builderze o ile dobrze pamiętam we własnościach nigdy nie wykorzystywało sie typu char .. zawsze był AnsiString :)

nie martw sie to zawsze bedzie dzialac niezaleznie od tego jakiego środowiska się bedzie używac... bo to podstawy programowania obiektowego C++