home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / ACLOCK.PAK / ACLOCK.CPP next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  8.5 KB  |  364 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1993, 1995 by Borland International, All Rights Reserved
  4. //----------------------------------------------------------------------------
  5. #include <owl/pch.h>
  6. #include <owl/applicat.h>
  7. #include <owl/framewin.h>
  8. #include <owl/dialog.h>
  9. #include <owl/dc.h>
  10. #include <winsys/uimetric.h>
  11. #include "aclock.h"
  12. #include <alloc.h>
  13. #include <dos.h>
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include <mmsystem.h>
  17. #include <stdio.h>
  18.  
  19. #define USE_BWCC
  20.  
  21. #if defined(USE_BWCC)
  22. # define IDD_ABOUT "IDD_ABOUT_BWCC"
  23. #else
  24. # define IDD_ABOUT "IDD_ABOUT"
  25. #endif
  26.  
  27. const float Pi2 = 2*3.141592;
  28.  
  29. //
  30. // Chime & cukoo sounds based on the WIN.INI entries
  31. //
  32. const char ChimeSoundStr[] = "SystemAsterisk";
  33. const char CuckooSoundStr[] = "SystemExclamation";
  34.  
  35. //
  36. // Animated class animates a set of bitmaps
  37. //
  38. class Animated {
  39.   public:
  40.     Animated(HINSTANCE hInst, int numB, char far* name, int delayTics, int endTics);
  41.    ~Animated();
  42.  
  43.     void DisplayBegin(TDC& dc, int x, int y);
  44.     void DisplayNext(TDC& dc);
  45.  
  46.     BOOL IsRunning() {return WaitingTic;}
  47.  
  48.   private:
  49.     int       DelayTics;    // Amount to delay between frames (18.2 ticks/sec)
  50.     int       EndTics;      // Amount to delay after sequence
  51.     int       WaitingTic;   // Countdown for animation timing
  52.  
  53.     int       NumBmps;      // number of bitmaps
  54.     int       CurBmp;       // currently displayed bitmap
  55.     TBitmap** Bmps;         // bitmaps
  56.     int       X;            // position of bitmap
  57.     int       Y;
  58. };
  59.  
  60.  
  61. //
  62. // Construct an animated sequence
  63. //
  64. Animated::Animated(HINSTANCE hInst, int numB, char far* name, int delayTics, int endTics)
  65.  : WaitingTic(0)
  66. {
  67.   NumBmps = numB;
  68.   CurBmp = 0;
  69.   Bmps = new (TBitmap(*[NumBmps]));  //  create array of numB TBitmap*'s
  70.  
  71.   DelayTics = delayTics;
  72.   EndTics = endTics;
  73.  
  74.   // Load in bitmap resources
  75.   //
  76.   for (int j = 0; j < NumBmps; j++) {
  77.     char resName[40];
  78.     sprintf(resName, "%s%d", name, j+1);
  79.     Bmps[j] = new TBitmap(hInst, resName);
  80.   }
  81. }
  82.  
  83. //
  84. //
  85. //
  86. Animated::~Animated()
  87. {
  88.   for (int j = 0; j < NumBmps; j++)
  89.     delete Bmps[j];
  90.   delete[] Bmps;
  91. }
  92.  
  93. //
  94. // Begin to draw the series of bitmaps timed to the timer.
  95. //
  96. void
  97. Animated::DisplayBegin(TDC& dc, int x, int y)
  98. {
  99.   CurBmp = 0;
  100.   X = x;
  101.   Y = y;
  102.   WaitingTic = 1;   // prime the time clock
  103.   DisplayNext(dc);
  104. }
  105.  
  106. //
  107. // Draw each of the bitmaps timed to the timer.
  108. //
  109. void
  110. Animated::DisplayNext(TDC& dc)
  111. {
  112.   WaitingTic--;
  113.   if (WaitingTic || CurBmp == NumBmps)
  114.     return;
  115.  
  116.   TMemoryDC memDC(dc);
  117.  
  118.   memDC.SelectObject(*Bmps[CurBmp]);
  119.   dc.BitBlt(X, Y, Bmps[CurBmp]->Width(), Bmps[CurBmp]->Height(),
  120.             memDC, 0, 0, SRCCOPY);
  121.  
  122.   WaitingTic = (++CurBmp == NumBmps) ? EndTics : DelayTics;
  123. }
  124.  
  125. //----------------------------------------------------------------------------
  126.  
  127. //
  128. //
  129. //
  130. class TClockWindow : public TFrameWindow {
  131.   public:
  132.     TClockWindow(const char* title);
  133.     ~TClockWindow();
  134.  
  135.   protected:
  136.     void SetupWindow();
  137.  
  138.     void PaintHands(TDC& dc, struct time time);
  139.     void Paint(TDC&, bool, TRect&);
  140.  
  141.     void EvTimer(uint);
  142.     void CmAbout();
  143.     void CmChime();
  144.     void CmCuckoo();
  145.  
  146.   private:
  147.     TBitmap*    FaceBitmap;   // Clock face bitmap
  148.     TPoint      Center;       // Center of clock
  149.     int         Radius;       // Clock radius
  150.     struct time LastTime;     // Last time drawn
  151.     TPen*       HourPen;      // Pen for clock hour hand
  152.     TPen*       MinutePen;    // Pen for clock minute hand
  153.     Animated*   CuckooAnim;   // Cuckoo sequence
  154.  
  155.   DECLARE_RESPONSE_TABLE(TClockWindow);
  156. };
  157.  
  158. DEFINE_RESPONSE_TABLE1(TClockWindow, TFrameWindow)
  159.   EV_WM_TIMER,
  160.   EV_COMMAND(CM_ABOUT, CmAbout),
  161.   EV_COMMAND(CM_EFFECTCHIME, CmChime),
  162.   EV_COMMAND(CM_EFFECTCUCKOO, CmCuckoo),
  163. END_RESPONSE_TABLE;
  164.  
  165. //
  166. // Load animation sequences and set size in the constructor
  167. //
  168. TClockWindow::TClockWindow(const char* title)
  169.   : TFrameWindow(0, title, 0),
  170.     TWindow(0, title)
  171. {
  172.   // load face bitmap
  173.   //
  174.   FaceBitmap = new TBitmap(*GetModule(), "FACE_BMP");
  175.  
  176.   // load cuckoo sequence & set frame& end delay time in 1/10 sec tics
  177.   //
  178.   CuckooAnim = new Animated(*GetModule(), 8, "CUCKOO", 9, 80);
  179.  
  180.   // Set the window size to size of bitmap plus non-client area size
  181.   //
  182.   Attr.W = FaceBitmap->Width() + 2* TUIMetric::CxBorder;
  183.   Attr.H = FaceBitmap->Height() + TUIMetric::CyBorder +
  184.                                   TUIMetric::CyCaption +
  185.                                   TUIMetric::CyMenu ;
  186.   Attr.Style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
  187.  
  188.   Center.x = FaceBitmap->Width() / 2;
  189.   Center.y = FaceBitmap->Height() / 2;
  190.   Radius = 3*(Center.x < Center.y ? Center.x : Center.y) / 4;
  191. }
  192.  
  193. //
  194. //
  195. //
  196. TClockWindow::~TClockWindow()
  197. {
  198.   KillTimer(1);      // Get rid of timer
  199.   delete MinutePen;  // delete pens, bitmaps, animations
  200.   delete HourPen;
  201.   delete FaceBitmap;
  202.   delete CuckooAnim;
  203. }
  204.  
  205. //
  206. // Do any HWindow required setup tasks here, not in constructor
  207. //
  208. void
  209. TClockWindow::SetupWindow()
  210. {
  211.   TFrameWindow::SetupWindow();
  212.  
  213.   // set the timer - get called every minute
  214.   //
  215.   if (!SetTimer(1, 60000U, 0)) {
  216.     MessageBox("Out of Timers", GetApplication()->GetName(),
  217.                MB_ICONEXCLAMATION|MB_OK);
  218.   }
  219.  
  220.   // Create the pens for the clock hands
  221.   //
  222.   HourPen = new TPen(TColor(0, 255, 255), 4);   // cyan
  223.   MinutePen = new TPen(TColor(255, 0, 255), 4); // purple
  224. }
  225.  
  226. //
  227. // Paint the clock background and then the hands
  228. //
  229. void
  230. TClockWindow::Paint(TDC& dc, bool, TRect&)
  231. {
  232.   TMemoryDC memDC(dc);
  233.   memDC.SelectObject(*FaceBitmap);
  234.   dc.BitBlt(0, 0, FaceBitmap->Width(), FaceBitmap->Height(), memDC,
  235.             0, 0, SRCCOPY);
  236.   gettime(&LastTime);                   //paint the first time
  237.   PaintHands(dc, LastTime);
  238. }
  239.  
  240. //
  241. // Paint the hour and minute hands onto the face
  242. //
  243. void
  244. TClockWindow::PaintHands(TDC& dc, struct time time)
  245. {
  246.   // Compute the location of the hands
  247.   //
  248.   float minuteAngle = time.ti_min * Pi2 / 60;
  249.   float hourAngle = (time.ti_hour % 12) * Pi2 / 12 + minuteAngle/12;
  250.  
  251.   TPoint hourPt((Radius/2)*sin(hourAngle) + Center.x,
  252.                 (-Radius/2)*cos(hourAngle) + Center.y);
  253.   TPoint minutePt(Radius*sin(minuteAngle) + Center.x,
  254.                   -Radius*cos(minuteAngle) + Center.y);
  255.  
  256.   // Now draw them.  Note the use of XOR to simplify erasing.
  257.   //
  258.   dc.SetROP2(R2_XORPEN);
  259.   dc.SelectObject(*HourPen);
  260.   dc.MoveTo(Center);
  261.   dc.LineTo(hourPt);
  262.   dc.SelectObject(*MinutePen);
  263.   dc.MoveTo(Center);
  264.   dc.LineTo(minutePt);
  265.   dc.RestorePen();
  266. }
  267.  
  268. //
  269. // Menu item Effect:Chime
  270. //
  271. // Stop any currently playing sound, and then play the chime sound.
  272. //
  273. void
  274. TClockWindow::CmChime()
  275. {
  276.   sndPlaySound(0,0);
  277.   sndPlaySound(ChimeSoundStr, SND_ASYNC);
  278. }
  279.  
  280. //
  281. // Menu item Effect:Cuckoo
  282. //
  283. // Stop any currently playing sound, and then play the cuckoo sound.
  284. //
  285. void
  286. TClockWindow::CmCuckoo()
  287. {
  288.   sndPlaySound(0,0);
  289.   sndPlaySound(CuckooSoundStr, SND_ASYNC);
  290.  
  291.   // Do cute graphics, temporarally speeding up timer for animation
  292.   //
  293.   TClientDC dc(*this);
  294.   SetTimer(1, 10, 0);
  295.   CuckooAnim->DisplayBegin(dc, 55, 125);
  296. }
  297.  
  298. //
  299. // Called each timer tick. Every 1/10th second during animation and
  300. // every minute to paints hands
  301. //
  302. void
  303. TClockWindow::EvTimer(uint)
  304. {
  305.   TClientDC dc(*this);
  306.  
  307.   // If an animation is running, let it draw. If its done then, clean up.
  308.   //
  309.   if (CuckooAnim->IsRunning()) {
  310.     CuckooAnim->DisplayNext(dc);
  311.     if (!CuckooAnim->IsRunning()) {
  312.       SetTimer(1, 60000U, 0);
  313.       Invalidate(FALSE);
  314.     }
  315.     return;
  316.   }
  317.  
  318.   PaintHands(dc, LastTime);
  319.   gettime(&LastTime);
  320.   PaintHands(dc, LastTime);
  321.  
  322.   // Every hour play a chime
  323.   //
  324.   if (LastTime.ti_min == 0) {
  325.     CmChime();
  326.     if (LastTime.ti_hour == 0)  // If midnight, time for the cuckoo
  327.       CmCuckoo();
  328.   }
  329. }
  330.  
  331. //  About dialog box
  332. //
  333. void
  334. TClockWindow::CmAbout()
  335. {
  336.   TDialog(this, IDD_ABOUT).Execute();
  337. }
  338.  
  339. //----------------------------------------------------------------------------
  340.  
  341.  
  342. class TClockApp : public TApplication {
  343.   public:
  344.     TClockApp() : TApplication() {}
  345.     void InitMainWindow();
  346. };
  347.  
  348. void
  349. TClockApp::InitMainWindow()
  350. {
  351.   MainWindow = new TClockWindow("Cuckoo Clock");
  352.   MainWindow->AssignMenu("TOOL_MENU");
  353.   MainWindow->SetIcon(this, IDI_APP);
  354. #if defined(USE_BWCC)
  355.   EnableBWCC();
  356. #endif
  357. }
  358.  
  359. int
  360. OwlMain(int /*argc*/, char* /*argv*/ [])
  361. {
  362.   return TClockApp().Run();
  363. }
  364.