"bar" <
XXXX@XXXXX.COM >wrote:
Quote
The point is i have to scroll some of the pictures and text.
For this i am creating images boxes and lable controls dynamically, all
together placed in a panel and i am moving this panel.
I have used a TPaintBox inside a TScrollBox where I paint a
huge TBitmap and scroll it with only a slight occurance of
flicker and that's without using DoubleBuffered.
Using TImage(s) can greatly reduce performance especially if
they're stretched. I would suggest that you use TBitmaps and
AnsiStrings instead and be sure that if you are reducing the
image that you do so when you load the image instead of doing
it every time you paint it.
Assuming that you have one TLabel for every TBitmap, define a
new class (that derives from TComponent because of Owner(ship)
benifits) that will allocate and manage the Text and Image for
you. For example:
//-------------------------------------------------------------
class TLabeledImage : public TComponent
{
private:
int FLeft;
int FTop;
AnsiString FText;
Graphics::TBitmap *FImage;
public:
__fastcall TLabeledImage( TComponent* Owner, int, int, int, int, AnsiString&, Graphics::TBitmap* );
__fastcall ~TLabeledImage();
__property int Left = { read = FLeft };
__property int Top = { read = FTop };
__property AnsiString Text = { read = FText };
__property Graphics::TBitmap *Image = { read = FImage };
};
//-------------------------------------------------------------
__fastcall TLabeledImage::TLabeledImage( TComponent* Owner, int AWidth, int AHeight, int ALeft, int ATop, AnsiString &AText, Graphics::TBitmap *AImage ) : TComponent(Owner)
{
FImage = new Graphics::TBitmap();
FImage->PixelFormat = pf24bit;
FImage->Canvas->Brush->Style = bsClear; // Reported to speed-up bitmap operations
FImage->Width = AWidth;
FImage->Height = AHeight;
FImage->Canvas->StretchDraw( Rect(0,0,AWidth,AHeight), AImage );
FLeft = ALeft;
FTop = ATop;
FText = AText;
}
//-------------------------------------------------------------
__fastcall TLabeledImage::~TLabeledImage()
{
delete FImage;
}
//-------------------------------------------------------------
To use it the above class, allocate it as needed in the loop
where you load the images. For example (note that the
TPaintBox is set at the Owner):
Graphics::TBitmap *Bmp = new Graphics::TBitmap();
int L = SomeInitialPos, T = SomeOtherInitialPos;
while( files still to load )
{
Bmp->LoadFromFile( SomeFileName );
new TLabeledImage( PaintBox1,
DesiredImageWidth,
DesiredImageHeight,
L,
T,
DesiredCaption,
Bmp );
if( L < SomeWidthLimit )
{
L += SomeNumberOfPixels;
}
else
{
L = SomeInitialPos;
H += SomeOtherNumberOfPixels;
}
}
PaintBox1->Height = H + MaybeSomeExtraPixels;
delete Bmp;
Then to draw the images, ad an OnPaint event to the TPaintBox
and make the code look like:
//-------------------------------------------------------------
void __fastcall TFormX::PaintBox1Paint(TObject *Sender)
{
TRect Dst, Src;
TPaintBox *Box = static_cast<TPaintBox*>( Sender );
for( int x = 0; x < Box->ComponentCount; ++x )
{
TLabeledImage *LI = static_cast<TLabeledImage*>( Box->Components[x] ); // might need reinterpret_cast here
Dst = Rect( LI->Left, LI->Top, LI->Left + LI->Image->Width, LI->Top + LI->Image->Height );
Src = Rect( 0, 0, LI->Image->Width, LI->Image->Height );
Box->Canvas->CopyRect( Dst, LI->Image->Canvas, Src );
Box->Canvas->TextOut( LI->Left + Something, LI->Top + Somethingelse, LI->Text );
}
}
//-------------------------------------------------------------
If you need to reuse the form without destroying it, you can
destroy all of the TLabeledImage by iterating the TPaintBox's
Components array. For example (Note that the array is iterated
backwards):
for( int x = PaintBox1->ComponentCount; x>0; --x )
{
delete PaintBox1->Components[ x - 1 ];
}
If you're not reusing the form, then because the TLabeledImages
are Owned by the TPaintBox and the TPaintBox is Owned by the
TForm, when the TForm is destroyed, the TPaintBox is also
destroyed which will cause all of the TLabeledImages that it
Ownes to be destroyed. IOW, a simple call to delete to destroy
the form is all that's needed.
You should not need to worry about scrolling any more because
the TScrollBox will automatically handle all of that for you
according to how you have positioned and sized the TPaintBox
but if you still want to, all you have to do is set the
TScrollBox's scroll positions.
~ JD