Category : C++ Source Code
Archive   : LED.ZIP
Filename : LEDWIND.CPP

 
Output of file : LEDWIND.CPP contained in archive : LED.ZIP

//
// LED Window to Display Numbers
//
// Chris Hewitt, 100036,133
//
// Displays red LEDs on a black background. The chiseled surrounding is
// optional and is designed to fit on a GRAY background. Setting bSurround
// to TRUE adds 2 pixels to height and width. Height is 24, width is 13 *
// number of digits (not counting the surround).
//
// If bClock is TRUE, the LEDWindow becomes an HH:MM:SS clock, and
// lLEDValue should be a time variable (seconds since 1st Jan 1970,
// or, to be more exact, seconds since -05:00 on 0th Jan 1970!), just
// feed it a time value, or, for an elapsed time counter, a number.
//
// The maximum size of an LEDWindow is 10 Digits.
//
// StarTimer and StopTimer may be used to make the LED register
// time intervals between 1 and 60 seconds. The LED will be incremented
// by one for each interval.
//
// The Bitmaps led0.bmp thru led9.bmp must be declared in the resource
// file as LED0Bmp, LED1Bmp etc. (see example).
//


class LEDDigit : public TWindow
{
public:
LEDDigit( PTWindowsObject AParent, int DigitXLoc, BOOL bSurround,
HBITMAP hLED0Bmp );
void UpdateDigit( HBITMAP hLEDBmp );
virtual void Paint( HDC PaintDC, PAINTSTRUCT _FAR &PaintInfo );
HBITMAP hCurrentLEDBmp; // Digit Currently in Window
};


class LEDWindow : public TWindow
{
public:
LEDWindow( PTWindowsObject AParent, int x, int y,
int nDigits, BOOL bSurround, BOOL bClock, LONG lValue );
~LEDWindow( void );
void GetWindowClass(WNDCLASS& AWndClass);
void DisplayNumber( LONG lValue );
BOOL StartTimer( int nInterval );
void StopTimer( void );
void SetupLEDs( void );
virtual void Tick( RTMessage Msg ) = [WM_TIMER];
virtual void Paint(HDC PaintDC, PAINTSTRUCT&);
HBITMAP hLEDBmp[11]; // Bitmaps for LED numbers (0 - 9 + 🙂
BOOL bTimerActive; // Switch indicating if this is a timer
BOOL bSurroundExists; // True if Surround exists
BOOL bClockWindow; // True if this is a Clock
BOOL bLEDCreated; // First Time Switch
LONG lLEDValue; // The Current Value of this LED window
LONG lClockWork; // Used to store altered time values
struct tm *tmLEDValue; // Time Struct for Clock Windows
int nOldDigit[10]; // Old LED Digits
int nMaxDigits; // Maximum Number of Digits
int nTimerInterval; // The current Timer interval
int nDigitStart; // Start location of LED Digits in Window
int nRow, nCol; // The parent window offset of LED Window
LEDDigit *hLED[10]; // Handle array for LED Digit Children
//
// Note: LEDDigits are right to left: *hLED[0] (and nOldDigit[0]) is
// the right-most (ones) digit.
//

};


// LEDWindow Constructor
// Called with parent window handle, int x and y offsets in parent,
// int number of digits, and BOOL surround setting.

