CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - [BCB] C++ Formularze tworzone dynamicznie

[BCB] C++ Formularze tworzone dynamicznie

dział ogólny

[BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Darek_C++ » czwartek, 14 czerwca 2012, 11:39

Witam ponownie,
napotkałem problem z formularzami:

W głównym oknie programu wywołuje formularz/okno tworzone dynamicznie {jest przeniesione w Projekty/formularze / Available forms}

KOD cpp:     UKRYJ  
void __fastcall TForm1::Listadodanychserwisw1Click(TObject *Sender)
{
    // Lista dodanych serwisów
    TForm3 *Form3 = new TForm3(this);
    Form3->ShowModal();
}

Otwiera się formularz/ okno Form3 w której jest komponent TListViev zawierający jakieś dane powiedzmy definiowania projektu.
Z poziomu tego okna wywołuję kolejny formularz/okno
KOD cpp:     UKRYJ  
void __fastcall TForm3::Zdefiniowaneprojkety1Click(TObject *Sender)
{
    // Zdefiniowane projkety
    TForm5 *Form5 = new TForm5(this);
    Form5->Caption="Otwarte z TForm3";
    Form5->ShowModal();
}

Otwiera się kolejne okno z projektami i problem jest taki, że jak chce wywołać akcję np:
Dodam, że Form5 zawiera #include "Unit3ListaDodanychSerwisow.h" czyli Form3
KOD cpp:     UKRYJ  
void __fastcall TForm5::Button1Click(TObject *Sender)
{
    // Wyczysc dane w ListView1
    Form3->ListView1->Clear();
    /* Dalsze akcje wstawiające do Form3->ListView1 */
}

I pojawia się wyjątek: " Exception class EAccessViolation with message 'Access violation"

Pytanie brzmi jak zrealizować, odwołać się do komponentów VCL z Form3 z poziomu Form5
----
Te odstępy między kodem a tekstem "zrobiło forum" - nie idzie ich wydytować :(
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Cyfrowy Baron » czwartek, 14 czerwca 2012, 12:02

Jeżeli tworzysz jakiś formularz w zdarzeniu lub funkcji to poza tym zdarzeniem lub funkcją ten formularz nie będzie dostępny. Poza tym formularz tworzysz w oparciu o jakiś już istniejący formularz, np. w oparciu o Form3 przeniesiony na Available form, ale tworzysz nowe formularze w oparciu o ten z nową nazwą a nie nazwą jaka istnieje na Available form.
Przykład:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:
       TForm3 *MyForm;


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
void __fastcall TForm1::Listadodanychserwisw1Click(TObject *Sender)
{
   if(MyForm != NULL) delete MyForm;

   MyForm = new TForm3(this);
   MyForm->ShowModal();
}
//--------------------------------
void __fastcall TForm5::Button1Click(TObject *Sender)
{
    MyForm->ListView1->Clear(); /* teraz to zadziała */
}


Pamiętaj, że zanim utworzysz nowy obiekt o tej samej nazwie to stary trzeba najpierw zniszczyć, dlatego jest tam warunek if(MyFom !+ NULL).
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Darek_C++ » czwartek, 14 czerwca 2012, 12:14

W podanym wyżej przypadku formularz TForm3 tworzy i otwiera sam siebie, a nie TForm5 czyli kolejny . Jeśli zmieniee na
MyForm = new TForm5(this); to wywala bledy...
Jeśli w sekcji private formularza Form3 który ma tworzyc Form5
#include "Unit5ZapisaneProjekty.h"
private:
TForm5*MyForm;
i teraz wywołanie w Form3:
KOD cpp:     UKRYJ  
void __fastcall TForm3::Button7Click(TObject *Sender)
{
   if(MyForm != NULL) delete MyForm;
   MyForm = new TForm5(this);
   MyForm->ShowModal();
}
Otwiera się ten dodatkowy formularza Form5 o jaki chodzi, ale nie można w nim zrealizować wywołania MyForm->ListView1->Clear();
Poza tym MyForm->ListView1->Clear(); /* teraz to zadziała */
Tyczy nie tego formularz na którym na być akcja ListView1->Clear() :(

------
Więc Cyfrowy Baronie nie wiem nadal jak sobie z tym poradzić :(
Ostatnio edytowano czwartek, 14 czerwca 2012, 14:56 przez Darek_C++, łącznie edytowano 1 raz
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez polymorphism » czwartek, 14 czerwca 2012, 14:53

KOD cpp:     UKRYJ  
void __fastcall TForm1::Listadodanychserwisw1Click(...)
{
    ...
    TForm3 *Form3 = new TForm3(this); //przypisujesz nowy obiekt lokalnemu wskaźnikowi
    ...
}

...

void __fastcall TForm5::Button1Click(...)
{
    ...
    Form3->ListView1->... // odwołujesz się do globalnego wskaźnika Form3, zdefiniowanego zapewne tam, gdzie klasa TForm3
    ...
}

Rozwiązanie jest banalnie proste (trochę dziwne, że masz z tym problem): w klasie TForm5 stwórz pole Form3 (choć jakaś lepsza nazwa by się przydała), które odpowiednio ustawiasz przy tworzeniu obiektu tejże klasy.

p.s. co, już z serwerem odpuściłeś? :)
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Darek_C++ » czwartek, 14 czerwca 2012, 15:05

polymorphism napisał(a):Rozwiązanie jest banalnie proste
Chyba się coś nie rozumiemy
W formularzu oknie Form3 jest kod który "otwiera" Form5
Kod: Zaznacz cały
void __fastcall TForm3::Button8Click(TObject *Sender)
{
   TForm5 *Form5 = new TForm5(this); //przypisujesz nowy obiekt lokalnemu wskaźnikowi
   Form5->ShowModal();
}
i z tego Form5 chce się odwołać do Form3 z której to wywołałem Form5, więc tak jak Piszesz nie na żadnego odwołania z poziomu utworzonego okna Form5 do Form3 które to oko wywołało.

Dodam, że Form3 też jest tworzony dynamicznie i wywoływany z okna głównego programu .

Co do serwera zrealizuje go w oparciu o JAVA i http://www.jboss.org/netty Netty is a NIO client server framework. W sadzie już kody testowe zrobiłem, ale z uwagi na ten programik co pisze teraz musiałem zrobić przerwę .
Ostatnio edytowano czwartek, 14 czerwca 2012, 16:03 przez Darek_C++, łącznie edytowano 1 raz
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Darek_C++ » czwartek, 14 czerwca 2012, 15:33

W za załączeniu jest projekt demo tego co chciał bym osiągnąć :)
Załącznik ma za duży rozmiar. Maksymalny rozmiar pliku to 2 MB.
Liczba ta zapisana jest w pliku php.ini i nie może zostać zmieniona.

Zamieściłem do pobrania z http://www7.zippyshare.com/v/777161/file.html po kliknięcu w prawy button [DOWNLOAD NOW]
------------
Rozwiązałem kwestię Dla formularza głównego w Unit1.h
Kod: Zaznacz cały
public:      // User declarations
   __fastcall TForm1(TComponent* Owner);
   TForm3 *MyForm; //
};

Wywołanie Formularza 3
Kod: Zaznacz cały
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   if(MyForm != NULL) delete MyForm;
   MyForm = new TForm3(this);
   MyForm->ShowModal();
}
i teraz w Form5 które jest wywoływane w Form3 za pomocą kodu:
Kod: Zaznacz cały
void __fastcall TForm3::Button1Click(TObject *Sender)
{
   TForm5 *Form5 = new TForm5(this);
   Form5->ShowModal();
}

