CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Okno MDIChild i Action = caFree - Abnormal program terminati
Strona 1 z 1

Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: środa, 6 marca 2013, 18:47
przez event15
WItam.

Oto ja oraz kolejny problem.

W sumie znam rozwiązanie, jednak nie rozumiem czemu ono skutkuje.
Mianowicie stworzyłem książkowa aplikację MDI.

Plik Unit1.cpp
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "MDIChild.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonClick(TObject *Sender)
{
        TChild* child = new TChild(this);
        child->Parent = this;
        child->Width = 100;
        child->Height = 200;
        child->Show();
}
//---------------------------------------------------------------------------


Plik MDIChild.cpp
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "MDIChild.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TChild *Child;
//---------------------------------------------------------------------------
__fastcall TChild::TChild(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TChild::FormClose(TObject *Sender, TCloseAction &Action)
{
        Action = caFree;       
}
//---------------------------------------------------------------------------


Skompilowanie kodu nie przynosi problemów.

Problem przychodzi w chwili, gdy muszę zamknąć okienko MDI Child. Na jednym komputerze wywala mi błąd "Abnormal program terminated" na innym komputerze mam błąd: "Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00000000. Read of address 00000000'. Process stopped. Use Step or Run to continue. "

Kolega, który miał również problem z tym powiedział, że znalazł rozwiązanie. Mianowicie usunięcie linii: "child->Parent = this;"

Jednak nurtuje mnie ten problem. Skoro książka do C++Buildera 6 Personal podaje ten program jako przykład, to powinien on działać bezbłędnie.
Nie rozumiem, czemu usunięcie tej linijki sprawia poprawne działanie aplikacji.

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: czwartek, 7 marca 2013, 00:28
przez Cyfrowy Baron
event15 napisał(a):
KOD cpp:     UKRYJ  
void __fastcall TForm1::ButtonClick(TObject *Sender)
{
        TChild* child = new TChild(this)
;


Problem w tym, że tworzysz nowe okno dynamicznie w zdarzeniu, zarówno deklaracja jak i definicja znajdują się w tym zdarzeniu i poza zdarzeniem nie ma do nich dostępu.

Zastanów się: co się stanie gdy utworzysz zmienną w jakimś zdarzeniu, np w OnClick dla Button1:

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 int x = 0;
}


Czy będziesz miał dostęp do tej zmiennej np. w zdarzeniu OnClick dla innego przycisku Button2? Jeżeli nie znasz odpowiedzi to sprawdź!

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: piątek, 8 marca 2013, 00:55
przez event15
Dobrze, już rozumiem czemu tak się dzieje. A w jaki sposób powinno się poprawnie to zadeklarować i inicjalizować, by to miało ręce i nogi?

Już siedzę x godz. nad tym i nie potrafię wymyślić poprawnego miejsca w kodzie i poprawnej "formuły".
Trochę mnie to dziwi, bo na nowszych wersjach Buildera kod działa bez problemu, tylko tutaj nie chce.

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: piątek, 8 marca 2013, 09:35
przez Cyfrowy Baron
Tworzysz dwa formularze. Właściwość FormStyle formularza głównego (np. FormMDI) ustawiasz na fsMDIForm, dla formularza drugiego (np. FormChild) FormStyle ustawiasz na fsMDIChild. Wchodzisz w opcje projektu w sekcję Forms i okno FormChild przenosisz do sekcji Available Forms.
W pliku źródłowym w sekcji include dla obydwu okien włączasz plik nagłówkowy okna sąsiedniego, czyli np:

KOD cpp:     UKRYJ  
#include "UniteMDI.h" /* FormMDI */
#include "UniteChild.h" /* FormChild */


Okno Child przywołujesz w prosty sposób np. w zdarzeniu OnClick dla Button1 w formularzu FormMDI:

KOD cpp:     UKRYJ  
void __fastcall TFormMDI::Button1Click(TObject *Sender)
{
    FormChild = new TFormChild( this );
}


W zdarzeniu OnClose dla okna FormChild umieszczasz kod:

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


I to już wszystko.

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: piątek, 8 marca 2013, 16:46
przez event15
Zrobiłem tak, jak napisałeś. Jednak problem pojawia się w chwili, kiedy pojawia się wpis:

KOD cpp:     UKRYJ  
void __fastcall TFormMDI::Button1Click(TObject *Sender)
{
    FormChild = new TFormChild( this );
    FormChild->Parent = this; // tu pojawia się problem.
}
Wychodzi na to, że nie mogę ustawiać rodzica dla tak stworzonego okienka MDIChild?
Czy deklaracja rodzica jest konieczna?

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: piątek, 8 marca 2013, 17:29
przez Mironas
event15 napisał(a):Czy deklaracja rodzica jest konieczna?


Nie jest konieczna.
Ale dziwne jest że pojawia się błąd w tym miejscu.

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: sobota, 9 marca 2013, 08:54
przez Cyfrowy Baron
To jest aplikacja typu MDI-CHILD i tak to się robi. Nie musisz ustawiać rodzica, gdyż okno Child zawsze będzie przypisane do MDI i to Parent jest tutaj zupełnie nie na miejscu. Rodzicem dla Child zawsze jest MDI, a aplikacja może mieć tylko jedno okno typu MDI i musi to być okno główne.

event15 napisał(a):Zrobiłem tak, jak napisałeś. Jednak problem pojawia się w chwili, kiedy pojawia się wpis:


Wcale nie zrobiłeś tak jak ja napisałem! :evil:

Cyfrowy Baron napisał(a):
KOD cpp:     UKRYJ  
void __fastcall TFormMDI::Button1Click(TObject *Sender)
{
    FormChild = new TFormChild( this );
}


Pokaż mi, gdzie w moim kodzie jest to Parent? :o

Re: Okno MDIChild i Action = caFree - Abnormal program terminati

Nowy postNapisane: sobota, 9 marca 2013, 11:46
przez event15
Zrobiłem tak jak napisałeś. Chciałem sprawdzić tylko, czy w tym momencie "FormChild->Parent" będzie działać. Napisałem w poprzednim poście, że problem się pojawia kiedy wpisze się to.

Często korzystam z programów ćwiczebnych z archaicznej już książki C++Builder 3. W niej właśnie znalazłem przykład z tą aplikacją MDI i stąd wzięła się moja upartość w tym ustawianiu rodzica.