LEDWindow::LEDWindow( PTWindowsObject AParent, int x, int y,
int nDigits, BOOL bSurround, BOOL bClock, LONG lValue) :
TWindow( AParent, "" )
{
lLEDValue = lValue;
if( bClock )
{
nDigits = 8; // A clock HH:MM:SS
lClockWork = lLEDValue; // Work field for localtime
if(lClockWork<86400l) // Time is actually since -05:00
lClockWork = lClockWork + 18000l; // on 0th Jan 1970 !
tmLEDValue = localtime(&lClockWork); // Point struct at Value
}

if( nDigits>10 )
nDigits = 10;

Attr.W = 13*nDigits;
Attr.H = 24;
nDigitStart = Attr.W;
if( bSurround )
{
Attr.W = Attr.W + 2;
Attr.H = Attr.H + 2;
nDigitStart--;
}
Attr.X = y; // x and y are reversed because
Attr.Y = x; // of screen coordinates
Attr.Style = WS_VISIBLE|WS_CHILD;

hLEDBmp[0] = LoadBitmap ( GetApplication()->hInstance, "LED0Bmp" );
hLEDBmp[1] = LoadBitmap ( GetApplication()->hInstance, "LED1Bmp" );
hLEDBmp[2] = LoadBitmap ( GetApplication()->hInstance, "LED2Bmp" );
hLEDBmp[3] = LoadBitmap ( GetApplication()->hInstance, "LED3Bmp" );
hLEDBmp[4] = LoadBitmap ( GetApplication()->hInstance, "LED4Bmp" );
hLEDBmp[5] = LoadBitmap ( GetApplication()->hInstance, "LED5Bmp" );
hLEDBmp[6] = LoadBitmap ( GetApplication()->hInstance, "LED6Bmp" );
hLEDBmp[7] = LoadBitmap ( GetApplication()->hInstance, "LED7Bmp" );
hLEDBmp[8] = LoadBitmap ( GetApplication()->hInstance, "LED8Bmp" );
hLEDBmp[9] = LoadBitmap ( GetApplication()->hInstance, "LED9Bmp" );
hLEDBmp[10] = LoadBitmap ( GetApplication()->hInstance, "LEDColBmp" );

bTimerActive = FALSE;
bLEDCreated = FALSE;
bSurroundExists = bSurround;
bClockWindow = bClock;
nTimerInterval = 0;
nMaxDigits = nDigits;
SetupLEDs(); // Set up initial LED values
bLEDCreated = TRUE;
}

// LEDWindow Destructor
LEDWindow::~LEDWindow( void )
{
for( int i=0; i<10; i++ )
DeleteObject( hLEDBmp[i] );
}

// Modify the background colour attribute to GRAY
void LEDWindow::GetWindowClass(WNDCLASS& AWndClass)
{
HBRUSH BackBrush;

TWindow::GetWindowClass(AWndClass);
BackBrush = GetStockObject(GRAY_BRUSH);
AWndClass.hbrBackground = BackBrush;
}

// DisplayNumber - Accept a number to Display
void LEDWindow::DisplayNumber( LONG lValue )
{
lLEDValue = lValue;
if( bClockWindow )
{
lClockWork = lLEDValue; // Work field for localtime
if(lClockWork<86400l) // Handle 0th Jan 1970
lClockWork = lClockWork + 18000l; // Add 5 hours
tmLEDValue = localtime(&lClockWork); // Point struct at Value
}
SetupLEDs();
}

// StartTimer - Used to Start an LED Timer Window
BOOL LEDWindow::StartTimer( int nInterval)
{
if( nInterval == 0 || nInterval > 60)
{
return(FALSE);
}
// Set Timer (pass interval to SetTimer in milliseconds)
if(!SetTimer(HWindow, 1, (WORD) nInterval*1000, NULL))
{
return(FALSE);
}
else
{
bTimerActive = TRUE;
nTimerInterval = nInterval;
return(TRUE);
}
}

// StopTimer - Stops a previously started LED timer window
void LEDWindow::StopTimer(void)
{
if(bTimerActive==TRUE)
{
KillTimer(HWindow, 1);
bTimerActive=FALSE;
nTimerInterval = 0;
}
}

// Tick - Called for each WM_TIMER received by this LEDWindow
void LEDWindow::Tick(RTMessage)
{
lLEDValue = lLEDValue + 1;
if(bClockWindow)
{
lClockWork = lClockWork + 1; // Work field for localtime
tmLEDValue = localtime(&lClockWork); // Point struct at Value
}
SetupLEDs();
}

// Paint LEDWindow surround
void LEDWindow::Paint(HDC PaintDC, PAINTSTRUCT&)
{
HPEN OldPen;
HPEN WhitePen;
HPEN DkGrayPen;
BOOL MadeDC;

// Secure the device context
if ( PaintDC == 0 )
{
PaintDC = GetDC( HWindow );
MadeDC = TRUE;
}
else
MadeDC = FALSE;

// Paint the surround (if required)
if(bSurroundExists)
{
WhitePen = GetStockObject(WHITE_PEN);
DkGrayPen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));

