home *** CD-ROM | disk | FTP | other *** search
/ ftp.disi.unige.it / 2015-02-11.ftp.disi.unige.it.tar / ftp.disi.unige.it / pub / .person / GianuzziV / SO1 / letters.cpp < prev    next >
C/C++ Source or Header  |  2001-11-11  |  4KB  |  140 lines

  1. /* File:  letters.cpp    illustrates multiple threads using functions:
  2.  *
  3.  *      _beginthread            _endthread
  4.  *
  5.  * presa dalla libreria Visual C++
  6.  * da eseguire come Applicazione Console, con MFC
  7.  *
  8.  */
  9.  
  10. #include "stdafx.h"
  11. #include "thread1.h"
  12.  
  13. #include <windows.h>
  14. #include <process.h>    /* _beginthread, _endthread */
  15. #include <stddef.h>
  16. #include <stdlib.h>
  17. #include <conio.h>
  18.  
  19. void Bounce( void *ch );
  20. void CheckKey( void *dummy );
  21.  
  22. /* GetRandom returns a random integer between min and max. */
  23. #define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) +
  24. (min))
  25.  
  26. BOOL repeat = TRUE;     /* Global repeat flag and video variable */
  27. HANDLE hStdOut;           /* Handle for console window */
  28. CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */
  29. CHAR    ch = 'A';
  30.  
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37. CWinApp theApp;
  38. using namespace std;
  39.  
  40. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  41. {
  42.  int nRetCode = 0;
  43.  
  44.  // initialize MFC and print and error on failure
  45.  if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  46.  {
  47.   cerr << _T("Fatal Error: MFC initialization failed") << endl;
  48.   nRetCode = 1;
  49.  }
  50.  else
  51.  {
  52.     hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
  53.  
  54.     /* Get display screen's text row and column information. */
  55.    GetConsoleScreenBufferInfo( hStdOut, &csbi );
  56.  
  57.  
  58.     /* Launch CheckKey thread to check for terminating keystroke. */
  59.     _beginthread( CheckKey, 0, NULL );
  60.  
  61.     /* Loop until CheckKey terminates program. */
  62.     while( repeat )
  63.     {
  64.         /* On first loops, launch character threads. */
  65.         _beginthread( Bounce, 0, (void *) (ch++)  );
  66.  
  67.         /* Wait one second between loops. */
  68.         Sleep( 1000L );
  69.     }
  70. }
  71.  return nRetCode;
  72. }
  73. /* CheckKey - Thread to wait for a keystroke, then clear repeat flag. */
  74. void CheckKey( void *dummy )
  75. {
  76.     _getch();
  77.     repeat = 0;    /* _endthread implied */
  78.  
  79. }
  80.  
  81. /* Bounce - Thread to create and and control a colored letter that moves
  82.  * around on the screen.
  83.  *
  84.  * Params: ch - the letter to be moved
  85.  */
  86. void Bounce( void *ch )
  87. {
  88.     /* Generate letter and color attribute from thread argument. */
  89.     char    blankcell = 0x20;
  90.     char    blockcell = (char) ch;
  91.     BOOL    first = TRUE;
  92.     COORD   oldcoord, newcoord;
  93.     DWORD   result;
  94.  
  95.  
  96.     /* Seed random number generator and get initial location. */
  97.     srand( _threadid );
  98.     newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );
  99.     newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );
  100.     while( repeat )
  101.     {
  102.         /* Pause between loops. */
  103.         Sleep( 100L );
  104.  
  105.         /* Blank out our old position on the screen, and draw new letter. */
  106.  
  107.         if( first )
  108.             first = FALSE;
  109.         else
  110.          WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord,
  111. &result );
  112.          WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord,
  113. &result );
  114.  
  115.         /* Increment the coordinate for next placement of the block. */
  116.         oldcoord.X = newcoord.X;
  117.         oldcoord.Y = newcoord.Y;
  118.         newcoord.X += GetRandom( -1, 1 );
  119.         newcoord.Y += GetRandom( -1, 1 );
  120.  
  121.         /* Correct placement (and beep) if about to go off the screen. */
  122.         if( newcoord.X < 0 )
  123.             newcoord.X = 1;
  124.         else if( newcoord.X == csbi.dwSize.X )
  125.             newcoord.X = csbi.dwSize.X - 2;
  126.         else if( newcoord.Y < 0 )
  127.             newcoord.Y = 1;
  128.         else if( newcoord.Y == csbi.dwSize.Y )
  129.             newcoord.Y = csbi.dwSize.Y - 2;
  130.  
  131.         /* If not at a screen border, continue, otherwise beep. */
  132.         else
  133.             continue;
  134.         Beep( ((char) ch - 'A') * 100, 175 );
  135.     }
  136.     /* _endthread given to terminate */
  137.     _endthread();
  138. }
  139.  
  140.