| View previous topic :: View next topic |
| Author |
Message |
Jan Guest
|
Posted: Fri Apr 21, 2006 11:03 am Post subject: Receive data between MDI child forms |
|
|
Hello,
All the forms in my application are fsMDIChild.
Now the problem I have is to receive data from another form.
In form 1 I call Form 2 like this: FormRelatie = new
TFormRelatie(Application);
In this second form, the user do a search in a database and select a
record. When the user clicks on OK I need to receive in Form1 of the
user clicks OK or Cancel and also what he have selected.
How can I share data between this forms ?
Thanks,
Jan |
|
| Back to top |
|
 |
Jan Guest
|
Posted: Fri Apr 21, 2006 11:03 am Post subject: Re: Receive data between MDI child forms |
|
|
| Quote: | There are many ways. Please confirm first that you do not
use a modal form for the query.
Hans.
|
Hans,
The main form is fsMDIForm and all the others are fsMDIChild.
From the main menu on the main form I call Form1.
So Form1 is fsMDIChild and calls FormRelatie for a query (when the user
want to do a search), FormRelatie is also fsMDIChild.
Jan |
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Fri Apr 21, 2006 11:03 am Post subject: Re: Receive data between MDI child forms |
|
|
Jan wrote:
| Quote: | All the forms in my application are fsMDIChild.
|
Your mainform will be a fsMDIForm I think.
| Quote: | Now the problem I have is to receive data from another form.
In form 1 I call Form 2 like this: FormRelatie = new
TFormRelatie(Application);
|
Hehh.. You mean: In form1 you created FormRelatie like this: FormRelatie = new
TFormRelatie(Application);
What is form 1 ? The mainform or a child ?
| Quote: | In this second form, the user do a search in a database and select a
record. When the user clicks on OK I need to receive in Form1 of the
user clicks OK or Cancel and also what he have selected.
|
Is it correct that RelatieForm is non-modal ?
| Quote: | How can I share data between this forms ?
|
There are many ways. Please confirm first that you do not
use a modal form for the query.
Hans. |
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Fri Apr 21, 2006 11:03 am Post subject: Re: Receive data between MDI child forms |
|
|
Jan wrote:
| Quote: | The main form is fsMDIForm and all the others are fsMDIChild.
|
Ok.
| Quote: | From the main menu on the main form I call Form1.
|
What do you consider 'calling a form' ? Create it ? Show it ?
| Quote: | So Form1 is fsMDIChild and calls FormRelatie for a query (when the user
want to do a search), FormRelatie is also fsMDIChild.
|
Can you show in code how the child calls FormRelatie ? (We know
already how RelatieForm is created.) But we also do not
know at which moment that is done. Also we do not
know what happens with FormRelatie when the user clicks the
OK-button. Does it Close() ? If so, is FormRelatie deleted then ?
Hans. |
|
| Back to top |
|
 |
