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

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1995 by Borland International, All Rights Reserved
  4. //
  5. // A Multi-thread GDI demo program
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #include <owl/applicat.h>
  9. #include <owl/mdi.h>
  10. #include <string.h>
  11. #include "demobase.h"
  12. #include "line.h"
  13. #include "arty.h"
  14.  
  15. //
  16. // Menu bar constants
  17. //
  18. const int MenuId             = 100;  // Resource Id of the menubar
  19. const int MoveToLineToDemoId = 201;  // Demo->MoveToDemo Id
  20. const int ArtyDemoId         = 202;  // Demo->Arty Demo Id
  21.  
  22. const int IconId             = 100;  // Resource Id of the program icon
  23.  
  24. const int SpeedDelay         = 20;   // Minimum delay between thread iterations
  25.  
  26. //----------------------------------------------------------------------------
  27.  
  28. //
  29. //
  30. //
  31. TBaseDemoWindow::TBaseDemoWindow()
  32. :
  33.   TWindow(0, 0, 0),
  34.   Sync(0, 2)        // We'll add 2 objects to this semaphore
  35. {
  36.   Sync.Add(*GetApplication()->GetMutex());  // (Assumes the mutex is present)
  37.   Sync.Add(Done);
  38. }
  39.  
  40. //
  41. // Start this thread and adjust priority down. The demo windows run at a lower
  42. // priority than the main thread.
  43. //
  44. TThread::THandle
  45. TBaseDemoWindow::Start()
  46. {
  47.   TThread::THandle result = TThread::Start();
  48.   SetPriority(Lowest);
  49.   return result;
  50. }
  51.  
  52. //
  53. //
  54. //
  55. int
  56. TBaseDemoWindow::Run()
  57. {
  58.   for (;;) {
  59.     Sleep(SpeedDelay);
  60.  
  61.     // Attempt to lock one of our two semaphores: AppMutex, or Done
  62.     //
  63.     TSemaphoreSet::TLock l(Sync, TSemaphoreSet::WaitAny);
  64.  
  65.     if (!l.WasAquired())        // We timed out or erred somehow
  66.       return -1;
  67.  
  68.     if (l.WhichAquired() == 1)  // The Done event was signaled, time to exit
  69.       return 0;
  70.             
  71.     // We've got the AppMutex, call into the derived class for the actual
  72.     // processing
  73.     //
  74.     ClockTick();
  75.   }
  76. }
  77.  
  78. //
  79. //
  80. //
  81. TApplication*
  82. TBaseDemoWindow::GetApplication() const
  83. {
  84.   return TWindow::GetApplication();
  85. }
  86.  
  87. //
  88. //
  89. //
  90. bool
  91. TBaseDemoWindow::CanClose()
  92. {
  93.   if (TerminateAndWait(1000) == 0) {
  94.     return true;
  95.   }
  96.   else {
  97.     MessageBox("Timeout while terminating thread", "MTHREAD");
  98.     return false;
  99.   }
  100. }
  101.  
  102. IMPLEMENT_CASTABLE1(TBaseDemoWindow, TWindow);
  103.  
  104. //----------------------------------------------------------------------------
  105.  
  106. //
  107. //
  108. //
  109. class TGdiDemoWindow : public TMDIClient {
  110.   public:
  111.     TGdiDemoWindow() : TMDIClient() { Attr.Style |= WS_TABSTOP; }
  112.  
  113.   protected:
  114.     void CmMoveToLineToDemo();
  115.     void CmArtyDemo();
  116.  
  117.   DECLARE_RESPONSE_TABLE(TGdiDemoWindow);
  118. };
  119.  
  120. DEFINE_RESPONSE_TABLE1(TGdiDemoWindow, TMDIClient)
  121.   EV_COMMAND(MoveToLineToDemoId, CmMoveToLineToDemo),
  122.   EV_COMMAND(ArtyDemoId, CmArtyDemo),
  123. END_RESPONSE_TABLE;
  124.  
  125.  
  126. //
  127. // In response to a demo command, create one of the demo windows as the client
  128. // of an mdi child frame. Turn of the icon for the mdi child to allow the
  129. // client to paint itself when iconic.
  130. //
  131.  
  132. void
  133. TGdiDemoWindow::CmMoveToLineToDemo()
  134. {
  135.   TMDIChild* child = new TMDIChild(*this, "MoveTo/LineTo Window",
  136.                                    new TMoveToLineToWindow);
  137.   child->SetIcon(0, 0);
  138.   child->Create();
  139. }
  140.  
  141. void
  142. TGdiDemoWindow::CmArtyDemo()
  143. {
  144.   TMDIChild* child = new TMDIChild(*this, "Arty Window", new TArtyWindow);
  145.   child->SetIcon(0, 0);
  146.   child->Create();
  147. }
  148.  
  149. //----------------------------------------------------------------------------
  150.  
  151. //
  152. //
  153. //
  154. class TGdiDemoApp : public TApplication {
  155.   public:
  156.     TGdiDemoApp() : TApplication() {}
  157.     void InitMainWindow();
  158. };
  159.  
  160. //
  161. //
  162. //
  163. void
  164. TGdiDemoApp::InitMainWindow()
  165. {
  166.   TFrameWindow* fw = new TMDIFrame("Multi-Thread Demo", MenuId, *new TGdiDemoWindow);
  167.   fw->SetIcon(this, IconId);
  168.   SetMainWindow(fw);
  169.  
  170.   // This is very important when using threads with a TApplication, and is
  171.   // new to OWL 5.0. Without this the app runs faster since it doesn't have
  172.   // to lock a mutex during message dispatching.
  173.   //
  174.   EnableMultiThreading(true);
  175. }
  176.  
  177. //
  178. //
  179. //
  180. int
  181. OwlMain(int /*argc*/, char* /*argv*/ [])
  182. {
  183.   // If under Win32, then make sure it is a version that has threads. If Win16
  184.   // then shouldn't build at all
  185.   //
  186.   if (!TSystem::SupportsThreads()) {
  187.     ::MessageBox(0, "This Example requires a multithreaded version of Windows",
  188.                  "OWL Examples", MB_OK);
  189.     return 0;
  190.   }
  191.   return TGdiDemoApp().Run();
  192. }
  193.