Mogę się odwołać do Form3 kodem:
Kod: Zaznacz cały
void __fastcall TForm5::Button2Click(TObject *Sender)
{
  Form1->MyForm->Edit1->Text = "Inny Tekst";
}

---
ALe nadal jest LIPA, bo jak pozamykam te dodatkowe okienka to już drugi raz nie mogę wywołać z poziomu ogna głównego Form1 :( bo wywala błąd

Więc mój parobem pozostaje nierozwiązany :( ...
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez polymorphism » czwartek, 14 czerwca 2012, 17:48

(...) i z tego Form5 chce się odwołać do Form3 z której to wywołałem Form5

No to chyba Ty mnie nie zrozumiałeś. Przecież jak zrobisz pole-wskaźnik, który wskazuje na obiekt klasy TForm3, to będziesz mógł się odwoływać do instancji, która jest właścicielem obiektu klasy TForm5:
KOD cpp:     UKRYJ  
void __fastcall TForm3::Button8Click(TObject *Sender)
{
    TForm5 *Form5 = new TForm5(this);
    Form5->Form3 = this; //<--- tu!!!
    Form5->ShowModal();
}


p.s. dla jasności, kod, który wcześniej podałem, miał Ci tylko pokazać błąd, który robisz. To nie było rozwiązanie.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Darek_C++
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Darek_C++ » czwartek, 14 czerwca 2012, 18:03

Wiec jeśli w sekcji Form5 utworze wskaźnik:
Kod: Zaznacz cały
public:      // User declarations
   __fastcall TForm5(TComponent* Owner);
   TForm *Form3;
};
Następnie wywołują tak jak Piszesz:

Kod: Zaznacz cały
void __fastcall TForm3::Button1Click(TObject *Sender)
{
   TForm5 *Form5 = new TForm5(this);
   Form5->Form3 = this;
   Form5->ShowModal();
}

W formularzu Form5 w którym mam się odwołać do Form3 nie można tego zrobić:
Kod: Zaznacz cały
void __fastcall TForm5::Button1Click(TObject *Sender)
{
   Form3->Edit1->Text = "inny tekst";
}


[C++ Error] Unit5Formularz3.cpp(25): E2316 'Edit1' is not a member of 'TForm'


---
Tworzyłem zły wskaźnik musi być:
Kod: Zaznacz cały
#include "Unit3Formularz2.h"
//
public:      // User declarations
   __fastcall TForm5(TComponent* Owner);
   //TForm *Form3;
   TForm3 *Form3;
};
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Cyfrowy Baron » piątek, 15 czerwca 2012, 23:12