Jan Guest
|
Posted: Fri Apr 21, 2006 12:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
Hans,
What I mean calling the form1 is: Form1 = new TForm1(Application);
and the form becomes visible, on form1 under the search button I have:
FormRelatie = new TFormRelatie(Application);
and on FormRelatie under the OK button I set the public propertys
lOK = true;
iID = Query->FieldByName("ID")->AsInteger;
Close();
In the close event of TFormRelatie:
Action = caFree;
In Form1 I want to read out the properties lOK and iID;
I think this is not the good way to work with MDI forms ?
Jan |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Apr 21, 2006 12:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
"Jan" <jan (AT) jlcsoft (DOT) com> wrote:
| Quote: |
[...] When the user clicks on OK I need to receive in Form1
of the user clicks OK or Cancel and also what he have
selected. How can I share data between this forms ?
|
There are many different ways to accomplish this. The problem
for me is that you haven't provided enough information about
your design. From my perspective, communication between child
forms can be problematic - especially mdiChild forms because
those forms are typically deleted when closed and frequently
multiple instances of the same form are permitted.
I would suggest using the win32 API PostMessage to send the
main form a custom message to let it know that the user has
done something in the other mdiChild (note that you can use
the WParam and LParam to indicate a whole bunch of things).
When the main form get's the message, the main form can
allocate the second mdiChild (if needed) or restore it
(if it's been minimized) and then pass in any information
that it needs.
~ JD |
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Fri Apr 21, 2006 12:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
Jan wrote:
| Quote: | What I mean calling the form1 is: Form1 = new TForm1(Application);
|
As already said: that is creating a form.
| Quote: | and on FormRelatie under the OK button I set the public propertys
lOK = true;
iID = Query->FieldByName("ID")->AsInteger;
Close();
In the close event of TFormRelatie:
Action = caFree;
In Form1 I want to read out the properties lOK and iID;
|
In this way that is impossible. I suppose you want to read them out
after FormRelatie closed. But it is deleted then too.
Otherwise you could place in Form1 code like:
if ( FormRelatie->lOK )
{
//FormRlatie->iID
}
Didnot you try such code already ?
If you did not use Action = caFree; then it would work.
Now what is left is 'when will Form1 execute that code?'.
How does form1 know that FormRelatie has closed ?
So a solution would be: Place a TTimer on Form1. Enabled false.
In the timereventhandler place code like
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Timer1->Enabled = false;
lOK = FormRelatie->lOK; //FormRelatie is private
iID = FormRelatie->iID;
delete FormRelatie;
if ( lOK )
{
//
}
}
#include "Unit1.h" // Form1 declarations
void __fastcall TFormRelatie::OKButtonClick(TObject *Sender)
{
lOK = true;
iID = Query->FieldByName("ID")->AsInteger;
Close();
}
void __fastcall TFormRelatie::FormClose(TObject *Sender,
TCloseAction &Action)
{
// remove Action = caFree;
Form1->Timer1->Enabled = true;
}
| Quote: | I think this is not the good way to work with MDI forms ?
|
It was much easier when FormRelatie was not fsMDIChild and
you used ShowModal() for it.
Hans. |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Apr 21, 2006 1:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
Hans Galema <notused (AT) notused (DOT) nl> wrote:
| Quote: |
[...] Place a TTimer on Form1.
|
Oh Yuck. Just use SendMessage in OnClose (instead of
PostMessage) and the OnClose will wait until SendMessage
returns. This will keep the form and all of it's members
valid long enough for the message handler to get what it
needs.
~ JD |
|
| Back to top |
|
 |
Jan Guest
|
Posted: Fri Apr 21, 2006 1:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
JD wrote:
| Quote: |
Hans Galema <notused (AT) notused (DOT) nl> wrote:
[...] Place a TTimer on Form1.
Oh Yuck. Just use SendMessage in OnClose (instead of
PostMessage) and the OnClose will wait until SendMessage
returns. This will keep the form and all of it's members
valid long enough for the message handler to get what it
needs.
~ JD
|
JD,
Thanks, I give this a try.
Also, Hans, thanks for the info.
Jan
-- |
|
| Back to top |
|
 |
Jan Guest
|
Posted: Fri Apr 21, 2006 2:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
JD wrote:
| Quote: |
Hans Galema <notused (AT) notused (DOT) nl> wrote:
[...] Place a TTimer on Form1.
Oh Yuck. Just use SendMessage in OnClose (instead of
PostMessage) and the OnClose will wait until SendMessage
returns. This will keep the form and all of it's members
valid long enough for the message handler to get what it
needs.
~ JD
|
JD,
Thanks, I give this a try.
Also, Hans, thanks for the info.
Jan
-- |
|
| Back to top |
|
 |
