home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1990 / 11 / threads2.c < prev    next >
Text File  |  1990-05-08  |  7KB  |  211 lines

  1. ENVIRONMENTS
  2. CHARLES PETZOLD
  3. Vol. 9, No. 11
  4.  
  5. ---------------------------------------------------------
  6.  THREADS2.C -- Demonstrates drawing from a second thread
  7.                (c) 1990, Ziff Communications Co.
  8.                PC Magazine * Charles Petzold, 1/90
  9. ---------------------------------------------------------
  10.  
  11. #define INCL_WIN
  12. #define INCL_GPI
  13. #include <os2.h>
  14. #include <mt\process.h>
  15.  
  16. #define STACKSIZE 4096 * sizeof (int)
  17.  
  18. typedef struct
  19.      {
  20.      HPS   hps ;
  21.      BOOL  fContinue ;
  22.      BOOL  fTerminate ;
  23.      SHORT cxClient ;
  24.      SHORT cyClient ;
  25.      ULONG semTriggerDraw ;
  26.      ULONG semDoingDraw ;
  27.      }
  28.      THREADPARAMS ;
  29.  
  30. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  31. VOID    FAR      SecondThread (THREADPARAMS *) ;
  32. VOID             DrawPattern (HPS, SHORT, SHORT, BOOL *) ;
  33. VOID             DrawLine (HPS, SHORT, SHORT, SHORT, SHORT) ;
  34.  
  35. HAB  hab ;
  36.  
  37. int main (void)
  38.      {
  39.      static CHAR  szClientClass [] = "Threads2" ;
  40.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU |
  41.                                  FCF_SIZEBORDER    | FCF_MINMAX  |
  42.                                  FCF_SHELLPOSITION | FCF_TASKLIST ;
  43.      HMQ          hmq ;
  44.      HWND         hwndFrame, hwndClient ;
  45.      QMSG         qmsg ;
  46.  
  47.      hab = WinInitialize (0) ;
  48.      hmq = WinCreateMsgQueue (hab, 0) ;
  49.  
  50.      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
  51.  
  52.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  53.                                      &flFrameFlags, szClientClass, NULL,
  54.                                      0L, NULL, 0, &hwndClient) ;
  55.  
  56.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  57.           WinDispatchMsg (hab, &qmsg) ;
  58.  
  59.      WinDestroyWindow (hwndFrame) ;
  60.      WinDestroyMsgQueue (hmq) ;
  61.      WinTerminate (hab) ;
  62.      return 0 ;
  63.      }
  64.  
  65. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  66.      {
  67.      static int          aiThreadStack [STACKSIZE / sizeof (int)] ;
  68.      static THREADPARAMS tp ;
  69.      HDC                 hdc ;
  70.      SIZEL               sizl ;
  71.  
  72.      switch (msg)
  73.           {
  74.           case WM_CREATE:
  75.                               // create a presentation space for the window
  76.  
  77.                hdc = WinOpenWindowDC (hwnd) ;
  78.                sizl.cx = 0 ;
  79.                sizl.cy = 0 ;
  80.                tp.hps = GpiCreatePS (hab, hdc, &sizl,
  81.                                      PU_PELS    | GPIF_DEFAULT |
  82.                                      GPIT_MICRO | GPIA_ASSOC) ;
  83.  
  84.                               // start the thread after initialization
  85.  
  86.                tp.fTerminate = FALSE ;
  87.  
  88.                DosSemSet (&tp.semTriggerDraw) ;
  89.                DosSemClear (&tp.semDoingDraw) ;
  90.  
  91.                if (_beginthread (SecondThread, aiThreadStack,
  92.                                  STACKSIZE, &tp) == -1)
  93.                     {
  94.                     WinMessageBox (HWND_DESKTOP, hwnd,
  95.                                    "Cannot create second thread!", "Threads2",
  96.                                    0, MB_OK | MB_ICONEXCLAMATION) ;
  97.                     return 0 ;
  98.                     }
  99.  
  100.                return 0 ;
  101.  
  102.           case WM_SIZE:
  103.                               // stop the thread from drawing
  104.  
  105.                tp.fContinue = FALSE ;
  106.                DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
  107.  
  108.                tp.cxClient = SHORT1FROMMP (mp2) ;
  109.                tp.cyClient = SHORT2FROMMP (mp2) ;
  110.                return 0 ;
  111.  
  112.           case WM_PAINT:
  113.                               // stop the thread from drawing
  114.  
  115.                tp.fContinue = FALSE ;
  116.                DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
  117.  
  118.                               // erase the whole window
  119.  
  120.                WinInvalidateRect (hwnd, NULL, FALSE) ;
  121.  
  122.                WinBeginPaint (hwnd, tp.hps, NULL) ;
  123.                GpiErase (tp.hps) ;
  124.                WinEndPaint (tp.hps) ;
  125.  
  126.                               // let the thread start again at the beginning
  127.  
  128.                tp.fContinue = TRUE ;
  129.                DosSemSet (&tp.semDoingDraw) ;
  130.                DosSemClear (&tp.semTriggerDraw) ;
  131.                return 0 ;
  132.  
  133.           case WM_DESTROY:
  134.                               // stop the thread and clean up
  135.  
  136.                tp.fTerminate = TRUE ;
  137.                tp.fContinue  = FALSE ;
  138.                DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
  139.  
  140.                GpiDestroyPS (tp.hps) ;
  141.                return 0 ;
  142.           }
  143.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  144.      }
  145.  
  146. VOID _CDECL FAR SecondThread (THREADPARAMS * ptp)
  147.      {
  148.      HAB  hab ;
  149.  
  150.      hab = WinInitialize (0) ;
  151.  
  152.      while (!ptp->fTerminate)
  153.           {
  154.                               // wait for the semaphore to be cleared
  155.  
  156.           DosSemWait (&ptp->semTriggerDraw, SEM_INDEFINITE_WAIT) ;
  157.  
  158.                               // draw the pattern until stopped
  159.  
  160.           while (ptp->fContinue)
  161.                DrawPattern (ptp->hps, ptp->cxClient,
  162.                                       ptp->cyClient, &ptp->fContinue) ;
  163.  
  164.           DosSemSet (&ptp->semTriggerDraw) ;
  165.           DosSemClear (&ptp->semDoingDraw) ;
  166.           }
  167.  
  168.      WinTerminate (hab) ;
  169.      _endthread () ;
  170.      }
  171.  
  172. VOID DrawPattern (HPS hps, SHORT cxClient, SHORT cyClient, BOOL *pfContinue)
  173.      {
  174.      SHORT x, y ;
  175.  
  176.      GpiSetMix (hps, FM_INVERT) ;
  177.  
  178.      for (x = 0 ; *pfContinue && x < cxClient ; x++)
  179.           DrawLine (hps, 0, 0, x, cyClient) ;
  180.  
  181.      for (y = cyClient ; *pfContinue && y > 0 ; y--)
  182.           DrawLine (hps, 0, 0, cxClient, y) ;
  183.  
  184.      for (y = 0 ; *pfContinue && y < cyClient ; y++)
  185.           DrawLine (hps, cxClient, 0, 0, y) ;
  186.  
  187.      for (x = 0 ; *pfContinue && x < cxClient ; x++)
  188.           DrawLine (hps, cxClient, 0, x, cyClient) ;
  189.  
  190.      for (x = cxClient ; *pfContinue && x > 0 ; x--)
  191.           DrawLine (hps, cxClient, cyClient, x, 0) ;
  192.  
  193.      for (y = 0 ; *pfContinue && y < cyClient ; y++)
  194.           DrawLine (hps, cxClient, cyClient, 0, y) ;
  195.  
  196.      for (y = cyClient ; *pfContinue && y > 0 ; y--)
  197.           DrawLine (hps, 0, cyClient, cxClient, y) ;
  198.  
  199.      for (x = cxClient ; *pfContinue && x > 0 ; x--)
  200.           DrawLine (hps, 0, cyClient, x, 0) ;
  201.      }
  202.  
  203. VOID DrawLine (HPS hps, SHORT x1, SHORT y1, SHORT x2, SHORT y2)
  204.      {
  205.      POINTL ptl ;
  206.  
  207.      ptl.x = x1 ; ptl.y = y1 ; GpiMove (hps, &ptl) ;
  208.      ptl.x = x2 ; ptl.y = y2 ; GpiLine (hps, &ptl) ;
  209.      }
  210.  
  211.