Category : C++ Source Code
Archive   : LED.ZIP
Filename : LEDWIND.CPP
// 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 );
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/