Hans Galema Guest
|
Posted: Fri Apr 21, 2006 3:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
JD wrote:
Unfamilliar with this expression I'm wondering if that was
accompnied with a slash on my forehead or on your own.
:-) Hans. |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Apr 21, 2006 4:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
Hans Galema <notused (AT) notused (DOT) nl> wrote:
| Quote: |
Oh Yuck.
Unfamilliar with this expression
|
It's some what like opening an expensive bottle of red that
got a little too warm at some point. It's just not what you've
come to expect [Yuck] but if you've never had it before, you'll
most likely enjoy it anyway. ;-)
| Quote: | I'm wondering if that was accompnied with a slash on my
forehead or on your own.
|
Certainly not mine <g>.
~ JD |
|
| Back to top |
|
 |
Jan Guest
|
Posted: Mon Apr 24, 2006 11:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
I have made a little testprogram and this works fine.
The main form (TForm1 is fsMDIform) and Form2 is fsMDIChild.
Here is the code.
Greetings,
Jan
FORM1.H
#include "Unit2.h"
#define TEST_MESSAGE (WM_APP + 400)
//----------------------------------------------------------------------
-----
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
TForm2 *Form2;
protected:
void __fastcall ReadMessage( TMessage & Message ) ;
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER ( TEST_MESSAGE , TMessage , LeesMessage )
END_MESSAGE_MAP ( TForm )
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//----------------------------------------------------------------------
-----
extern PACKAGE TForm1 *Form1;
//----------------------------------------------------------------------
-----
FORM1.CPP
TForm1 *Form1;
//----------------------------------------------------------------------
-----
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//----------------------------------------------------------------------
-----
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2 = new TForm2(this);
}
//----------------------------------------------------------------------
-----
void __fastcall TForm1::ReadMessage( TMessage & Message )
{
bool lOk;
int iRet = -1;
lOk = Form2->lOk;
iRet = Form2->iRet;
MessageDlg("Receive notification", mtInformation, TMsgDlgButtons()
<< mbOK, 0);
}
//----------------------------------------------------------------------
----
FORM2.H
//----------------------------------------------------------------------
-----
class TForm2 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
public: // User declarations
bool lOk;
int iRet;
__fastcall TForm2(TComponent* Owner);
};
//----------------------------------------------------------------------
-----
extern PACKAGE TForm2 *Form2;
//----------------------------------------------------------------------
-----
FORM2.CPP
TForm2 *Form2;
//----------------------------------------------------------------------
-----
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
lOk = false;
iRet = 0;
}
//----------------------------------------------------------------------
-----
void __fastcall TForm2::ButtonCloseClick(TObject *Sender)
{
lOk = true; //-- just for test
iRet = 99; //-- just for test
Close();
}
//----------------------------------------------------------------------
-----
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
TForm *oF = dynamic_cast<TForm*>(Owner);
SendMessage(oF->Handle,TEST_MESSAGE,0,0);
Action = caFree;
} |
|
| Back to top |
|
 |
JD Guest
|
Posted: Tue Apr 25, 2006 1:03 pm Post subject: Re: Receive data between MDI child forms |
|
|
"Jan" <jan (AT) jlcsoft (DOT) com> wrote:
| Quote: |
[...]
VCL_MESSAGE_HANDLER ( TEST_MESSAGE , TMessage , LeesMessage )
|
<cough> You missed something in the translation ;-)
You also don't have it declared correctly:
private:
MESSAGE void __fastcall ReadMessage( TMessage & Message ) ;
public:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER( TEST_MESSAGE, TMessage, ReadMessage )
END_MESSAGE_MAP( TForm )
| Quote: | void __fastcall TForm1::ReadMessage( TMessage & Message )
|
Then just preface that:
MESSAGE void __fastcall TForm1::ReadMessage(...)
| Quote: | void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
TForm *oF = dynamic_cast<TForm*>(Owner);
SendMessage(oF->Handle,TEST_MESSAGE,0,0);
|
You can eliminate the #include and the casting if you send the
message to Application->MainForm->Handle instead.
~ JD |
|
| Back to top |
|
 |
|