Nierozwiązany zostaje problem niszczenia formularza po użyciu. Tworzysz nowe okno w zdarzeniu, więc poza tym zdarzeniem nie ma już dostępu do tego okna. Po zamknięciu okno utworzone dynamicznie nie jest niszczone, lecz tylko zamykane i wciąż rezyduje w pamięci. Warunek if(MyForm != NULL) delete MyForm; niszczy co prawda okno, ale dopiero wtedy, gdy jest tworzone nowe. Po użyciu okno jest niepotrzebne, więc powinieneś je zniszczyć. Ponieważ wywołujesz okno modalne to po funkcji ShowModal możesz dodać funkcję delete niszczącą okno:

KOD cpp:     UKRYJ  
void __fastcall TForm3::Button1Click(TObject *Sender)
{
   TForm5 *Form5 = new TForm5(this);
   Form5->Form3 = this;

   Form5->ShowModal();

  delete Form5;
}
Okno zostanie zniszczone zaraz po zamknięciu.
Jednakże w przypadku okien tworzonych dynamicznie lepiej jest zwolnić pamięć w zdarzeniu OnClose dla tego okna, w ten sposób nie musisz się martwić o to czy nie zapomniałeś gdzieś w kodzie zniszczyć okna, gdyż okno samo po sobie posprząta:

KOD cpp:     UKRYJ  
void __fastcall TForm5::FormClose(TObject *Sender, TCloseAction &Action)
{
  Action = caFree;
}


Tutaj jednak uwaga: w tym przypadku nie jest wysyłana wartość NULL do okna właściciela (Owner), dlatego można spróbować tak:

KOD cpp:     UKRYJ  
void __fastcall TForm5::FormClose(TObject *Sender, TCloseAction &Action)
{
  Action = caFree;
  this = NULL;
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez polymorphism » sobota, 16 czerwca 2012, 11:25

(...) dlatego można spróbować tak:

Nie można. this to nie jest zmienna, to wartość stała w ramach instancji klasy. Nawet jak by to była zmienna, to i tak nie zadziałałoby to w taki sposób, jaki oczekujesz. No i najważniejsze: po co zerować lokalny wskaźnik, jeśli z tego nic nie wynika?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB] C++ Formularze tworzone dynamicznie

Nowy postprzez Cyfrowy Baron » sobota, 16 czerwca 2012, 12:07

polymorphism napisał(a):Nie można. this to nie jest zmienna,


Fakt! Testowałem Form5 = NULL;

polymorphism napisał(a):po co zerować lokalny wskaźnik, jeśli z tego nic nie wynika?


Na wypadek gdyby było potrzeba sprawdzić, czy formularz istnieje w pamięci.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 6 gości