home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP14 / MULTI2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  10.9 KB  |  384 lines

  1. /*---------------------------------------
  2.    MULTI2.C -- Multitasking Demo
  3.                (c) Charles Petzold, 1996
  4.   ---------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <process.h>
  11.  
  12. typedef struct
  13.      {
  14.      HWND hwnd ;
  15.      int  cxClient ;
  16.      int  cyClient ;
  17.      int  cyChar ;
  18.      BOOL bKill ;
  19.      }
  20.      PARAMS, *PPARAMS ;
  21.  
  22. LRESULT APIENTRY WndProc (HWND, UINT, WPARAM, LPARAM) ;
  23.  
  24. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  25.                     PSTR szCmdLine, int iCmdShow)
  26.      {
  27.      static char szAppName[] = "Multi2" ;
  28.      HWND        hwnd ;
  29.      MSG         msg ;
  30.      WNDCLASSEX  wndclass ;
  31.  
  32.      wndclass.cbSize        = sizeof (wndclass) ;
  33.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  34.      wndclass.lpfnWndProc   = WndProc ;
  35.      wndclass.cbClsExtra    = 0 ;
  36.      wndclass.cbWndExtra    = 0 ;
  37.      wndclass.hInstance     = hInstance ;
  38.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  39.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  40.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  41.      wndclass.lpszMenuName  = NULL ;
  42.      wndclass.lpszClassName = szAppName ;
  43.      wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;
  44.  
  45.      RegisterClassEx (&wndclass) ;
  46.  
  47.      hwnd = CreateWindow (szAppName, "Multitasking Demo",
  48.                           WS_OVERLAPPEDWINDOW,
  49.                           CW_USEDEFAULT, CW_USEDEFAULT,
  50.                           CW_USEDEFAULT, CW_USEDEFAULT,
  51.                           NULL, NULL, hInstance, NULL) ;
  52.  
  53.      ShowWindow (hwnd, iCmdShow) ;
  54.      UpdateWindow (hwnd) ;
  55.  
  56.      while (GetMessage (&msg, NULL, 0, 0))
  57.           {
  58.           TranslateMessage (&msg) ;
  59.           DispatchMessage (&msg) ;
  60.           }
  61.      return msg.wParam ;
  62.      }
  63.  
  64. int CheckBottom (HWND hwnd, int cyClient, int cyChar, int iLine)
  65.      {
  66.      if (iLine * cyChar + cyChar > cyClient)
  67.           {
  68.           InvalidateRect (hwnd, NULL, TRUE) ;
  69.           UpdateWindow (hwnd) ;
  70.           iLine = 0 ;
  71.           }
  72.      return iLine ;
  73.      }
  74.  
  75. // Window 1: Display increasing sequence of numbers
  76. // ------------------------------------------------
  77.  
  78. void Thread1 (PVOID pvoid)
  79.      {
  80.      int     iNum = 0, iLine = 0 ;
  81.      char    szBuffer[16] ;
  82.      HDC     hdc ;
  83.      PPARAMS pparams ;
  84.  
  85.      pparams = (PPARAMS) pvoid ;
  86.  
  87.      while (!pparams->bKill)
  88.           {
  89.           if (iNum < 0)
  90.                iNum = 0 ;
  91.  
  92.           iLine = CheckBottom (pparams->hwnd,   pparams->cyClient,
  93.                                pparams->cyChar, iLine) ;
  94.  
  95.           wsprintf (szBuffer, "%d", iNum++) ;
  96.  
  97.           hdc = GetDC (pparams->hwnd) ;
  98.  
  99.           TextOut (hdc, 0, iLine * pparams->cyChar,
  100.                    szBuffer, strlen (szBuffer)) ;
  101.  
  102.           ReleaseDC (pparams->hwnd, hdc) ;
  103.  
  104.           iLine++ ;
  105.           }
  106.      _endthread () ;
  107.      }
  108.  
  109. LRESULT APIENTRY WndProc1 (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  110.      {
  111.      static PARAMS params ;
  112.  
  113.      switch (iMsg)
  114.           {
  115.           case WM_CREATE :
  116.                params.hwnd = hwnd ;
  117.                params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
  118.                _beginthread (Thread1, 0, ¶ms) ;
  119.                return 0 ;
  120.  
  121.           case WM_SIZE :
  122.                params.cyClient = HIWORD (lParam) ;
  123.                return 0 ;
  124.  
  125.           case WM_DESTROY :
  126.                params.bKill = TRUE ;
  127.                return 0 ;
  128.           }
  129.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  130.      }
  131.  
  132. // Window 2: Display increasing sequence of prime numbers
  133. // ------------------------------------------------------
  134.  
  135. void Thread2 (PVOID pvoid)
  136.      {
  137.      char    szBuffer[16] ;
  138.      int     iNum = 1, iLine = 0, i, iSqrt ;
  139.      HDC     hdc ;
  140.      PPARAMS pparams ;
  141.  
  142.      pparams = (PPARAMS) pvoid ;
  143.  
  144.      while (!pparams->bKill)
  145.           {
  146.           do
  147.                {
  148.                if (++iNum < 0)
  149.                     iNum = 0 ;
  150.  
  151.                iSqrt = (int) sqrt (iNum) ;
  152.  
  153.                for (i = 2 ; i <= iSqrt ; i++)
  154.                     if (iNum % i == 0)
  155.                          break ;
  156.                }
  157.           while (i <= iSqrt) ;
  158.  
  159.           iLine = CheckBottom (pparams->hwnd,   pparams->cyClient,
  160.                                pparams->cyChar, iLine) ;
  161.  
  162.           wsprintf (szBuffer, "%d", iNum) ;
  163.  
  164.           hdc = GetDC (pparams->hwnd) ;
  165.  
  166.           TextOut (hdc, 0, iLine * pparams->cyChar,
  167.                    szBuffer, strlen (szBuffer)) ;
  168.  
  169.           ReleaseDC (pparams->hwnd, hdc) ;
  170.  
  171.           iLine++ ;
  172.           }
  173.      _endthread () ;
  174.      }
  175.  
  176. LRESULT APIENTRY WndProc2 (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  177.      {
  178.      static PARAMS params ;
  179.  
  180.      switch (iMsg)
  181.           {
  182.           case WM_CREATE :
  183.                params.hwnd = hwnd ;
  184.                params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
  185.                _beginthread (Thread2, 0, ¶ms) ;
  186.                return 0 ;
  187.  
  188.           case WM_SIZE :
  189.                params.cyClient = HIWORD (lParam) ;
  190.                return 0 ;
  191.  
  192.           case WM_DESTROY :
  193.                params.bKill = TRUE ;
  194.                return 0 ;
  195.           }
  196.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  197.      }
  198.  
  199. // Window 3: Display increasing sequence of Fibonacci numbers
  200. // ----------------------------------------------------------
  201.  
  202. void Thread3 (PVOID pvoid)
  203.      {
  204.      char    szBuffer[16] ;
  205.      int     iNum = 0, iNext = 1, iLine = 0, iTemp ;
  206.      HDC     hdc ;
  207.      PPARAMS pparams ;
  208.  
  209.      pparams = (PPARAMS) pvoid ;
  210.  
  211.      while (!pparams->bKill)
  212.           {
  213.           if (iNum < 0)
  214.                {
  215.                iNum  = 0 ;
  216.                iNext = 1 ;
  217.                }
  218.  
  219.           iLine = CheckBottom (pparams->hwnd,   pparams->cyClient,
  220.                                pparams->cyChar, iLine) ;
  221.  
  222.           wsprintf (szBuffer, "%d", iNum) ;
  223.  
  224.           hdc = GetDC (pparams->hwnd) ;
  225.  
  226.           TextOut (hdc, 0, iLine * pparams->cyChar,
  227.                    szBuffer, strlen (szBuffer)) ;
  228.  
  229.           ReleaseDC (pparams->hwnd, hdc) ;
  230.  
  231.           iTemp  = iNum ;
  232.           iNum   = iNext ;
  233.           iNext += iTemp ;
  234.  
  235.           iLine++ ;
  236.           }
  237.      _endthread () ;
  238.      }
  239.  
  240. LRESULT APIENTRY WndProc3 (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  241.      {
  242.      static PARAMS params ;
  243.  
  244.      switch (iMsg)
  245.           {
  246.           case WM_CREATE :
  247.                params.hwnd = hwnd ;
  248.                params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
  249.                _beginthread (Thread3, 0, ¶ms) ;
  250.                return 0 ;
  251.  
  252.           case WM_SIZE :
  253.                params.cyClient = HIWORD (lParam) ;
  254.                return 0 ;
  255.  
  256.           case WM_DESTROY :
  257.                params.bKill = TRUE ;
  258.                return 0 ;
  259.           }
  260.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  261.      }
  262.  
  263. // Window 4: Display circles of random radii
  264. // -----------------------------------------
  265.  
  266. void Thread4 (PVOID pvoid)
  267.      {
  268.      HDC     hdc ;
  269.      int     iDiameter ;
  270.      PPARAMS pparams ;
  271.  
  272.      pparams = (PPARAMS) pvoid ;
  273.  
  274.      while (!pparams->bKill)
  275.           {
  276.           InvalidateRect (pparams->hwnd, NULL, TRUE) ;
  277.           UpdateWindow (pparams->hwnd) ;
  278.  
  279.           iDiameter = rand() % (max (1,
  280.                                 min (pparams->cxClient, pparams->cyClient))) ;
  281.  
  282.           hdc = GetDC (pparams->hwnd) ;
  283.  
  284.           Ellipse (hdc, (pparams->cxClient - iDiameter) / 2,
  285.                         (pparams->cyClient - iDiameter) / 2,
  286.                         (pparams->cxClient + iDiameter) / 2,
  287.                         (pparams->cyClient + iDiameter) / 2) ;
  288.  
  289.           ReleaseDC (pparams->hwnd, hdc) ;
  290.           }
  291.      _endthread () ;
  292.      }
  293.  
  294. LRESULT APIENTRY WndProc4 (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  295.      {
  296.      static PARAMS params ;
  297.  
  298.      switch (iMsg)
  299.           {
  300.           case WM_CREATE :
  301.                params.hwnd = hwnd ;
  302.                params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
  303.                _beginthread (Thread4, 0, ¶ms) ;
  304.                return 0 ;
  305.  
  306.           case WM_SIZE :
  307.                params.cxClient = LOWORD (lParam) ;
  308.                params.cyClient = HIWORD (lParam) ;
  309.                return 0 ;
  310.  
  311.           case WM_DESTROY :
  312.                params.bKill = TRUE ;
  313.                return 0 ;
  314.           }
  315.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  316.      }
  317.  
  318. // Main window to create child windows
  319. // -----------------------------------
  320.  
  321. LRESULT APIENTRY WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  322.      {
  323.      static char   *szChildClass[] = { "Child1", "Child2",
  324.                                        "Child3", "Child4" } ;
  325.      static HWND    hwndChild[4] ;
  326.      static WNDPROC ChildProc[] = { WndProc1, WndProc2,
  327.                                     WndProc3, WndProc4 } ;
  328.      HINSTANCE      hInstance ;
  329.      int            i, cxClient, cyClient ;
  330.      WNDCLASSEX     wndclass ;
  331.  
  332.      switch (iMsg)
  333.           {
  334.           case WM_CREATE :
  335.                hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ;
  336.  
  337.                wndclass.cbSize        = sizeof (wndclass) ;
  338.                wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  339.                wndclass.cbClsExtra    = 0 ;
  340.                wndclass.cbWndExtra    = 0 ;
  341.                wndclass.hInstance     = hInstance ;
  342.                wndclass.hIcon         = NULL ;
  343.                wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  344.                wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  345.                wndclass.lpszMenuName  = NULL ;
  346.                wndclass.hIconSm       = NULL ;
  347.  
  348.                for (i = 0 ; i < 4 ; i++)
  349.                     {
  350.                     wndclass.lpfnWndProc   = ChildProc[i] ;
  351.                     wndclass.lpszClassName = szChildClass[i] ;
  352.  
  353.                     RegisterClassEx (&wndclass) ;
  354.  
  355.                     hwndChild[i] = CreateWindow (szChildClass[i], NULL,
  356.                           WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE,
  357.                           0, 0, 0, 0, hwnd, (HMENU) i, hInstance, NULL) ;
  358.                     }
  359.  
  360.                return 0 ;
  361.  
  362.           case WM_SIZE :
  363.                cxClient = LOWORD (lParam) ;
  364.                cyClient = HIWORD (lParam) ;
  365.  
  366.                for (i = 0 ; i < 4 ; i++)
  367.                     MoveWindow (hwndChild[i], (i % 2) * cxClient / 2,
  368.                                               (i > 1) * cyClient / 2,
  369.                                 cxClient / 2, cyClient / 2, TRUE) ;
  370.                return 0 ;
  371.  
  372.           case WM_CHAR :
  373.                if (wParam == '\x1B')
  374.                     DestroyWindow (hwnd) ;
  375.  
  376.                return 0 ;
  377.  
  378.           case WM_DESTROY :
  379.                PostQuitMessage (0) ;
  380.                return 0 ;
  381.           }
  382.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  383.      }
  384.