Borland C++ Builder - przesyłanie zmiennych pomiędzy oknami(formami)

0

Witam,

Program składa się z:

  • Form1
  • Form2

Mam nastepujący problem:

  • W Form1 Losuje sobie dowolną liczbę typu int i chce przekazać ją do Form2.
  • W Form2 mam kilka if-ów, które zależą od tej zmiennej.

Robiłem mały research ale nigdzie nie moge znaleźć w miare prostego rozwiazania jak to zrobić.
Próbowałem z extern oraz z ustawieniem zmiennej jako publiczną. Nawet coś tam działało, jednak musiałem umieścić zmienną w funkcji:

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
	//np
	liczba = 7;
}

i tam zadeklarować jej wartość na sztywno.

A ja chciałbym np. żeby po kliknieciu buttona w Form1, zmienna została wylosowana, a nastepnie wyswietlil sie Form2, ktory "wie" ile wynosi wartosc wylosowanej liczby.

0

Poprzez konstruktor przekazujesz wskaźnik na inne okno.
Zaś jeżeli okna stworzone automagicznie i nigdy ich nie niszczysz to używaj zmiennych: Form1, Form2 itp.

0

Probuje i probuje, ale kompilator ciagle wywala bledy. Czy moglbys mnie naprowadzic co i gdzie mam wpisać. Poniżej wklejam kod.
W Unit2.cpp mam Labela, w ktorym chce po prostu wyswietlic wartosc wylosowanej liczby. Program sprowadzilem do najprostszej postaci, aby skupic sie tylko na istocie mojego nieszczesnego problemu.

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
        TButton *Przycisk;
        void __fastcall PrzyciskClick(TObject *Sender);
private:	// User declarations
public:		// User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit2.h

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

#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:	// IDE-managed Components
        TLabel *Label1;
        void __fastcall FormCreate(TObject *Sender);
private:	// User declarations
public:		// User declarations
        __fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif

Unit1.cpp

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

#include <vcl.h>
#pragma hdrstop

#include <time.h>
#include "Unit1.h"
#include "Unit2.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int liczba;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        //Konstruktor Form1
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PrzyciskClick(TObject *Sender)
{
    srand(time(NULL));
    liczba = rand()%3+1;

    Form2->ShowModal();
}
//---------------------------------------------------------------------------

Unit2.cpp

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

#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)
{
        //Konstruktor Form2
}
//---------------------------------------------------------------------------

void __fastcall TForm2::FormCreate(TObject *Sender)
{
   //W tym miejscu chcialbym wyswietlic liczbe wylosowana w Form1
   Label1->Caption = liczba;
   //oczywiscie ten zapis poki co nie ma sensu ...
}
//---------------------------------------------------------------------------
0

Najprościej: int liczba; przenosisz do: Unit1.h pod: __fastcall TForm1(TComponent* Owner);
Label1->Caption = liczba; zamieniasz na: Label1->Caption = Form1->liczba;

0

Kiedyś już próbowałem rozwiązać mój problem w ten sposób, ale za każdym razem po wylosowaniu liczby wyświetla mi się zero. To samo w przypadku, gdy deklaruje zmienną i przypisuje jej konkretną wartość. Dziwne.

1

