BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Storing TBitmap property properly...

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Development)
View previous topic :: View next topic  
Author Message
MKo
Guest





PostPosted: Tue Apr 12, 2005 10:19 am    Post subject: Storing TBitmap property properly... Reply with quote




Hi,

Could not find the solution for following:

I have created own package (class inherited from TGraphicControl)
which has published property of type TBitmap (with appropriate
setters and getters). When I insert the installed component to
form and built+run, editor says; "Invalid property path;
Glyph->Data" which is the reference to the set bitmap data in dfm
file. Same error occurs of I save the test project and try to
open it again. In shortly problem is that IDE cannot read the
property value for the bitmap. I just don't understand why and
what path is wrong, isn't the bitmap data read from the dfm file
where is it streamed ??
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Apr 12, 2005 5:18 pm    Post subject: Re: Storing TBitmap property properly... Reply with quote




"MKo" <mirko.kontro (AT) ge (DOT) com> wrote


Quote:
In shortly problem is that IDE cannot read the property value
for the bitmap. I just don't understand why and what path is
wrong, isn't the bitmap data read from the dfm file where is it
streamed ??

Please show your actual code. You are probably not managing the TBitmap
itself properly to begin with.


Gambit



Back to top
MKo
Guest





PostPosted: Wed Apr 13, 2005 5:18 am    Post subject: Re: Storing TBitmap property properly... Reply with quote




"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote:
Quote:

"MKo" <mirko.kontro (AT) ge (DOT) com> wrote in message
news:425b9284 (AT) newsgroups (DOT) borland.com...

In shortly problem is that IDE cannot read the property value
for the bitmap. I just don't understand why and what path is
wrong, isn't the bitmap data read from the dfm file where is it
streamed ??

Please show your actual code. You are probably not managing the TBitmap
itself properly to begin with.


Gambit



Here (removed the irrelevant parts);

=Header========================================================

#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>

class PACKAGE TExampleButton : public TGraphicControl
{
private:

Graphics::TBitmap *FGlyph;

void __fastcall SetGlyph(Graphics::TBitmap*);
void __fastcall CalcGlyphLayout(TRect &r);

protected:

void __fastcall Paint(void);

public:

__fastcall TExampleButton(TComponent* Owner);

__published:

__property Graphics::TBitmap* Glyph = {read=FGlyph, write=SetGlyph};
};

=Cpp==========================================================

#include <vcl.h>
#pragma hdrstop

#include "ExampleButton.h"
#pragma package(smart_init)

static inline void ValidCtrCheck(TExampleButton *)
{
new TExampleButton(NULL);
}

__fastcall TExampleButton::TExampleButton(TComponent* Owner)
: TGraphicControl(Owner)
{
SetBounds( 0, 0, 50, 50 );
}

namespace Examplebutton
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TExampleButton)};
RegisterComponents("Samples", classes, 0);
}
}

void __fastcall TExampleButton::SetGlyph(Graphics::TBitmap* Value)
{
if(Value == NULL)
{
return;
}

if(!FGlyph)
{
FGlyph = new Graphics::TBitmap;
}

FGlyph->Assign(Value);
Invalidate();
}

void __fastcall TExampleButton::Paint(void)
{
TRect cRect, tRect, gRect;
TColor TopColor, BottomColor;

Canvas->Brush->Color = clBtnFace;
Canvas->FillRect(ClientRect);
cRect = ClientRect;
Graphics::TBitmap *bit = new Graphics::TBitmap;
bit->Width = ClientWidth;
bit->Height = ClientHeight;
bit->Canvas->Brush->Color = clBtnFace;
bit->Canvas->FillRect(cRect);

if(FGlyph)
{
if(!FGlyph->Empty)
{
CalcGlyphLayout(gRect);
bit->Canvas->BrushCopy(gRect, FGlyph,
Rect(0,0,FGlyph->Width,FGlyph->Height), FGlyph->TransparentColor);
}
}

BitBlt(Canvas->Handle, 0, 0, ClientWidth, ClientHeight, bit->Canvas->Handle, 0, 0,
SRCCOPY);

delete bit;
}

