Board index » cppbuilder » TDBGrid Draw a backgroundImage

TDBGrid Draw a backgroundImage


2004-06-09 04:22:22 PM
cppbuilder98
Hi to all,
I have a DBGrid and i have drawn on it a background image on the bottom
right corner.
My problem is that if i have less records than the height of the grid, the
image is cutted.
in specificy when the GridDrawColumnCell draw the last cell, a white
regtangle fill the empty space and mask part of my background Image (and
this code is not in the event it like as an internal behavior of DBGrid)
How could i fix it?
thanks
Teo
 
 

Re:TDBGrid Draw a backgroundImage

"Gallo_Teo" < XXXX@XXXXX.COM >wrote:
Quote
[...] How could i fix it?
How is any one to know whithout seeing your code?
~ JD
 

Re:TDBGrid Draw a backgroundImage

i thought it was a known think...
the code is:
void __fastcall TSpostaFinalistiForm::GridDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column,
TGridDrawState State)
{
TCanvas *C = Grid->Canvas;
//------------------------------
// PUSH
//------------------------------
TPen *OldPen = new TPen();
TBrush *OldBrush = new TBrush();
TFont *OldFont = new TFont();
OldPen->Assign(C->Pen);;
OldBrush->Assign(C->Brush);
OldFont->Assign(C->Font);
if(!DisegnaSoloLaGriglia)
{
//-- I draw only the backGround Image
if(!SfondoDisegnato)
{
//-- Pulisco lo sfondo
C->Pen->Style = psClear ;
C->Brush->Style = bsSolid;
C->Brush->Color = clWhite;
C->FillRect(TRect(0,18,Grid->Width,Grid->Height));
//-- Draw
int X = Grid->Width - Bmp->Width - 40;
int Y = Grid->Height - Bmp->Height - 40;
C->Draw(X,Y, Bmp->Graphic);
SfondoDisegnato = true;
//-- POP
C->Pen->Assign(OldPen);
C->Brush->Assign(OldBrush);
C->Font->Assign(OldFont);
}
//-- Draw selected Record
if (Grid->SelectedRows->CurrentRowSelected)
{
C->Brush->Color = TColor(0x00C9CDD0);
C->Font->Color = clBlack;
C->Font->Style = TFontStyles()<< fsBold ;
C->TextRect(Rect, Rect.Left +1, Rect.Top + 2 ,
Column->Field->Text );
//-- POP
C->Pen->Assign(OldPen);
C->Brush->Assign(OldBrush);
C->Font->Assign(OldFont);
}
else
{
C->Brush->Style = bsClear;
C->Font->Color = Grid->Font->Color;
C->TextRect(Rect, Rect.Left +1, Rect.Top + 2,
Column->Field->Text );
//-- POP
C->Pen->Assign(OldPen);
C->Brush->Assign(OldBrush);
C->Font->Assign(OldFont);
}
}
//-- Draw Cell Border
C->Brush->Style = bsClear;
C->Pen->Color = clSilver;
C->Pen->Style = psSolid;
C->Pen->Width = 1;
C->Rectangle(Rect.Left-1, Rect.Top-1, Rect.Right + 1, Rect.Bottom + 1 );
//-- POP
C->Pen->Assign(OldPen);
C->Brush->Assign(OldBrush);
C->Font->Assign(OldFont);
}
"JD" < XXXX@XXXXX.COM >ha scritto nel messaggio
Quote

"Gallo_Teo" < XXXX@XXXXX.COM >wrote:
>[...] How could i fix it?

How is any one to know whithout seeing your code?

~ JD

 

{smallsort}

Re:TDBGrid Draw a backgroundImage

"Gallo_Teo" < XXXX@XXXXX.COM >wrote:
Quote
[...] the code is:
First allocate 2 bitmaps. Use one to load the image. Then set
the other bitmap dimensions to match the size of the grid and
use StretchDraw to copy from one bitmap to the other and then
delete the first bitmap.
Bitmap1 = new Graphics::TBitmap;
Bitmap1->LoadFromFile("C:/MyBitmap.bmp");
Bitmap2 = new Graphics::TBitmap;
Bitmap2->Height = DBGrid1->Height;
Bitmap2->Width = DBGrid1->Width;
Bitmap2->Canvas->StretchDraw( TRect(0, 0, DBGrid1->Width - 1, DBGrid1->Height - 1), Bitmap1 );
delete Bitmap1;
Now you have the bitmap sized exactly the same as the grid and
you can use the TRect parameter passed in the OnDraw event
because it will match up exactly with the section of the bitmap
that you want to draw.
Assumes that Bitmap2 has the background image:
void __fastcall TSpostaFinalistiForm::GridDrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State)
{
TDBGrid* pGrid = static_cast<TDBGrid*>( Sender );
TCanvas* pCanvas = pGrid->Canvas;
// paint the bitmap into the background
// The Rect should not include the grid lines
pCanvas->CopyRect( Rect, Bitmap2->Canvas, Rect );
// draw the text
DrawText( pCanvas->Handle, Column->Field->Text, -1, &Rect, DT_SINGLELINE | DT_VCENTER | DT_LEFT );
}
The only question in my mind is if you need to modify the
DrawText function because it wants a pointer to the text - not
the actual text - and I don't use data-aware components so I
can't test it for you.
~ JD
 

