home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / ACLOCK.PAK / ACLOCK.CPP next >
C/C++ Source or Header  |  1995-08-29  |  9KB  |  361 lines

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