Najprościej moim zdaniem by było jakbyś tworzył okno dynamicznie i wtedy można przekazać w konstruktorze interesującą Cię wartość. Bez zmiennych globalnych itp. Wtedy wystarczy tak:
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
        TButton *Przycisk;
        void __fastcall PrzyciskClick(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit2.h

//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:    // IDE-managed Components
        TLabel *Label1;
        void __fastcall FormCreate(TObject *Sender);
private:    // User declarations
  int liczba;
public:        // User declarations
        __fastcall TForm2(TComponent* Owner, int _liczba);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif

Unit1.cpp

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include <time.h>
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        //Konstruktor Form1
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::PrzyciskClick(TObject *Sender)
{
    srand(time(NULL));
    liczba = rand()%3+1;
 
    Form2 = new TForm2(this,liczba);
    Form2->ShowModal();
    delete From2;
    Form2 = NULL;
}
//---------------------------------------------------------------------------

Unit2.cpp

//---------------------------------------------------------------------------
#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, int _liczba)
        : TForm(Owner)
{
        //Konstruktor Form2
    this->liczba = _liczba;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm2::FormCreate(TObject *Sender)
{
   Label1->Caption = liczba;
}
//---------------------------------------------------------------------------

Nie sprawdzałem, bo aktualnie nie mam dostępu do Buildera, ale powinno działać.

0

Niestety nie działa.

Po kompilacji wyświetla mi się następujący komunikat:
[C++ Error] Unit1.cpp(23): E2451 Undefined symbol 'liczba';
Po zadeklarowaniu zmiennej liczba w Unit1.cpp lub w Unit1.h pod public:
Debugger wyświetla taką informacje:

Project Project1.exe raised exception class EStackOverflow with message 'stack overflow'. 
Process Stoped. Use Step or Run to continue.
0

Bo @Mr.YaHooo (pewnie pisał z palca) i zapomniał dodać int liczba do Unit1.h tak samo jak do Unit2.h

0
blackpab napisał(a):

Niestety nie działa.

Po kompilacji wyświetla mi się następujący komunikat:
[C++ Error] Unit1.cpp(23): E2451 Undefined symbol 'liczba';
Po zadeklarowaniu zmiennej liczba w Unit1.cpp lub w Unit1.h pod public:
Debugger wyświetla taką informacje:

Project Project1.exe raised exception class EStackOverflow with message 'stack overflow'. 
Process Stoped. Use Step or Run to continue.

Przeciez napisalem, ze zadeklarowalem te liczby, a w Unit2.h byly juz zdeklarowane. Teraz występuje następny błąd:

Project Project1.exe raised exception class EStackOverflow with message 'stack overflow'. 
Process Stoped. Use Step or Run to continue.
0

Pokaż kod lub zgłoś się do wróżbitów.

0
_13th_Dragon napisał(a):

Bo @Mr.YaHooo (pewnie pisał z palca) i zapomniał dodać int liczba do Unit1.h tak samo jak do Unit2.h
W Unit1.h tak naprawdę chciałem to zadeklarować nie jako zmienną w klasie TForm1, ale w metodzie TForm1::PrzyciskClick() Jeśli to ma tylko losować i przekazywać zmienną do innego okna nie ma co zaśmiecać klasy zmiennymi.

Co do błędu kolegi to raczej wina nie jest w tym kodzie. Tak jak piszesz, niech poda cały kod się zobaczy. Bo mam wrażenie, że to już powstaje zupełnie gdzieś indziej.

0

Oto mój kod:

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
        TButton *Przycisk;
        void __fastcall PrzyciskClick(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit2.h

//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:    // IDE-managed Components
        TLabel *Label1;
        void __fastcall FormCreate(TObject *Sender);
private:    // User declarations
  int liczba;
public:        // User declarations
        __fastcall TForm2(TComponent* Owner, int _liczba);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif

Unit1.cpp

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include <time.h>
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        //Konstruktor Form1
        srand(time(NULL));
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::PrzyciskClick(TObject *Sender)
{
    int liczba;
    liczba = rand()%3+1;
 
    Form2 = new TForm2(this,liczba);
    Form2->ShowModal();
    delete Form2;
    Form2 = NULL;
}
//---------------------------------------------------------------------------

Unit2.cpp

//---------------------------------------------------------------------------
#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, int _liczba)
        : TForm(Owner)
{
        //Konstruktor Form2
    this->liczba = _liczba;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm2::FormCreate(TObject *Sender)
{
   Label1->Caption = liczba;
}
//---------------------------------------------------------------------------
0

Tak na pierwszy rzut oka nic nie widzę. Nie napisałem tego wprost, ale przy tworzeniu formatek ręcznie, trzeba w ustawieniach projektu na zakładce Forms usunąć z sekcji Auto-create forms Form2.

0

Przeniosłem Form2 z: Auto-create forms do Available forms. Tak jak mowiles. Program uruchamia sie, wyswietla sie okno Form1. Jednak, gdy klikam na buttona "Przycisk" wyswietla mi sie ten sam blad co wczesniej. Program przestaje działać.

Błąd:

Project Project1.exe raised exception class EStackOverflow with message 'stack overflow'. 
Process Stoped. Use Step or Run to continue.
0

Zrobiłem wszystko tak samo jak Ty i u mnie nic takiego się nie dzieje. Tworzę nowy projekt VLC Application, następnie dodaję nową formatkę kładę button na Form1, label na Form2 i uzupełniam i działa bez problemów. Ten błąd EStackOverflow może być spowodowany tym, że gdzieś coś wywołuje się w kółko. Użyj debuggera i prześledź co się dzieje w funkcji PrzyciskClick i będzie jasne co jest nie tak.

2

Ja wolę nadpisywać ShowModal - wtedy masz możliwość nawet coś zwrócić.

Unit1.h

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <time.h>
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
   srand(time(NULL));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PrzyciskClick(TObject *Sender)
{
   TForm2 *Form2 = new TForm2(Application);
   try
   {
      Form2->ShowModal(rand()%3+1);
   }
   __finally
   {
      delete Form2;
   }
}
//---------------------------------------------------------------------------

Unit1.cpp

//---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
   TButton *Przycisk;
   void __fastcall PrzyciskClick(TObject *Sender);
private:    // User declarations
public:        // User declarations
   __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit2.h

//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:    // IDE-managed Components
   TLabel *Label1;
private:    // User declarations
   int liczba;
public:        // User declarations
   __fastcall TForm2(TComponent* Owner);
   int __fastcall ShowModal(int _liczba);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif

Unit2.cpp

//---------------------------------------------------------------------------
#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)
{
}
//---------------------------------------------------------------------------
int __fastcall TForm2::ShowModal(int _liczba)
{
   liczba=_liczba;
   Label1->Caption = liczba;
   return TForm::ShowModal();
}
1

Odpowiem w nowym poście, bo to ważna sprawa jeśli kolega kompiluje na 6-tce. Faktycznie 6-tka ma błąd który powoduje, ze jeśli doda się do konstruktora TForm parametr int, to właśnie wywołuje błąd EStackOverflow. http://stackoverflow.com/questions/9772862/mysterious-stack-overflow-in-constructor

Można to rozwiązać najprościej poprzez zamianę kolejności parametrów konstruktora z:

__fastcall TForm2::TForm2(TComponent* Owner, int _liczba)

na

__fastcall TForm2::TForm2(int _liczba, TComponent* Owner)

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