 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
David Guest
|
Posted: Fri Jun 23, 2006 5:05 am Post subject: TMemo parent problem |
|
|
Hi,
I am having yet another problem with Borland Builder. Web searches on an
answer are not bringing much joy.
I have a normal Borland form that contains a TPanel (named Panel) and the
constuctor coded thus:
__fastcall TMyForm::TMyForm(TComponent* Owner)
: TForm(Owner)
{
mem =new TMemo(Panel);
mem->Parent=Panel;
mem->Lines->Strings[0]="testing";
// /*MyClass2* */ myClass2 = new MyClass2(this);
}
This works fine. The word "testing" shows as you would expect it to. Next I
have a class that inherits from TPanel and called from the constuctor of the
previous class previous with the following consturctor:
__fastcall MyClass2::MyClass2(TComponent* Owner) : TPanel(Owner)
{
TMemo* mem =new TMemo(this);
mem->Parent=this;
mem->Lines->Strings[0]="testing";
delete mem;
}
But here I get an error ...EInvalidOperation with message 'Control '' has no
parent window'... at the point of "mem->Lines->Strings[0]="testing";"
when the code is run. The code compiles without any problems.
I have tried various things such as use TForm* in place of TComponent* in
the constructor definition and used Owner in place of 'this' when creating
'mem'. I get the same error every time. I have come to the conclusion that
an instance of TMemo cannot be created in any class that itself is not
derived from TForm. Is this a correct assumption, or am I simply missing the
point somewhere. |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Fri Jun 23, 2006 5:09 am Post subject: Re: TMemo parent problem |
|
|
"David" <dbai7864 (AT) bigpond (DOT) net.au> wrote in message
news:449b2c9e$1 (AT) newsgroups (DOT) borland.com...
| Quote: | mem =new TMemo(Panel);
mem->Parent=Panel;
mem->Lines->Strings[0]="testing";
|
Your memo is Empty when you create it. You can't access strings that do not
exist. To add new strings to it, use the Add() method instead, ie:
mem->Lines->Add("testing");
Or use the Text property:
mem->Text = "testing";
| Quote: | Next I have a class that inherits from TPanel and called from
the constuctor of the previous class previous with the following
consturctor: |
| Quote: | But here I get an error ...EInvalidOperation with message 'Control ''
has no parent window'.
|
The error is self-explanatory. You tried to do something that required a
Parent window be present, but there was no Parent available. In this case,
the TMyClass constructor is trying to access the Memo before the myClass2
instance's Parent property had been set. You need to set the Parent for a
child component before it can do anything that requires a valid Handle,
since the Parent is needed to initialize the Handle properly.
| Quote: | I have come to the conclusion that an instance of TMemo cannot
be created in any class that itself is not derived from TForm.
|
Yes, it can. You are simply trying to access the contents of the Memo too
early. In order for the Memo's Handle to be created, the Memo has to have a
Parent, and the Parent has to already have a Parent, and so on until the
top-level TForm is reached, since a TForm does not (usually) have a Parent
of its own.
Gambit |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Jun 23, 2006 5:19 am Post subject: Re: TMemo parent problem |
|
|
"David" <dbai7864 (AT) bigpond (DOT) net.au> wrote:
| Quote: |
[...] I have come to the conclusion that an instance of
TMemo cannot be created in any class that itself is not
derived from TForm.
|
Just let MyClass finish construction before you assign the
Lines. This can be accomplished by posting a custom message
in it's ctor and by overriding it's WndProc method to
intercept the message. For example:
#define UWM_INITIALIZE (WM_USER + 100)
//-------------------------------------------------------------
class MyClass2 : public TPanel
{
typedef inherited TPanel;
....
private:
TMemo* mem;
protected:
virtual void __fastcall WndProc( TMessage &Message );
....
}
//-------------------------------------------------------------
__fastcall MyClass2::MyClass2(TComponent* Owner) : TPanel(Owner)
{
mem =new TMemo(this);
mem->Parent=this;
::PostMessage( Handle, UWM_INITIALIZE, 0, 0 );
}
//-------------------------------------------------------------
void __fastcall MyClass2::WndProc( TMessage &Message )
{
if( Message.Msg == UWM_INITIALIZE )
{
mem->Lines->Strings[0]="testing";
}
inherited::WndProc( Message );
}
//-------------------------------------------------------------
Note that I did not delete the TMemo. That's because it was
assigned an Owner and the rules are that when an object is
destroyed, all of the objects that it ownes are also destroyed.
~ JD |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Jun 23, 2006 5:21 am Post subject: Re: TMemo parent problem |
|
|
"Remy Lebeau \(TeamB\)" <no.spam (AT) no (DOT) spam.com> wrote:
| Quote: |
mem->Lines->Strings[0]="testing";
Your memo is Empty when you create it. You can't access strings that do not
exist.
|
Good catch ... missed that one.
~ JD |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Fri Jun 23, 2006 5:26 am Post subject: Re: TMemo parent problem |
|
|
"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:449b33ac$1 (AT) newsgroups (DOT) borland.com...
| Quote: | Just let MyClass finish construction before you assign the
Lines. This can be accomplished by posting a custom
message in it's ctor and by overriding it's WndProc method
to intercept the message.
|
That won't work. Posting a message requires a valid Handle to post to. A
Parent is needed in order to create that Handle. Which is exactly why
David's code is failing in the first place - accessing the Lines requires a
valid Handle, which cannot be created in the constructor because no Parent
has been assigned yet. Which is why your code will also fail - your
MyClass2 instance does not have a Parent assigned yet when you try to access
its Handle in the constructor.
Gambit |
|
| Back to top |
|
 |
David Bailey Guest
|
Posted: Fri Jun 23, 2006 7:10 am Post subject: Thankyou |
|
|
Thankyou, thankyou, thankyou, thankyou, thankyou, thankyou, thankyou...
Thankyou to you both. I needed to set the Parent's Parent. Just need to go
though the code and do some clean up, but initial tests showed that it'll
work
Regards,
David |
|
| Back to top |
|
 |
JD Guest
|
Posted: Fri Jun 23, 2006 1:12 pm Post subject: Re: TMemo parent problem |
|
|
"Remy Lebeau \(TeamB\)" <no.spam (AT) no (DOT) spam.com> wrote:
| Quote: |
That won't work. [...]
|
It does.
~ JD |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Fri Jun 23, 2006 3:25 pm Post subject: Re: TMemo parent problem |
|
|
"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:449ba25b$1 (AT) newsgroups (DOT) borland.com...
As I explained earlier, the Handle property is not valid inside the
constructor without a Parent being assigned first. TWinControl::CreateWnd()
throws an exception if a Parent is not assigned yet - which is exactly what
was happening in David's code. The *only* possibility of the Handle being
valid in the constructor is if the class is instantiated by the DFM
streaming, in which case the Owner is used as the Parent window in
CreateWnd(). If the class is not created during DFM streaming, then the
Parent is required.
Gambit |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|