void __fastcall TExampleButton::CalcGlyphLayout(TRect &r)
{

int TotalHeight=0;
int TextHeight=0;

if(!FCaption.IsEmpty())
TextHeight = Canvas->TextHeight(FCaption);

TotalHeight = FGlyph->Height + TextHeight + 5;

r = Rect((ClientWidth/2)-(FGlyph->Width/2),
((ClientHeight/2)-(TotalHeight/2)), FGlyph->Width +
(ClientWidth/2)-(FGlyph->Width/2), FGlyph->Height +
((ClientHeight/2)-(TotalHeight/2)));
}
===============================================================

Code is based on example from C++Builder6 Deve Guide. After installing and inserting above component to test form, it displays ok on form and property value shows 'TBitmap'. If I Run or save + close + open the test project (and ide) it says that 'invalid property path; Glyph->Data'. Also if I display the containing form 'as text' and switch back to 'as form' it could not show the bitmap. The bitmap data seems to be ok in form's dfm file after saving. Do I have to do something else to make it streamed out from there or ???


Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 13, 2005 6:05 am    Post subject: Re: Storing TBitmap property properly... Reply with quote


"MKo" <mirko.kontro (AT) ge (DOT) com> wrote


Quote:
__fastcall TExampleButton::TExampleButton(TComponent* Owner)
: TGraphicControl(Owner)
{
SetBounds( 0, 0, 50, 50 );
}

As I suspected, you are not managing the TBitmap properly. You are not
instantiating the TBitmap when the component is being instantiated. You
must do so. Waiting for SetGlyph() to be called first is much too late.
The DFM won't even call SetGlyph to begin with when loading the form from
the DFM data, thus you end up providing a NULL pointer to the DFM. That is
why you are getting the streaming error.

Change your code to the following instead:

__fastcall TExampleButton::TExampleButton(TComponent* Owner)
: TGraphicControl(Owner)
{
FGlyph = new Graphics::TBitmap;
FGlyph->OnChange = GlyphChanged;
SetBounds( 0, 0, 50, 50 );
}

void __fastcall TExampleButton::GlyphChanged(TObject*)
{
Invalidate();
}

void __fastcall TExampleButton::SetGlyph(Graphics::TBitmap* Value)
{
FGlyph->Assign(Value);
}

void __fastcall TExampleButton::Paint(void)
{
TRect cRect = ClientRect;
TRect tRect, gRect;
TColor TopColor, BottomColor;

Canvas->Brush->Color = clBtnFace;
Canvas->FillRect(cRect);

Graphics::TBitmap *bit = new Graphics::TBitmap;
try
{
bit->Width = ClientWidth;
bit->Height = ClientHeight;
bit->Canvas->Brush->Color = clBtnFace;
bit->Canvas->FillRect(cRect);

if( !FGlyph->Empty )
{
gRect = CalcGlyphLayout();
bit->Canvas->BrushCopy(gRect, FGlyph, Rect(0, 0,
FGlyph->Width, FGlyph->Height), FGlyph->TransparentColor);
}

BitBlt(Canvas->Handle, 0, 0, ClientWidth, ClientHeight,
bit->Canvas->Handle, 0, 0, SRCCOPY);
}
__finally
{
delete bit;
}
}

TRect __fastcall TExampleButton::CalcGlyphLayout(void)
{
int TextHeight = (!FCaption.IsEmpty()) ?
Canvas->TextHeight(FCaption) : 0;
int TotalHeight = FGlyph->Height + TextHeight + 5;

return Rect(
(ClientWidth/2)-(FGlyph->Width/2),
(ClientHeight/2)-(TotalHeight/2),
FGlyph->Width + ((ClientWidth/2)-(FGlyph->Width/2)),
FGlyph->Height + ((ClientHeight/2)-(TotalHeight/2))
);
}