Re:TDBGrid Draw a backgroundImage

may be that my English and my explanation is too bad : | so sorry....
I don't need to resize image i simply have "place" it
I use 2 TPicture because i have two images to draw if i sort ASC or if i
sort DESC so i load it only one time onCreate of the form and i store them
in two TPicture
if u try my code and break it, u'll see that it works fine but when it draw
the last cell (bottom Right), if the Grid has no scroll and the records of
the table are LESS than the height of canvas, the last part of the picture
is cleared.
When i said the last part of the picture i mean that part witch is not under
the grid and the text. this part was visible until the last cell drawn
Why? it does not happen into Draw Event, so what's happened????
Thanks a lot for your help
Teo
"JD" < XXXX@XXXXX.COM >ha scritto nel messaggio
Quote

"Gallo_Teo" < XXXX@XXXXX.COM >wrote:
>[...] the code is:

First allocate 2 bitmaps. Use one to load the image. Then set
the other bitmap dimensions to match the size of the grid and
use StretchDraw to copy from one bitmap to the other and then
delete the first bitmap.

Bitmap1 = new Graphics::TBitmap;
Bitmap1->LoadFromFile("C:/MyBitmap.bmp");
Bitmap2 = new Graphics::TBitmap;
Bitmap2->Height = DBGrid1->Height;
Bitmap2->Width = DBGrid1->Width;
Bitmap2->Canvas->StretchDraw( TRect(0, 0, DBGrid1->Width - 1,
DBGrid1->Height - 1), Bitmap1 );
delete Bitmap1;

Now you have the bitmap sized exactly the same as the grid and
you can use the TRect parameter passed in the OnDraw event
because it will match up exactly with the section of the bitmap
that you want to draw.

Assumes that Bitmap2 has the background image:

void __fastcall TSpostaFinalistiForm::GridDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State)
{
TDBGrid* pGrid = static_cast<TDBGrid*>( Sender );
TCanvas* pCanvas = pGrid->Canvas;
// paint the bitmap into the background
// The Rect should not include the grid lines
pCanvas->CopyRect( Rect, Bitmap2->Canvas, Rect );
// draw the text
DrawText( pCanvas->Handle, Column->Field->Text, -1, &Rect,
DT_SINGLELINE | DT_VCENTER | DT_LEFT );
}

The only question in my mind is if you need to modify the
DrawText function because it wants a pointer to the text - not
the actual text - and I don't use data-aware components so I
can't test it for you.

~ JD

 

Re:TDBGrid Draw a backgroundImage

"Gallo_Teo" < XXXX@XXXXX.COM >wrote:
Quote
[...] so i load it only one time onCreate of the form
You should not be using OnCreate or OnDestroy. They are Delphi
remnants that can execute in the wrong sequence. You should be
using the constructor and destructor instead:
www.bcbdev.com/articles/suggest.htm
Quote
and i store them in two TPicture
TPicture is a visible control. A TBitmap would be better.
Quote
if u try my code and break it,
As I said before, I don't use data-aware components so I would
have no place from where to begin hooking up the data source
ect..
Quote
if the Grid has no scroll and the records of the table are
LESS than the height of canvas, the last part of the picture
is cleared.
Most likely the event is never being called because there is
no data for it.
You might be able to 'trick' it into executing by adding an
empty record to the data or by calling it yourself with an
empty Column.
You might also want to look at subclassing it's WndProc method
where you can intercept it's WM_ERASEBKGND message. That way
you can erase what you want and paint what you want where you
want with out regards to what the number of records are:
//--- in the form's header
private: // User declarations
void __fastcall NewDBGridWndProc( TMessage& );
TWndMethod OldDBGridWndProc;
public: // User declarations
__fastcall TForm1(TComponent* Owner); // don't duplicate this line
__fastcall TForm1::~TForm1();
//--- in the unit
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
OldDBGrigWndProc = DBGrid1->WindowProc;
DBGrid1->WindowProc = NewDBGridWndProc;
}
//-------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
DBGrid1->WindowProc = OldDBGridWndProc;
}
//-------------------------------------------------------------
void __fastcall TForm1::NewDBGridWndProc( TMessage &Message )
{
if( Message.Msg == WM_ERASEBKGND )
{
// do your drawing here instead
}
else OldDBGridWndProc( Message );
}
//-------------------------------------------------------------
~ JD
BTW : you should be t{*word*220} your posts.
 

Re:TDBGrid Draw a backgroundImage

Quote

You might also want to look at subclassing it's WndProc method
where you can intercept it's WM_ERASEBKGND message. That way
you can erase what you want and paint what you want where you
want with out regards to what the number of records are:

I Tried with WM_PAINT and with WM_ERASEBKGND but i really can't get it!
: (