home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
ACLOCK.PAK
/
ACLOCK.CPP
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
9KB
|
361 lines
//----------------------------------------------------------------------------
// ObjectWindows - (C) Copyright 1991, 1993 by Borland International
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dialog.h>
#include <owl\dc.h>
#include "aclock.h"
#include <alloc.h>
#include <dos.h>
#include <stdlib.h>
#include <math.h>
#include <mmsystem.h>
#include <stdio.h>
#define USE_BWCC
#if defined(USE_BWCC)
#define IDD_ABOUT "IDD_ABOUT_BWCC"
#else
#define IDD_ABOUT "IDD_ABOUT"
#endif
const float Pi2 = 2*3.141592;
//
// Chime & cukoo sounds based on the WIN.INI entries
//
const char ChimeSoundStr[] = "SystemAsterisk";
const char CuckooSoundStr[] = "SystemExclamation";
//
// Animated class animates a set of bitmaps
//
class Animated {
public:
Animated(HINSTANCE hInst, int numB, char far* name, int delayTics, int endTics);
~Animated();
void DisplayBegin(TDC& dc, int x, int y);
void DisplayNext(TDC& dc);
BOOL IsRunning() {return WaitingTic;}
private:
int DelayTics; // Amount to delay between frames (18.2 ticks/sec)
int EndTics; // Amount to delay after sequence
int WaitingTic; // Countdown for animation timing
int NumBmps; // number of bitmaps
int CurBmp; // currently displayed bitmap
TBitmap** Bmps; // bitmaps
int X; // position of bitmap
int Y;
};
//
// Construct an animated sequence
//
Animated::Animated(HINSTANCE hInst, int numB, char far* name, int delayTics, int endTics)
: WaitingTic(0)
{
NumBmps = numB;
CurBmp = 0;
Bmps = new (TBitmap(*[NumBmps])); // create array of numB TBitmap*'s
DelayTics = delayTics;
EndTics = endTics;
// Load in bitmap resources
//
for (int j = 0; j < NumBmps; j++) {
char resName[40];
wsprintf(resName, "%s%d", name, j+1);
Bmps[j] = new TBitmap(hInst, resName);
}
}
//
//
//
Animated::~Animated()
{
for (int j = 0; j < NumBmps; j++)
delete Bmps[j];
delete Bmps;
}
//
// Begin to draw the series of bitmaps timed to the timer.
//
void
Animated::DisplayBegin(TDC& dc, int x, int y)
{
CurBmp = 0;
X = x;
Y = y;
WaitingTic = 1; // prime the time clock
DisplayNext(dc);
}
//
// Draw each of the bitmaps timed to the timer.
//
void
Animated::DisplayNext(TDC& dc)
{
WaitingTic--;
if (WaitingTic || CurBmp == NumBmps)
return;
TMemoryDC memDC(dc);
memDC.SelectObject(*Bmps[CurBmp]);
dc.BitBlt(X, Y, Bmps[CurBmp]->Width(), Bmps[CurBmp]->Height(),
memDC, 0, 0, SRCCOPY);
WaitingTic = (++CurBmp == NumBmps) ? EndTics : DelayTics;
}
//----------------------------------------------------------------------------
//
//
//
class TClockWindow : public TFrameWindow {
public:
TClockWindow(const char* title);
~TClockWindow();
protected:
void SetupWindow();
void PaintHands(TDC& dc, struct time time);
void Paint(TDC&, BOOL, TRect&);
void EvTimer(UINT);
void CmAbout();
void CmChime();
void CmCuckoo();
private:
TBitmap* FaceBitmap; // Clock face bitmap
TPoint Center; // Center of clock
int Radius; // Clock radius
struct time LastTime; // Last time drawn
TPen* HourPen; // Pen for clock hour hand
TPen* MinutePen; // Pen for clock minute hand
Animated* CuckooAnim; // Cuckoo sequence
DECLARE_RESPONSE_TABLE(TClockWindow);
};
DEFINE_RESPONSE_TABLE1(TClockWindow, TFrameWindow)
EV_WM_TIMER,
EV_COMMAND(CM_ABOUT, CmAbout),
EV_COMMAND(CM_EFFECTCHIME, CmChime),
EV_COMMAND(CM_EFFECTCUCKOO, CmCuckoo),
END_RESPONSE_TABLE;
//
// Load animation sequences and set size in the constructor
//
TClockWindow::TClockWindow(const char* title)
: TFrameWindow(0, title, 0),
TWindow(0, title)
{
// load face bitmap
//
FaceBitmap = new TBitmap(*GetModule(), "FACE_BMP");
// load cuckoo sequence & set frame& end delay time in 1/10 sec tics
//
CuckooAnim = new Animated(*GetModule(), 8, "CUCKOO", 9, 80);
// Set the window size to size of bitmap plus non-client area size
//
Attr.W = FaceBitmap->Width() + 2*GetSystemMetrics(SM_CXBORDER);
Attr.H = FaceBitmap->Height() + GetSystemMetrics(SM_CYBORDER) +
GetSystemMetrics(SM_CYCAPTION) +
GetSystemMetrics(SM_CYMENU);
Attr.Style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
Center.x = FaceBitmap->Width() / 2;
Center.y = FaceBitmap->Height() / 2;
Radius = 3*(Center.x < Center.y ? Center.x : Center.y) / 4;
}
//
//
//
TClockWindow::~TClockWindow()
{
KillTimer(1); // Get rid of timer
delete MinutePen; // delete pens, bitmaps, animations
delete HourPen;
delete FaceBitmap;
delete CuckooAnim;
}
//
// Do any HWindow required setup tasks here, not in constructor
//
void
TClockWindow::SetupWindow()
{
TFrameWindow::SetupWindow();
// set the timer - get called every minute
//
if (!SetTimer(1, 60000U, 0)) {
MessageBox("Out of Timers", GetApplication()->GetName(),
MB_ICONEXCLAMATION|MB_OK);
}
// Create the pens for the clock hands
//
HourPen = new TPen(TColor(0, 255, 255), 4); // cyan
MinutePen = new TPen(TColor(255, 0, 255), 4); // purple
}
//
// Paint the clock background and then the hands
//
void
TClockWindow::Paint(TDC& dc, BOOL, TRect&)
{
TMemoryDC memDC(dc);
memDC.SelectObject(*FaceBitmap);
dc.BitBlt(0, 0, FaceBitmap->Width(), FaceBitmap->Height(), memDC, 0, 0, SRCCOPY);
gettime(&LastTime); //paint the first time
PaintHands(dc, LastTime);
}
//
// Paint the hour and minute hands onto the face
//
void
TClockWindow::PaintHands(TDC& dc, struct time time)
{
// Compute the location of the hands
//
float minuteAngle = time.ti_min * Pi2 / 60;
float hourAngle = (time.ti_hour % 12) * Pi2 / 12 + minuteAngle/12;
TPoint hourPt((Radius/2)*sin(hourAngle) + Center.x,
(-Radius/2)*cos(hourAngle) + Center.y);
TPoint minutePt(Radius*sin(minuteAngle) + Center.x,
-Radius*cos(minuteAngle) + Center.y);
// Now draw them. Note the use of XOR to simplify erasing.
//
dc.SetROP2(R2_XORPEN);
dc.SelectObject(*HourPen);
dc.MoveTo(Center);
dc.LineTo(hourPt);
dc.SelectObject(*MinutePen);
dc.MoveTo(Center);
dc.LineTo(minutePt);
dc.RestorePen();
}
//
// Menu item Effect:Chime
//
// Stop any currently playing sound, and then play the chime sound.
//
void
TClockWindow::CmChime()
{
sndPlaySound(0,0);
sndPlaySound(ChimeSoundStr, SND_ASYNC);
}
//
// Menu item Effect:Cuckoo
//
// Stop any currently playing sound, and then play the cuckoo sound.
//
void
TClockWindow::CmCuckoo()
{
sndPlaySound(0,0);
sndPlaySound(CuckooSoundStr, SND_ASYNC);
// do cute graphics, temporarally speeding up timer for animation
//
TClientDC dc(*this);
SetTimer(1, 10, 0);
CuckooAnim->DisplayBegin(dc, 55, 125);
}
//
// Called each timer tick. Every 1/10th second during animation and
// every minute to paints hands
//
void
TClockWindow::EvTimer(UINT)
{
TClientDC dc(*this);
// If an animation is running, let it draw. If its done then, clean up.
//
if (CuckooAnim->IsRunning()) {
CuckooAnim->DisplayNext(dc);
if (!CuckooAnim->IsRunning()) {
SetTimer(1, 60000U, 0);
Invalidate(FALSE);
}
return;
}
PaintHands(dc, LastTime);
gettime(&LastTime);
PaintHands(dc, LastTime);
// Every hour play a chime
//
if (LastTime.ti_min == 0) {
CmChime();
if (LastTime.ti_hour == 0) // If midnight, time for the cuckoo
CmCuckoo();
}
}
// About dialog box
//
void
TClockWindow::CmAbout()
{
TDialog(this, IDD_ABOUT).Execute();
}
//----------------------------------------------------------------------------
class TClockApp : public TApplication {
public:
TClockApp() : TApplication() {}
void InitMainWindow();
};
void
TClockApp::InitMainWindow()
{
MainWindow = new TClockWindow("Cuckoo Clock");
MainWindow->AssignMenu("TOOL_MENU");
MainWindow->SetIcon(this, "ICON_1");
#if defined(USE_BWCC)
EnableBWCC();
#endif
}
int
OwlMain(int /*argc*/, char* /*argv*/ [])
{
return TClockApp().Run();
}