home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / S10072.ZIP / PMTHREAD.ALL
Text File  |  1988-03-11  |  31KB  |  1,109 lines

  1. Microsoft Systems Journal
  2. Volume 3; Issue 2; March, 1988
  3.  
  4. Code Listings For:
  5.  
  6.     BIGJOB1 ... BIGJOB5
  7.     pp. 11-27
  8.  
  9. Author(s): Charles Petzold
  10. Title:     Utilizing Os/2 Multithread Techniques in Presentation Manager
  11.            Applications
  12.  
  13.  
  14.  
  15. Figure 1  
  16. ========
  17.  
  18.  
  19. /*--------------------------------
  20.    BIGJOB.RC resource script file
  21.   --------------------------------*/
  22.  
  23. #include <os2.h>
  24. #include "bigjob.h"
  25.  
  26. MENU ID_RESOURCE
  27.      {
  28.      SUBMENU "~Repetitions",  IDM_REPS
  29.           {
  30.           MENUITEM "     10", IDM_10,    MIA_CHECKED
  31.           MENUITEM "    100", IDM_100
  32.           MENUITEM "   1000", IDM_1000
  33.           MENUITEM "  10000", IDM_10000
  34.           }
  35.      SUBMENU "~Action",       IDM_ACTION
  36.           {
  37.           MENUITEM "~Start",  IDM_START
  38.           MENUITEM "~Abort",  IDM_ABORT, MIA_DISABLED
  39.           }
  40.      }
  41.  
  42.  
  43. ==============================================================================
  44.  
  45.  
  46. /*----------------------
  47.    BIGJOB.H header file
  48.   ----------------------*/
  49.  
  50. #define ID_RESOURCE 1
  51.  
  52. #define IDM_REPS    1
  53. #define IDM_ACTION  2
  54.  
  55. #define IDM_10      10
  56. #define IDM_100     100
  57. #define IDM_1000    1000
  58. #define IDM_10000   10000
  59.  
  60. #define IDM_START   20
  61. #define IDM_ABORT   21
  62.  
  63.      /*-----------------------------------------------------
  64.         Definitions, functions, and variables for BIGJOBx.C
  65.        -----------------------------------------------------*/
  66.  
  67. #ifndef RC_INVOKED       /* This stuff not needed for .RC file */
  68.  
  69. #define STATUS_READY     0
  70. #define STATUS_WORKING   1
  71. #define STATUS_DONE      2
  72.  
  73. ULONG EXPENTRY ClientWndProc (HWND, USHORT, ULONG, ULONG) ;
  74.  
  75. HAB  hab ;
  76.  
  77. double Savage (double A)
  78.      {
  79.      return tan (atan (exp (log (sqrt (A * A))))) + 1.0 ;
  80.      }
  81.  
  82. VOID CheckMenuItem (HWND hwnd, SHORT iMenuItem, BOOL bCheck)
  83.      {
  84.      HWND hwndParent = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
  85.      HWND hwndMenu   = WinWindowFromID (hwndParent, FID_MENU) ;
  86.  
  87.      WinSendMsg (hwndMenu, MM_SETITEMATTR, MAKEULONG (iMenuItem, TRUE),
  88.                  MAKEULONG (MIA_CHECKED, bCheck ? MIA_CHECKED : 0)) ;
  89.      }
  90.  
  91. VOID EnableMenuItem (HWND hwnd, SHORT iMenuItem, BOOL bEnable)
  92.      {
  93.      HWND hwndParent = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
  94.      HWND hwndMenu   = WinWindowFromID (hwndParent, FID_MENU) ;
  95.  
  96.      WinSendMsg (hwndMenu, MM_SETITEMATTR, MAKEULONG (iMenuItem, TRUE),
  97.                  MAKEULONG (MIA_DISABLED, bEnable ? 0 : MIA_DISABLED)) ;
  98.      }
  99.  
  100. VOID PaintWindow (HWND hwnd, SHORT iStatus, SHORT iRep, LONG lTime)
  101.      {
  102.      static CHAR *szMessage [3] = { "Ready", "Working ...",
  103.                                     "%d repetitions in %ld msec." } ;
  104.      CHAR        szBuffer [60] ;
  105.      HPS         hps ;
  106.      WRECT       wrc ;
  107.  
  108.      hps = WinBeginPaint (hwnd, NULL, NULL) ;
  109.      GpiErase (hps) ;
  110.  
  111.      WinQueryWindowRect (hwnd, &wrc) ;
  112.  
  113.      sprintf (szBuffer, szMessage [iStatus], iRep, lTime) ;
  114.  
  115.      WinDrawText (hps, -1, szBuffer, &wrc, DT_CENTER | DT_VCENTER) ;
  116.      WinEndPaint (hps) ;
  117.      }
  118.  
  119. #endif
  120.  
  121. =============================[ End Figure 1 ]=================================
  122.  
  123.  
  124.  
  125. Figure 2 
  126. ========
  127.  
  128.  
  129.  
  130. #-------------------
  131. # BIGJOB1 make file
  132. #-------------------
  133.  
  134. bigjob1.obj : bigjob1.c bigjob.h
  135.      cl -c -FPa -G2sw -W3 -Zp bigjob1.c
  136.  
  137. bigjob.res : bigjob.rc bigjob.h
  138.      rc -r bigjob.rc
  139.  
  140. bigjob1.exe : bigjob1.obj bigjob1.def bigjob.res
  141.      link bigjob1, /align:16, /map, /nod slibc slibcp slibfa os2, bigjob1
  142.      rc bigjob.res bigjob1.exe
  143. unCrunching: <to console> BIGJOB1.C
  144.  
  145. ==============================================================================
  146.  
  147.  
  148. ;------------------------------------
  149. ; BIGJOB1.DEF module definition file
  150. ;------------------------------------
  151.  
  152. NAME           BIGJOB1
  153. DESCRIPTION    'BIGJOB Demo Program No. 1 (C) Charles Petzold, 1988'
  154. HEAPSIZE       1024
  155. STACKSIZE      8192
  156. EXPORTS        ClientWndProc
  157.  
  158.  
  159.  
  160. ==============================================================================
  161.  
  162.  
  163. /*-------------------------------------------------------
  164.    BIGJOB1.C -- Naive approach to lengthy processing job
  165.  --------------------------------------------------------*/
  166.  
  167. #define INCL_WIN
  168.  
  169. #include <os2.h>
  170. #include <math.h>
  171. #include <stdio.h>
  172. #include "bigjob.h"
  173.  
  174. INT main (VOID)
  175.      {
  176.      static CHAR szClassName [] = "BigJob1" ;
  177.      HMQ         hmq ;
  178.      HWND        hwndFrame, hwndClient ;
  179.      QMSG        qmsg ;
  180.  
  181.      hab = WinInitialize (0) ;
  182.      hmq = WinCreateMsgQueue (hab, 0) ;
  183.  
  184.      WinRegisterClass (hab, szClassName, ClientWndProc,
  185.                             CS_SYNCPAINT | CS_SIZEREDRAW, 0, NULL) ;
  186.  
  187.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  188.                     WS_VISIBLE | FS_SIZEBORDER | FS_TITLEBAR
  189.                                | FS_SYSMENU    | FS_MINMAX   | FS_MENU,
  190.                     szClassName, "BIGJOB Demo No. 1",
  191.                     0L, NULL, ID_RESOURCE, &hwndClient) ;
  192.  
  193.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  194.           WinDispatchMsg (hab, &qmsg) ;
  195.  
  196.      WinDestroyWindow (hwndFrame) ;
  197.      WinDestroyMsgQueue (hmq) ;
  198.      WinTerminate (hab) ;
  199.  
  200.      return 0 ;
  201.      }
  202.  
  203. ULONG EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, ULONG mp1,
  204.                                                      ULONG mp2)
  205.      {
  206.      static SHORT iCalcRep, iCurrentRep = IDM_10 ;
  207.      static SHORT iStatus = STATUS_READY ;
  208.      static ULONG lElapsedTime ;
  209.      double       A ;
  210.      SHORT        i ;
  211.  
  212.      switch (msg)
  213.           {
  214.           case WM_COMMAND:
  215.  
  216.                switch (LOUSHORT (mp1))
  217.                     {
  218.                     case IDM_10:
  219.                     case IDM_100:
  220.                     case IDM_1000:
  221.                     case IDM_10000:
  222.                          CheckMenuItem (hwnd, iCurrentRep, FALSE) ;
  223.                          iCurrentRep = LOUSHORT (mp1) ;
  224.                          CheckMenuItem (hwnd, iCurrentRep, TRUE) ;
  225.                          break ;
  226.  
  227.                     case IDM_START:
  228.                          EnableMenuItem (hwnd, IDM_START, FALSE) ;
  229.                          EnableMenuItem (hwnd, IDM_ABORT, TRUE) ;
  230.  
  231.                          iStatus = STATUS_WORKING ;
  232.                          WinInvalidateRect (hwnd, NULL) ;
  233.  
  234.                          iCalcRep = iCurrentRep ;
  235.                          lElapsedTime = WinGetCurrentTime (hab) ;
  236.  
  237.                          for (A = 1.0, i = 0 ; i < iCalcRep ; i++)
  238.                               A = Savage (A) ;
  239.  
  240.                          lElapsedTime = WinGetCurrentTime (hab) -
  241.                                         lElapsedTime ;
  242.  
  243.                          iStatus = STATUS_DONE ;
  244.                          WinInvalidateRect (hwnd, NULL) ;
  245.  
  246.                          EnableMenuItem (hwnd, IDM_START, TRUE) ;
  247.                          EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  248.                          break ;
  249.  
  250.                     case IDM_ABORT:
  251.  
  252.                               /* Not much we can do here */
  253.  
  254.                          break ;
  255.  
  256.                     default:
  257.                          break ;
  258.                     }
  259.                break ;
  260.  
  261.           case WM_PAINT:
  262.                PaintWindow (hwnd, iStatus, iCalcRep, lElapsedTime) ;
  263.                break ;
  264.  
  265.           default:
  266.                return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  267.           }
  268.      return 0L ;
  269.      }
  270.  
  271.  
  272. =============================[ End Figure 2 ]=================================
  273.  
  274.  
  275.  
  276. Figure 3 
  277. ========
  278.  
  279.  
  280.  
  281.  
  282. #-------------------
  283. # BIGJOB2 make file
  284. #-------------------
  285.  
  286. bigjob2.obj : bigjob2.c bigjob.h
  287.      cl -c -FPa -G2sw -W3 -Zp bigjob2.c
  288.  
  289. bigjob.res : bigjob.rc bigjob.h
  290.      rc -r bigjob.rc
  291.  
  292. bigjob2.exe : bigjob2.obj bigjob2.def bigjob.res
  293.      link bigjob2, /align:16, /map, /nod slibc slibcp slibfa os2, bigjob2
  294.      rc bigjob.res bigjob2.exe
  295.  
  296.  
  297. ==============================================================================
  298.  
  299.  
  300. ;------------------------------------
  301. ; BIGJOB2.DEF module definition file
  302. ;------------------------------------
  303.  
  304. NAME           BIGJOB2
  305. DESCRIPTION    'BIGJOB Demo Program No. 2 (C) Charles Petzold, 1988'
  306. HEAPSIZE       1024
  307. STACKSIZE      8192
  308. EXPORTS        ClientWndProc
  309.  
  310.  
  311. ==============================================================================
  312.  
  313.  
  314. /*-------------------------------------------------------
  315.    BIGJOB2.C -- Timer approach to lengthy processing job
  316.  --------------------------------------------------------*/
  317.  
  318. #define INCL_WIN
  319.  
  320. #include <os2.h>
  321. #include <math.h>
  322. #include <stdio.h>
  323. #include "bigjob.h"
  324.  
  325. #define ID_TIMER 1
  326.  
  327. INT main (VOID)
  328.      {
  329.      static CHAR szClassName [] = "BigJob2" ;
  330.      HMQ         hmq ;
  331.      HWND        hwndFrame, hwndClient ;
  332.      QMSG        qmsg ;
  333.  
  334.      hab = WinInitialize (0) ;
  335.      hmq = WinCreateMsgQueue (hab, 0) ;
  336.  
  337.      WinRegisterClass (hab, szClassName, ClientWndProc,
  338.                             CS_SYNCPAINT | CS_SIZEREDRAW, 0, NULL) ;
  339.  
  340.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  341.                     WS_VISIBLE | FS_SIZEBORDER | FS_TITLEBAR
  342.                                | FS_SYSMENU    | FS_MINMAX   | FS_MENU,
  343.                     szClassName, "BigJob Demo No. 2",
  344.                     0L, NULL, ID_RESOURCE, &hwndClient) ;
  345.  
  346.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  347.           WinDispatchMsg (hab, &qmsg) ;
  348.  
  349.      WinDestroyWindow (hwndFrame) ;
  350.      WinDestroyMsgQueue (hmq) ;
  351.      WinTerminate (hab) ;
  352.  
  353.      return 0 ;
  354.      }
  355.  
  356. ULONG EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, ULONG mp1,
  357.                                                      ULONG mp2)
  358.      {
  359.      static double A ;
  360.      static SHORT  i, iCalcRep, iCurrentRep = IDM_10 ;
  361.      static SHORT  iStatus = STATUS_READY ;
  362.      static ULONG  lElapsedTime ;
  363.  
  364.      switch (msg)
  365.           {
  366.           case WM_COMMAND:
  367.  
  368.                switch (LOUSHORT (mp1))
  369.                     {
  370.                     case IDM_10:
  371.                     case IDM_100:
  372.                     case IDM_1000:
  373.                     case IDM_10000:
  374.                          CheckMenuItem (hwnd, iCurrentRep, FALSE) ;
  375.                          iCurrentRep = LOUSHORT (mp1) ;
  376.                          CheckMenuItem (hwnd, iCurrentRep, TRUE) ;
  377.                          break ;
  378.  
  379.                     case IDM_START:
  380.  
  381.                          if (!WinStartTimer (hab, hwnd, ID_TIMER, 1))
  382.                               {
  383.                               WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  384.                               break ;
  385.                               }
  386.  
  387.                          EnableMenuItem (hwnd, IDM_START, FALSE) ;
  388.                          EnableMenuItem (hwnd, IDM_ABORT, TRUE) ;
  389.  
  390.                          iStatus = STATUS_WORKING ;
  391.                          WinInvalidateRect (hwnd, NULL) ;
  392.  
  393.                          iCalcRep = iCurrentRep ;
  394.                          lElapsedTime = WinGetCurrentTime (hab) ;
  395.  
  396.                          A = 1.0 ;
  397.                          i = 0 ;
  398.           
  399.                          break ;
  400.  
  401.                     case IDM_ABORT:
  402.                          WinStopTimer (hab, hwnd, ID_TIMER) ;
  403.  
  404.                          iStatus = STATUS_READY ;
  405.                          WinInvalidateRect (hwnd, NULL) ;
  406.  
  407.                          EnableMenuItem (hwnd, IDM_START, TRUE) ;
  408.                          EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  409.                          break ;
  410.      
  411.                     default:
  412.                          break ;
  413.                     }
  414.                break ;
  415.  
  416.           case WM_TIMER:
  417.  
  418.                A = Savage (A) ;
  419.  
  420.                if (++i == iCalcRep)
  421.                     {
  422.                     lElapsedTime = WinGetCurrentTime (hab) -
  423.                                         lElapsedTime ;
  424.  
  425.                     WinStopTimer (hab, hwnd, ID_TIMER) ;
  426.  
  427.                     iStatus = STATUS_DONE ;
  428.                     WinInvalidateRect (hwnd, NULL) ;
  429.  
  430.                     EnableMenuItem (hwnd, IDM_START, TRUE) ;
  431.                     EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  432.                     }
  433.                break ;
  434.  
  435.           case WM_PAINT:
  436.                PaintWindow (hwnd, iStatus, iCalcRep, lElapsedTime) ;
  437.                break ;
  438.  
  439.           default:
  440.                return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  441.           }
  442.      return 0L ;
  443.      }
  444.  
  445.  
  446. =============================[ End Figure 3 ]=================================
  447.  
  448.  
  449.  
  450.  
  451. Figure 4 
  452. ========
  453.  
  454.  
  455.  
  456. #-------------------
  457. # BIGJOB3 make file
  458. #-------------------
  459.  
  460. bigjob3.obj : bigjob3.c bigjob.h
  461.      cl -c -FPa -G2sw -W3 -Zp bigjob3.c
  462.  
  463. bigjob.res : bigjob.rc bigjob.h
  464.      rc -r bigjob.rc
  465.  
  466. bigjob3.exe : bigjob3.obj bigjob3.def bigjob.res
  467.      link bigjob3, /align:16, /map, /nod slibc slibcp slibfa os2, bigjob3
  468.      rc bigjob.res bigjob3.exe
  469.  
  470.  
  471. ==============================================================================
  472.  
  473.  
  474. ;------------------------------------
  475. ; BIGJOB3.DEF module definition file
  476. ;------------------------------------
  477.  
  478. NAME           BIGJOB3
  479. DESCRIPTION    'BigJob Demo Program No. 3 (C) Charles Petzold, 1988'
  480. HEAPSIZE       1024
  481. STACKSIZE      8192
  482. EXPORTS        ClientWndProc
  483.  
  484.  
  485. ==============================================================================
  486.  
  487.  
  488.  
  489. /*--------------------------------------------------------------
  490.    BIGJOB3.C -- Peek Message approach to lengthy processing job
  491.  ---------------------------------------------------------------*/
  492.  
  493. #define INCL_WIN
  494.  
  495. #include <os2.h>
  496. #include <math.h>
  497. #include <stdio.h>
  498. #include "bigjob.h"
  499.  
  500. INT main (VOID)
  501.      {
  502.      static CHAR szClassName [] = "BigJob3" ;
  503.      HMQ         hmq ;
  504.      HWND        hwndFrame, hwndClient ;
  505.      QMSG        qmsg ;
  506.  
  507.      hab = WinInitialize (0) ;
  508.      hmq = WinCreateMsgQueue (hab, 0) ;
  509.  
  510.      WinRegisterClass (hab, szClassName, ClientWndProc,
  511.                             CS_SIZEREDRAW, 0, NULL) ;
  512.  
  513.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  514.                     WS_VISIBLE | FS_SIZEBORDER | FS_TITLEBAR
  515.                                | FS_SYSMENU    | FS_MINMAX   | FS_MENU,
  516.                     szClassName, "BigJob Demo No. 3",
  517.                     0L, NULL, ID_RESOURCE, &hwndClient) ;
  518.  
  519.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  520.           WinDispatchMsg (hab, &qmsg) ;
  521.  
  522.      WinDestroyWindow (hwndFrame) ;
  523.      WinDestroyMsgQueue (hmq) ;
  524.      WinTerminate (hab) ;
  525.  
  526.      return 0 ;
  527.      }
  528.     
  529. ULONG EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, ULONG mp1,
  530.                                                      ULONG mp2)
  531.      {
  532.      static BOOL   bContinueCalc = FALSE ;
  533.      static SHORT  iStatus = STATUS_READY ;
  534.      static SHORT  iCalcRep, iCurrentRep = IDM_10 ;
  535.      static ULONG  lElapsedTime ;
  536.      double        A ;
  537.      SHORT         i ;
  538.      QMSG          qmsg ;
  539.  
  540.      switch (msg)
  541.           {
  542.           case WM_COMMAND:
  543.  
  544.                switch (LOUSHORT (mp1))
  545.                     {
  546.                     case IDM_10:
  547.                     case IDM_100:
  548.                     case IDM_1000:
  549.                     case IDM_10000:
  550.                          CheckMenuItem (hwnd, iCurrentRep, FALSE) ;
  551.                          iCurrentRep = LOUSHORT (mp1) ;
  552.                          CheckMenuItem (hwnd, iCurrentRep, TRUE) ;
  553.                          break ;
  554.  
  555.                     case IDM_START:
  556.                          EnableMenuItem (hwnd, IDM_START, FALSE) ;
  557.                          EnableMenuItem (hwnd, IDM_ABORT, TRUE) ;
  558.  
  559.                          iStatus = STATUS_WORKING ;
  560.                          WinInvalidateRect (hwnd, NULL) ;
  561.  
  562.                          iCalcRep = iCurrentRep ;
  563.                          bContinueCalc = TRUE ;
  564.                          lElapsedTime = WinGetCurrentTime (hab) ;
  565.  
  566.                          qmsg.msg = WM_NULL ;
  567.  
  568.                          for (A = 1.0, i = 0 ; i < iCalcRep ; i++)
  569.                               {
  570.                               A = Savage (A) ;
  571.  
  572.                               while (WinPeekMsg (hab, &qmsg, NULL, 0, 0,
  573.                                                   PM_NOREMOVE))
  574.                                    {
  575.                                    if (qmsg.msg == WM_QUIT)
  576.                                         break ;
  577.  
  578.                                    WinGetMsg (hab, &qmsg, NULL, 0, 0) ;
  579.                                    WinDispatchMsg (hab, &qmsg) ;
  580.  
  581.                                    if (!bContinueCalc)
  582.                                         break ;
  583.                                    }
  584.  
  585.                               if (!bContinueCalc || qmsg.msg == WM_QUIT)
  586.                                    break ;
  587.                               }
  588.                          lElapsedTime = WinGetCurrentTime (hab) - 
  589.                                                   lElapsedTime ;
  590.  
  591.                          if (!bContinueCalc || qmsg.msg == WM_QUIT)
  592.                               iStatus = STATUS_READY ;
  593.                          else
  594.                               iStatus = STATUS_DONE ;
  595.  
  596.                          WinInvalidateRect (hwnd, NULL) ;
  597.  
  598.                          EnableMenuItem (hwnd, IDM_START, TRUE) ;
  599.                          EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  600.                          break ;
  601.  
  602.                     case IDM_ABORT:
  603.                          bContinueCalc = FALSE ;
  604.                          break ;
  605.      
  606.                     default:
  607.                          break ;
  608.                     }
  609.                break ;
  610.  
  611.           case WM_PAINT:
  612.                PaintWindow (hwnd, iStatus, iCalcRep, lElapsedTime) ;
  613.                break ;
  614.  
  615.           default:
  616.                return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  617.           }
  618.      return 0L ;
  619.      }
  620.  
  621.  
  622. =============================[ End Figure 4 ]=================================
  623.  
  624.  
  625.  
  626.  
  627. Figure 5 
  628. ========
  629.  
  630.  
  631.  
  632.  
  633. #-------------------
  634. # BIGJOB4 make file
  635. #-------------------
  636.  
  637. bigjob4.obj : bigjob4.c bigjob.h
  638.      cl -c -FPa -G2sw -W3 -Zp bigjob4.c
  639.  
  640. bigjob.res : bigjob.rc bigjob.h
  641.      rc -r bigjob.rc
  642.  
  643. bigjob4.exe : bigjob4.obj bigjob4.def bigjob.res
  644.      link bigjob4, /align:16, /map, /nod slibc slibcp slibfa os2, bigjob4
  645.      rc bigjob.res bigjob4.exe
  646.  
  647.  
  648. ==============================================================================
  649.  
  650.  
  651. ;------------------------------------
  652. ; BIGJOB4.DEF module definition file
  653. ;------------------------------------
  654.  
  655. NAME           BIGJOB4
  656. DESCRIPTION    'BigJob Demo Program No. 4 (C) Charles Petzold, 1988'
  657. HEAPSIZE       1024
  658. STACKSIZE      8192
  659. EXPORTS        ClientWndProc
  660.  
  661.  
  662. ==============================================================================
  663.  
  664.  
  665.  
  666. /*---------------------------------------------------------------
  667.    BIGJOB4.C -- Second thread approach to lengthy processing job
  668.  ----------------------------------------------------------------*/
  669.  
  670. #define INCL_WIN
  671. #define INCL_DOS
  672.  
  673. #include <os2.h>
  674. #include <math.h>
  675. #include <stdio.h>
  676. #include "bigjob.h"
  677.  
  678. #define WM_CALC_DONE     (WM_USER + 0)
  679. #define WM_CALC_ABORTED  (WM_USER + 1) 
  680.  
  681. VOID FAR SecondThread (VOID) ;
  682.  
  683. BOOL  bContinueCalc = FALSE ;
  684. HWND  hwndClient ;
  685. SHORT iCalcRep ;
  686. LONG  lSemTrigger ;
  687. TID   idThread ;
  688. UCHAR cThreadStack [4096] ;
  689.  
  690. INT main (VOID)
  691.      {
  692.      static CHAR szClassName [] = "BigJob4" ;
  693.      HMQ         hmq ;
  694.      HWND        hwndFrame ;
  695.      QMSG        qmsg ;
  696.  
  697.      hab = WinInitialize (0) ;
  698.      hmq = WinCreateMsgQueue (hab, 0) ;
  699.  
  700.      WinRegisterClass (hab, szClassName, ClientWndProc,
  701.                             CS_SIZEREDRAW, 0, NULL) ;
  702.  
  703.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  704.                     WS_VISIBLE | FS_SIZEBORDER | FS_TITLEBAR
  705.                                | FS_SYSMENU    | FS_MINMAX   | FS_MENU,
  706.                     szClassName, "BigJob Demo No. 4",
  707.                     0L, NULL, ID_RESOURCE, &hwndClient) ;
  708.  
  709.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  710.           WinDispatchMsg (hab, &qmsg) ;
  711.  
  712.      DosSuspendThread (idThread) ;
  713.  
  714.      WinDestroyWindow (hwndFrame) ;
  715.      WinDestroyMsgQueue (hmq) ;
  716.      WinTerminate (hab) ;
  717.  
  718.      return 0 ;
  719.      }
  720.     
  721. ULONG EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, ULONG mp1,
  722.                                                      ULONG mp2)
  723.      {
  724.      static SHORT iCurrentRep = IDM_10 ;
  725.      static SHORT iStatus = STATUS_READY ;
  726.      static ULONG lElapsedTime ;
  727.  
  728.      switch (msg)
  729.           {
  730.           case WM_CREATE:
  731.  
  732.                DosSemSet (&lSemTrigger) ;
  733.  
  734.                if (DosCreateThread (SecondThread, &idThread,
  735.                                     cThreadStack + sizeof cThreadStack))
  736.  
  737.                     WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  738.  
  739.                break ;
  740.  
  741.           case WM_COMMAND:
  742.  
  743.                switch (LOUSHORT (mp1))
  744.                     {
  745.                     case IDM_10:
  746.                     case IDM_100:
  747.                     case IDM_1000:
  748.                     case IDM_10000:
  749.                          CheckMenuItem (hwnd, iCurrentRep, FALSE) ;
  750.                          iCurrentRep = LOUSHORT (mp1) ;
  751.                          CheckMenuItem (hwnd, iCurrentRep, TRUE) ;
  752.                          break ;
  753.  
  754.                     case IDM_START:
  755.                          iStatus = STATUS_WORKING ;
  756.                          WinInvalidateRect (hwnd, NULL) ;
  757.  
  758.                          iCalcRep = iCurrentRep ;
  759.                          bContinueCalc = TRUE ;
  760.                          DosSemClear (&lSemTrigger) ;
  761.           
  762.                          EnableMenuItem (hwnd, IDM_START, FALSE) ;
  763.                          EnableMenuItem (hwnd, IDM_ABORT, TRUE) ;
  764.                          break ;
  765.  
  766.                     case IDM_ABORT:
  767.                          bContinueCalc = FALSE ;
  768.  
  769.                          EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  770.                          break ;
  771.      
  772.                     default:
  773.                          break ;
  774.                     }
  775.                break ;
  776.  
  777.           case WM_CALC_DONE:
  778.  
  779.                iStatus = STATUS_DONE ;
  780.                lElapsedTime = mp1 ;
  781.                WinInvalidateRect (hwnd, NULL) ;
  782.  
  783.                EnableMenuItem (hwnd, IDM_START, TRUE) ;
  784.                EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  785.                break ;
  786.  
  787.           case WM_CALC_ABORTED:
  788.  
  789.                iStatus = STATUS_READY ;
  790.                WinInvalidateRect (hwnd, NULL) ;
  791.  
  792.                EnableMenuItem (hwnd, IDM_START, TRUE) ;
  793.                break ;
  794.  
  795.           case WM_PAINT:
  796.                PaintWindow (hwnd, iStatus, iCalcRep, lElapsedTime) ;
  797.                break ;
  798.  
  799.           default:
  800.                return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  801.           }
  802.      return 0L ;
  803.      }
  804.  
  805. VOID FAR SecondThread ()
  806.      {
  807.      double A ;
  808.      int    i ;
  809.      LONG   lTime ;
  810.      
  811.      while (1)
  812.           {
  813.           DosSemWait (&lSemTrigger, -1L) ;
  814.  
  815.           lTime = WinGetCurrentTime (hab) ;
  816.  
  817.           for (A = 1.0, i = 0 ; i < iCalcRep ; i++)
  818.                {
  819.                if (!bContinueCalc)
  820.                     break ;
  821.  
  822.                A = Savage (A) ;
  823.                }
  824.  
  825.           lTime = WinGetCurrentTime (hab) - lTime ;
  826.           
  827.           DosSemSet (&lSemTrigger) ;
  828.  
  829.           if (bContinueCalc)
  830.                WinPostMsg (hwndClient, WM_CALC_DONE, lTime, 0L) ;
  831.           else
  832.                WinPostMsg (hwndClient, WM_CALC_ABORTED, 0L, 0L) ;     
  833.           }
  834.      }
  835.  
  836.  
  837. =============================[ End Figure 5 ]=================================
  838.  
  839.  
  840.  
  841.  
  842. Figure 6
  843. ========
  844.  
  845.  
  846.  
  847. #-------------------
  848. # BIGJOB5 make file
  849. #-------------------
  850.  
  851. bigjob5.obj : bigjob5.c bigjob.h
  852.      cl -c -FPa -G2sw -W3 -Zp bigjob5.c
  853.  
  854. bigjob.res : bigjob.rc bigjob.h
  855.      rc -r bigjob.rc
  856.  
  857. bigjob5.exe : bigjob5.obj bigjob5.def bigjob.res
  858.      link bigjob5, /align:16, /map, /nod slibc slibcp slibfa os2, bigjob5
  859.      rc bigjob.res bigjob5.exe
  860.  
  861.  
  862. ==============================================================================
  863.  
  864.  
  865. ;------------------------------------
  866. ; BIGJOB5.DEF module definition file
  867. ;------------------------------------
  868.  
  869. NAME           BIGJOB5
  870. DESCRIPTION    'BigJob Demo Program No. 5 (C) Charles Petzold, 1988'
  871. HEAPSIZE       1024
  872. STACKSIZE      8192
  873. EXPORTS        ClientWndProc
  874.                ObjectWndProc
  875.  
  876.  
  877.  
  878. ==============================================================================
  879.  
  880.  
  881.  
  882.  
  883. /*---------------------------------------------------------------
  884.    BIGJOB5.C -- Object window approach to lengthy processing job
  885.  ----------------------------------------------------------------*/
  886.  
  887. #define INCL_WIN
  888. #define INCL_DOS
  889.  
  890. #include <os2.h>
  891. #include <math.h>
  892. #include <stdio.h>
  893. #include "bigjob.h"
  894.  
  895. #define WM_OBJECT_CREATED     (WM_USER + 0)
  896. #define WM_START_CALC         (WM_USER + 1)
  897. #define WM_ABORT_CALC         (WM_USER + 2)
  898. #define WM_CALC_DONE          (WM_USER + 3)
  899. #define WM_CALC_ABORTED       (WM_USER + 4)
  900. #define WM_OBJECT_DESTROYED   (WM_USER + 5)
  901.  
  902. VOID  FAR SecondThread (VOID) ;
  903. ULONG EXPENTRY ObjectWndProc (HWND, USHORT, ULONG, ULONG) ;
  904.  
  905. HWND  hwndClient, hwndObject ;
  906. UCHAR cThreadStack [8192] ;
  907.  
  908. INT main (VOID)
  909.      {
  910.      static CHAR szClassName [] = "BigJob5" ;
  911.      HMQ         hmq ;
  912.      HWND        hwndFrame ;
  913.      QMSG        qmsg ;
  914.      TID         idThread ;
  915.  
  916.      hab = WinInitialize (0) ;
  917.      hmq = WinCreateMsgQueue (hab, 0) ;
  918.  
  919.      WinRegisterClass (hab, szClassName, ClientWndProc,
  920.                             CS_SIZEREDRAW, 0, NULL) ;
  921.  
  922.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  923.                     WS_VISIBLE | FS_SIZEBORDER | FS_TITLEBAR
  924.                                | FS_SYSMENU    | FS_MINMAX   | FS_MENU,
  925.                     szClassName, "BigJob Demo No. 5",
  926.                     0L, NULL, ID_RESOURCE, &hwndClient) ;
  927.  
  928.      EnableMenuItem (hwndClient, IDM_START, FALSE) ;
  929.  
  930.      if (DosCreateThread (SecondThread, &idThread,
  931.                           cThreadStack + sizeof cThreadStack))
  932.  
  933.           WinAlarm (HWND_DESKTOP, WA_ERROR) ;
  934.  
  935.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  936.           WinDispatchMsg (hab, &qmsg) ;
  937.  
  938.      WinDestroyWindow (hwndFrame) ;
  939.      WinDestroyMsgQueue (hmq) ;
  940.      WinTerminate (hab) ;
  941.  
  942.      return 0 ;
  943.      }
  944.  
  945. ULONG EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, ULONG mp1,
  946.                                                      ULONG mp2)
  947.      {
  948.      static SHORT iCalcRep, iCurrentRep = IDM_10 ;
  949.      static SHORT iStatus = STATUS_READY ;
  950.      static ULONG lElapsedTime ;
  951.  
  952.      switch (msg)
  953.           {
  954.           case WM_OBJECT_CREATED:
  955.  
  956.                EnableMenuItem (hwnd, IDM_START, TRUE) ;
  957.                break ;
  958.  
  959.           case WM_COMMAND:
  960.  
  961.                switch (LOUSHORT (mp1))
  962.                     {
  963.                     case IDM_10:
  964.                     case IDM_100:
  965.                     case IDM_1000:
  966.                     case IDM_10000:
  967.                          CheckMenuItem (hwnd, iCurrentRep, FALSE) ;
  968.                          iCurrentRep = LOUSHORT (mp1) ;
  969.                          CheckMenuItem (hwnd, iCurrentRep, TRUE) ;
  970.                          break ;
  971.  
  972.                     case IDM_START:
  973.                          EnableMenuItem (hwnd, IDM_START, FALSE) ;
  974.                          EnableMenuItem (hwnd, IDM_ABORT, TRUE) ;
  975.  
  976.                          iStatus = STATUS_WORKING ;
  977.                          WinInvalidateRect (hwnd, NULL) ;
  978.  
  979.                          iCalcRep = iCurrentRep ;
  980.                          WinPostMsg (hwndObject, WM_START_CALC,
  981.                                    MAKEULONG (iCalcRep, 0), 0L) ;
  982.                          break ;
  983.  
  984.                     case IDM_ABORT:
  985.                          WinPostMsg (hwndObject, WM_ABORT_CALC,
  986.                                                  0L, 0L) ;
  987.  
  988.                          EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  989.                          break ;
  990.      
  991.                     default:
  992.                          break ;
  993.                     }
  994.                break ;
  995.  
  996.           case WM_CALC_DONE:
  997.  
  998.                iStatus = STATUS_DONE ;
  999.                lElapsedTime = mp1 ;
  1000.                WinInvalidateRect (hwnd, NULL) ;
  1001.  
  1002.                EnableMenuItem (hwnd, IDM_START, TRUE) ;
  1003.                EnableMenuItem (hwnd, IDM_ABORT, FALSE) ;
  1004.                break ;
  1005.  
  1006.           case WM_CALC_ABORTED:
  1007.  
  1008.                iStatus = STATUS_READY ;
  1009.                WinInvalidateRect (hwnd, NULL) ;
  1010.  
  1011.                EnableMenuItem (hwnd, IDM_START, TRUE) ;
  1012.                break ;
  1013.  
  1014.           case WM_PAINT:
  1015.  
  1016.                PaintWindow (hwnd, iStatus, iCalcRep, lElapsedTime) ;
  1017.                break ;
  1018.  
  1019.           case WM_CLOSE:
  1020.  
  1021.                if (hwndObject)
  1022.                     WinPostMsg (hwndObject, WM_QUIT, 0L, 0L) ;
  1023.                else
  1024.                     WinPostMsg (hwnd, WM_QUIT, 0L, 0L) ;
  1025.                break ;
  1026.  
  1027.           case WM_OBJECT_DESTROYED:
  1028.  
  1029.                WinPostMsg (hwnd, WM_QUIT, 0L, 0L) ;
  1030.                break ;
  1031.  
  1032.           default:
  1033.                return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  1034.           }
  1035.      return 0L ;
  1036.      }
  1037.  
  1038. VOID FAR SecondThread ()
  1039.      {
  1040.      static CHAR szClassName [] = "BigJob5.Object" ;
  1041.      HMQ         hmq ;
  1042.      QMSG        qmsg ;
  1043.  
  1044.      hmq = WinCreateMsgQueue (hab, 0) ;
  1045.  
  1046.      WinRegisterClass (hab, szClassName, ObjectWndProc, 0L, 0, NULL) ;
  1047.  
  1048.      hwndObject = WinCreateWindow (HWND_OBJECT, szClassName,
  1049.                     NULL, 0L, 0, 0, 0, 0, NULL, NULL, 0, NULL, NULL) ;
  1050.  
  1051.      WinPostMsg (hwndClient, WM_OBJECT_CREATED, 0L, 0L) ;
  1052.  
  1053.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  1054.           WinDispatchMsg (hab, &qmsg) ;
  1055.  
  1056.      WinDestroyWindow (hwndObject) ;
  1057.      WinDestroyMsgQueue (hmq) ;
  1058.  
  1059.      WinPostMsg (hwndClient, WM_OBJECT_DESTROYED, 0L, 0L) ;
  1060.  
  1061.      DosExit (0, 0) ;
  1062.      }
  1063.  
  1064. ULONG EXPENTRY ObjectWndProc (HWND hwnd, USHORT msg, ULONG mp1,
  1065.                                                      ULONG mp2)
  1066.      {
  1067.      double A ;
  1068.      SHORT  i, iCalcRep ;
  1069.      LONG   lQueueStatus, lTime ;
  1070.  
  1071.      switch (msg)
  1072.           {
  1073.           case WM_START_CALC:
  1074.  
  1075.                iCalcRep = LOUSHORT (mp1) ;
  1076.                lTime = WinGetCurrentTime (hab) ;
  1077.  
  1078.                for (A = 1.0, i = 0 ; i < iCalcRep ; i++)
  1079.                     {
  1080.                     lQueueStatus = WinQueryQueueStatus (HWND_DESKTOP) ;
  1081.  
  1082.                     if (lQueueStatus & QS_POSTMSG)
  1083.                          break ;
  1084.  
  1085.                     A = Savage (A) ;
  1086.                     }
  1087.  
  1088.                if (lQueueStatus & QS_POSTMSG)
  1089.                     break ;
  1090.  
  1091.                lTime = WinGetCurrentTime (hab) - lTime ;
  1092.  
  1093.                WinPostMsg (hwndClient, WM_CALC_DONE, lTime, 0L) ;
  1094.                break ;
  1095.  
  1096.           case WM_ABORT_CALC:
  1097.  
  1098.                WinPostMsg (hwndClient, WM_CALC_ABORTED, 0L, 0L) ;
  1099.                break ;
  1100.  
  1101.           default:
  1102.                return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  1103.           }
  1104.      return 0L ;
  1105.      }
  1106.  
  1107.  
  1108. =============================[ End Figure 6 ]=================================
  1109.