Warwick Guest
|
Posted: Tue Dec 09, 2003 10:25 am Post subject: TImage descendant does not draw |
|
|
Hi,
Here is an LED component that I cant get to draw at all.
Oddly when I derived from TCustomGrid the logic below worked fine, but
now it wont draw at all - Image remains white. (TCustomGrid has a
problem with cell borders that makes it unsuitable for this
implementation:( )
It is simple stuff so I am hoping the definitions and declarations
will suffice without explanation. If ANYONE from the collective wisdom
of this group point out the error of my ways I would be very grateful
indeed.
#ifndef LEDH
#define LEDH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <ExtCtrls.hpp>
#include <math.h>
//---------------------------------------------------------------------------
class PACKAGE TLED : public TImage
{
private:
int FDigits;
int FValue;
AnsiString OutString;
bool FColour; //iff true red else black and white
int CellHeight;
int CellWidth;
TImageList* Images;
protected:
void __fastcall WMSize(TWMSize &Message);
void __fastcall Update();
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SIZE, TWMSize, WMSize)
END_MESSAGE_MAP(TImage)
void __fastcall MakeString ();
void __fastcall DrawACell( const Types::TRect &ARect, char c);
public:
__fastcall TLED(TComponent* Owner);
virtual __fastcall ~TLED();
void __fastcall SetValue (int);
void __fastcall SetColour (bool);
void __fastcall SetDigits(int);
__published:
__property int Digits= {read=FDigits, write=SetDigits, default=3
};
__property bool Colour={read=FColour,write=SetColour, default=true
};
__property int Value={read=FValue, write=SetValue, default=0};
__property Hint;
__property ShowHint;
};
//---------------------------------------------------------------------------
#endif
implementation ...
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LED.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not
have
// any pure virtual functions.
//
const AnsiString Path = "C:\Program
Files\Borland\CBuilder6\Projects\TLED\";
static inline void ValidCtrCheck(TLED *)
{
new TLED(NULL);
}
//---------------------------------------------------------------------------
__fastcall TLED::TLED(TComponent* Owner)
: TImage(Owner), FColour(true), FDigits(3), FValue(0)
{
try
{
Images = new TImageList(this);
Images->Height=23;
Images->Width=13;
Graphics::TBitmap* ptrBmp = new Graphics::TBitmap;
AnsiString fname(Path);
if( FColour==true )
fname += "LED_RED.bmp";
else
fname += "LED_BW.bmp";
ptrBmp->LoadFromFile(fname);
int top, bottom;
//12 images 13 pixels wide, 23 pixels high, image is 13x276
for( top = 0, bottom = 22; bottom < 277; top=bottom+1,
bottom+=23 )
{
Graphics::TBitmap* slice = new Graphics::TBitmap;
slice->Height = 23;
slice->Width = 13;
TRect RectDest(TPoint(0,0), TPoint(12, 22));
TRect RectSource(TPoint(0,top) ,TPoint(12, bottom));
slice->Canvas->CopyRect(RectDest, ptrBmp->Canvas,
RectSource);
Images->Add(slice, NULL);
}
delete ptrBmp;
Update();
}//try
catch(...)
{
throw ;
}
}
//---------------------------------------------------------------------------
namespace Led
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TLED)};
RegisterComponents("System", classes, 0);
}
}
//---------------------------------------------------------------------------
__fastcall TLED::~TLED()
{
Images->Clear();
delete Images;
}
//---------------------------------------------------------------------------
void __fastcall TLED::SetDigits(int n)
{
FDigits = n;
Update();
}
//---------------------------------------------------------------------------
void __fastcall TLED::SetColour(bool C)
{
FColour = C;
Update();
}
//---------------------------------------------------------------------------
void __fastcall TLED::SetValue (int newValue)
{
if(newValue >= pow10(FDigits) || newValue <= -(pow10(FDigits-1)) )
return;
FValue = newValue;
Update();
}
//---------------------------------------------------------------------------
void __fastcall TLED::WMSize(TWMSize &Message)
{
CellWidth = Message.Width / FDigits; // set new cell width
CellHeight = Message.Height; // and cell height
}
//------------------------------------------------------------------------
void __fastcall TLED::MakeString ()
{
OutString = IntToStr(FValue);
const AnsiString pad(' ');
while( OutString.Length() < FDigits )
OutString.Insert(pad, 1);
}
//---------------------------------------------------------------------------
void __fastcall TLED::Update()
{
MakeString();
for( int top=0, left=0, right=CellWidth, bottom=CellHeight, i=1;
i <= FDigits;
left+=CellWidth, right+=CellHeight, ++i )
{
Types::TRect ARect(left, top, right, bottom);
DrawACell(ARect, OutString[i]);
}
//Refresh(); this is a bad idea! causes infinite recursion
}
//---------------------------------------------------------------------------
void __fastcall TLED::DrawACell( const Types::TRect &ARect, char c)
{
Graphics::TBitmap* ptrBmp = new Graphics::TBitmap;
switch(c)
{
case '-': Images->GetBitmap(0, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '0': Images->GetBitmap(11, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '1': Images->GetBitmap(10, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '2': Images->GetBitmap(9, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '3': Images->GetBitmap(8, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '4': Images->GetBitmap(7, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '5': Images->GetBitmap(6, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '6': Images->GetBitmap(5, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '7': Images->GetBitmap(4, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '8': Images->GetBitmap(3, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case '9': Images->GetBitmap(2, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
case ' ': Images->GetBitmap(1, ptrBmp);
Canvas->StretchDraw(ARect, ptrBmp);
break;
default: Images->GetBitmap(1, ptrBmp); //Blank
Canvas->StretchDraw(ARect, ptrBmp);
break;
}//switch
delete ptrBmp;
}
Test unit - contains a timer and button object
TForm1 *Form1;
bool timerOn;
int ElapsedTime = 0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
timerOn = false;
LED = new TLED(this);
LED->Parent = this;
LED->Width = 72;
LED->Height = 36;
LED->Hint=AnsiString("this is supposed to be a led");
LED->ShowHint=true;
ElapsedTime = -99;
LED->Value = ElapsedTime;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if( timerOn )
LED->Value = ++ElapsedTime;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
timerOn=!timerOn;
}
//---------------------------------------------------------------------------
|
|