Quote:
Code is based on example from C++Builder6 Deve Guide.

Then either the guide is wrong, or your interpretation of it is wrong. The
TBitmap was being completely mismanaged.


Gambit



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 13, 2005 6:08 am    Post subject: Re: Storing TBitmap property properly... Reply with quote


"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote


Quote:
__fastcall TExampleButton::TExampleButton(TComponent* Owner)
: TGraphicControl(Owner)
{
FGlyph = new Graphics::TBitmap;
FGlyph->OnChange = GlyphChanged;
SetBounds( 0, 0, 50, 50 );
}

Don't forget to also add a destructor, if you don't already have one:

__fastcall TExampleButton::~TExampleButton()
{
delete FGlyph;
}


Gambit



Back to top
MKo
Guest





PostPosted: Wed Apr 13, 2005 11:19 am    Post subject: Re: Storing TBitmap property properly... Reply with quote


"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote:
Quote:

"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote in message
news:425cb610$1 (AT) newsgroups (DOT) borland.com...

__fastcall TExampleButton::TExampleButton(TComponent* Owner)
: TGraphicControl(Owner)
{
FGlyph = new Graphics::TBitmap;
FGlyph->OnChange = GlyphChanged;
SetBounds( 0, 0, 50, 50 );
}

Don't forget to also add a destructor, if you don't already have one:

__fastcall TExampleButton::~TExampleButton()
{
delete FGlyph;
}


Gambit



Thank You for those !

But... now the bitmap set in form (and property) displays fine in form and is also streamed ok when saving and opening project again. However, running the program causes still:

"...EReadError with message: 'Invalid property path'" and debugger current execution point points to the constructor of TForm (naturally). Just don't understand... what path if bitmap is written to dfm and read from there. If I do not set any bitmap value to the control it runs fine so problem is still in the value of that somehow ??

Do I have to do something 'extra' in class header regarding the:

FGlyph->OnChange = GlyphChanged;



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 13, 2005 4:56 pm    Post subject: Re: Storing TBitmap property properly... Reply with quote


"MKo" <mirko.kontro (AT) ge (DOT) com> wrote


Quote:
now the bitmap set in form (and property) displays fine in form
and is also streamed ok when saving and opening project again.

Then the DFM is streaming properly.

Quote:
However, running the program causes still:

If that were the case, then the DFM would NOT be streaming properly to begin
with. There is no difference between design-time streaming vs. run-time
streaming. If it works at design-time, then it has to work at run-time as
well.

Quote:
"...EReadError with message: 'Invalid property path'" and debugger
current execution point points to the constructor of TForm (naturally).

The code works fine when I use it. You probably did not implement it
properly when you copied it over to your project.


Gambit



Back to top
MKo
Guest





PostPosted: Thu Apr 14, 2005 7:38 am    Post subject: Re: Storing TBitmap property properly... Reply with quote


"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote:
Quote:

"MKo" <mirko.kontro (AT) ge (DOT) com> wrote in message
news:425cf224$1 (AT) newsgroups (DOT) borland.com...

now the bitmap set in form (and property) displays fine in form
and is also streamed ok when saving and opening project again.

Then the DFM is streaming properly.

However, running the program causes still:

If that were the case, then the DFM would NOT be streaming properly to begin
with. There is no difference between design-time streaming vs. run-time
streaming. If it works at design-time, then it has to work at run-time as
well.

"...EReadError with message: 'Invalid property path'" and debugger
current execution point points to the constructor of TForm (naturally).

The code works fine when I use it. You probably did not implement it
properly when you copied it over to your project.


Gambit



Correct,

I copied the whole example again and created new test project and now runs ok. Also my own version works ok now. Thank You again !

MKo


Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Development) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.