OldPen = SelectObject(PaintDC, DkGrayPen);
MoveTo( PaintDC, 0, 0);
LineTo( PaintDC, (nMaxDigits*13)+1, 0);
MoveTo( PaintDC, 0, 0);
LineTo( PaintDC, 0, 24);

SelectObject(PaintDC, WhitePen);
MoveTo( PaintDC, 0, 24);
LineTo( PaintDC, (nMaxDigits*13)+1, 24);
MoveTo( PaintDC, (nMaxDigits*13)+1, 0);
LineTo( PaintDC, (nMaxDigits*13)+1, 25);

SetPixel(PaintDC, (nMaxDigits*13)+1, 0, RGB(192, 192, 192));
SetPixel(PaintDC, 0, 24, RGB(192, 192, 192));

SelectObject(PaintDC, OldPen);
DeleteObject(DkGrayPen);
}

if ( MadeDC )
ReleaseDC( HWindow, PaintDC );

}

// SetupLEDS - Work out which LEDDigits need to be replaced,
// then invalidate the little suckers. This is simple except if
// bClock = TRUE, in which case we need to handle ':'s.
void LEDWindow::SetupLEDs( void )
{
int nNewDigit;
LONG lWorkValue;

lWorkValue = lLEDValue;
for( int i=0; i {
if(bClockWindow && (i==2 || i==5))
// Digit 10 is ':', use for positions 2 and 5 of clocks
nNewDigit = 10;
else
{
if(bClockWindow)
{
// Treat Clock as 3 different values
if(i==0)
lWorkValue=tmLEDValue->tm_sec;
if(i==3)
lWorkValue=tmLEDValue->tm_min;
if(i==6)
lWorkValue=tmLEDValue->tm_hour;
}
// This will Generate a Warning: this is expected
nNewDigit = lWorkValue-((lWorkValue/10)*10);
lWorkValue = lWorkValue/10;
}
if(!bLEDCreated)
hLED[i] = new LEDDigit( this, nDigitStart-(13*(i+1)-1),
bSurroundExists, hLEDBmp[nNewDigit]);
else
if( nNewDigit != nOldDigit[i] )
hLED[i]->UpdateDigit(hLEDBmp[nNewDigit]);
nOldDigit[i] = nNewDigit;
}
}


// LEDDigit - Create a new LEDDigit
LEDDigit::LEDDigit( PTWindowsObject AParent, int DigitXLoc, BOOL bSurround,
HBITMAP hLEDBmp ) :
TWindow( AParent, "" )
{
Attr.W = 13;
Attr.H = 23;
Attr.Y = 0;
Attr.X = DigitXLoc;
if(bSurround)
{
Attr.X = Attr.X + 1;
Attr.Y = Attr.Y + 1;
}
Attr.Style = WS_VISIBLE|WS_CHILD;
hCurrentLEDBmp = hLEDBmp;
}

// UpdateDigit - Set the digit in question invalid
void LEDDigit::UpdateDigit(HBITMAP hLEDBmp)
{
hCurrentLEDBmp = hLEDBmp;
InvalidateRect(HWindow, NULL, TRUE);

}

// Paint - Paint the LEDDigit
void LEDDigit::Paint(HDC PaintDC, PAINTSTRUCT&)
{
HDC MemDC;
BOOL MadeDC;

// Secure the device context
if ( PaintDC == 0 )
{
PaintDC = GetDC( HWindow );
MadeDC = TRUE;
}
else
MadeDC = FALSE;

MemDC = CreateCompatibleDC( PaintDC );

SelectObject( MemDC, hCurrentLEDBmp);
BitBlt( PaintDC, 0, 0, 13, 24, MemDC, 0, 0, SRCCOPY );

if ( MadeDC )
ReleaseDC( HWindow, PaintDC );

DeleteDC( MemDC );
}