Annotation of q_a/samples/threads/threads.c, revision 1.1.1.2

1.1.1.2 ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
1.1       root       12: /*************************************************************************\
                     13: *  PROGRAM: Threads.c
                     14: *
                     15: *  PURPOSE:
                     16: *
                     17: *     To demonstrate suspending, resuming, and setting the priorities
                     18: *     of threads.
                     19: *
                     20: *  FUNCTIONS:
                     21: *
                     22: *    WinMain()      - Initializes the window, and process the message loop.
                     23: *    MainWndProc()  - Process messages, launches server & client threads.
                     24: *    ThreadProc()   - Draws rectangles to the window, demonstrating the
                     25: *                     threads performance.
                     26: *
                     27: *  COMMENTS:
                     28: *
                     29: *    To Use:
                     30: *      When starting this application, two threads are created.  The
                     31: *      first draws a green box, the second a red.  Both boxes are moved
                     32: *      about the screen as their individual threads calculate a new
                     33: *      position and redraws the box.  The user can Suspend either thread,
                     34: *      Resume them, or change their priority through the menu selections.
                     35: *      The colored boxes will respond accordingly.
                     36: *
                     37: *      Note through out the sample "red thread" or "green thread" are
                     38: *      referred to.  This simply indicates the thread which draws either the
                     39: *      red or green rectangle.
                     40: *
                     41: \*************************************************************************/
                     42: 
                     43: 
                     44: #include <windows.h>
                     45: #include <stdlib.h>
                     46: #include <time.h>
                     47: #include "threads.h"
                     48: 
                     49: 
                     50: HANDLE hInst;
                     51: HANDLE hWnd;
                     52: 
                     53: /*************************************************************************\
                     54: *
                     55: *  FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
                     56: *
                     57: *  PURPOSE: calls initialization function, processes message loop
                     58: *
                     59: *  COMMENTS:
                     60: *
                     61: \*************************************************************************/
                     62: int APIENTRY WinMain (HANDLE hInstance,
                     63:                       HANDLE hPrevInstance,
                     64:                       LPSTR  lpCmdLine,
                     65:                       int    nCmdShow)
                     66: {
                     67:   MSG  msg;
                     68:   WNDCLASS wc;
                     69: 
                     70:   UNREFERENCED_PARAMETER( lpCmdLine );
                     71:   UNREFERENCED_PARAMETER( hPrevInstance );
                     72: 
                     73:   hInst = hInstance;
                     74: 
1.1.1.2 ! root       75:   wc.style = 0;                          // Replaces CS_SIZEREDRAW.
1.1       root       76:   wc.lpfnWndProc = (WNDPROC)MainWndProc; // The client window procedure.
                     77:   wc.cbClsExtra = 0;                     // No room reserved for extra data.
                     78:   wc.cbWndExtra = 0;
                     79:   wc.hInstance = hInstance;
                     80:   wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
                     81:   wc.hCursor = LoadCursor (NULL, IDC_ARROW);
                     82:   wc.hbrBackground = GetStockObject (WHITE_BRUSH);
                     83:   wc.lpszMenuName = "Thread_Menu";
                     84:   wc.lpszClassName = "ThreadsWClass";
                     85: 
                     86:   RegisterClass(&wc);
                     87: 
                     88: 
                     89:   hWnd = CreateWindow ("ThreadsWClass",
                     90:                        "Threads Sample",
                     91:                        WS_OVERLAPPEDWINDOW,
                     92:                        CW_USEDEFAULT,
                     93:                        CW_USEDEFAULT,
                     94:                        CW_USEDEFAULT,
                     95:                        CW_USEDEFAULT,
                     96:                        NULL,
                     97:                        NULL,
                     98:                        hInstance,
                     99:                        NULL);
                    100: 
                    101: 
                    102:   ShowWindow(hWnd, nCmdShow);
1.1.1.2 ! root      103:   while (GetMessage (&msg, NULL, 0, 0))
1.1       root      104:     DispatchMessage (&msg);   // Dispatch message to window.
                    105: 
                    106:   return (msg.wParam);           // Returns value from PostQuitMessage.
                    107: 
                    108: }
                    109: 
                    110: /*************************************************************************\
                    111: *
                    112: *  FUNCTION:  MainWndProc (HWND, UINT, UINT, LONG)
                    113: *
                    114: *  PURPOSE:   To process the windows messages.  This procedure totally
                    115: *             controls the priority and suspension/resumption of the
                    116: *             thread.
                    117: *
                    118: *  VARIABLES USED:
                    119: *
                    120: *    - hThread1, hThread2:
                    121: *             Static handles to the two created threads.
                    122: *
                    123: *    - ThreadID1 ThreadID2:
                    124: *             DWORDs used in the CreateThread call.
                    125: *
                    126: *    - pColor1, pColor2:
                    127: *             DWORDs used to allocate some memory to use as a parameter
                    128: *             to pass color values to the threads.  This memory was
                    129: *             allocated so that the threads wouldn't have to rely on this
                    130: *             procedures stack for the values.
                    131: *
                    132: *    - Buf[80]:
                    133: *             Character buffer used to write messages to the user.
                    134: *
                    135: *    - RedSuspendCnt, GreenSuspendCnt:
                    136: *             Static DWORDs used to track the count of suspension put
                    137: *             on the specific thread.
                    138: *
                    139: *  MESSAGES:
                    140: *
                    141: *    WM_DESTROY:     - Terminates the threads and post the quit message.
                    142: *    WM_CREATE:      - Allocates memory to hold some color values, and
                    143: *                      creates the two threads.
                    144: *    WM_COMMAND
                    145: *
                    146: *      IDM_SUSPEND***:
                    147: *               Suspends the specified thread, updates the globally kept
                    148: *               count (number of times the thread has been suspended),
                    149: *               and then produces a message box telling the user the
                    150: *               number of suspensions.
                    151: *
                    152: *      IDM_RESUME***:
                    153: *               Resumes the specified thread, updates the gobally kept
                    154: *               count (number of times the thread has been suspended),
                    155: *               and then produces a message box telling the user the
                    156: *               number of suspensions.
                    157: *
                    158: *      IDM_G***:
1.1.1.2 ! root      159: *               These 7 messages use SetThreadPriority to set the
1.1       root      160: *               priority of the Green Thread.
                    161: *
                    162: *      IDM_R***:
1.1.1.2 ! root      163: *               These 7 messages use SetThreadPriority to set the
1.1       root      164: *               priority of the Red Thread.
                    165: *
                    166: *  CALLED BY:
                    167: *
                    168: *    WinMain();
                    169: *
                    170: *  CALLS TO:
                    171: *
                    172: *    ThreadProc();
                    173: *
                    174: *  COMMENTS:
                    175: *
                    176: *
                    177: \*************************************************************************/
                    178: 
                    179: 
                    180: LONG APIENTRY MainWndProc (HWND hwnd,
                    181:                            UINT message,
                    182:                            UINT wParam,
                    183:                            LONG lParam)
                    184: {
                    185:   static HANDLE hThread1, hThread2;
                    186:   DWORD  ThreadID1, ThreadID2;
                    187:   CHAR Buf[80];
                    188:   static DWORD RedSuspendCnt = 0;
                    189:   static DWORD GreenSuspendCnt = 0;
                    190:   static DWORD *pColor1, *pColor2;
                    191: 
                    192:   switch (message)
                    193:       {
                    194: 
                    195:         case WM_CREATE :
                    196: 
                    197:           pColor1 = malloc(sizeof(DWORD));
                    198:           *pColor1 = GREEN;
                    199:           hThread1 = CreateThread (NULL, 0,
                    200:                                    (LPTHREAD_START_ROUTINE)ThreadProc,
1.1.1.2 ! root      201:                                    (LPVOID)pColor1, 0,
1.1       root      202:                                    (LPDWORD)&ThreadID1);
                    203: 
                    204:           if (!hThread1)
                    205:             {
                    206:              wsprintf(Buf, "Error in creating Green thread: %d",
                    207:                       GetLastError());
                    208:              MessageBox (hwnd, Buf, "WM_CREATE", MB_OK);
                    209:             }
                    210: 
                    211:           Sleep (500);             // Allow some time/distance between the
                    212:                                    // thread boxes.
                    213: 
                    214:           pColor2 = malloc(sizeof(DWORD));
                    215:           *pColor2 = RED;
                    216:           hThread2 = CreateThread (NULL, 0,
                    217:                                    (LPTHREAD_START_ROUTINE)ThreadProc,
1.1.1.2 ! root      218:                                    (LPVOID)pColor2, 0,
1.1       root      219:                                    (LPDWORD)&ThreadID2);
                    220:           if (!hThread2)
                    221:             {
                    222:              wsprintf(Buf, "Error in creating Red thread: %d",
                    223:                       GetLastError());
                    224:              MessageBox (hwnd, Buf, "WM_CREATE", MB_OK);
                    225:             }
                    226: 
                    227: 
                    228:           return (0);
                    229: 
                    230:         case WM_COMMAND:
                    231:           switch (LOWORD(wParam))
                    232:             {
                    233:             case IDM_SUSPENDGREEN:           // Suspends green thread.
                    234:               SuspendThread (hThread1);
                    235:               GreenSuspendCnt++;
                    236:               wsprintf(Buf, "The suspension count for the green thread is now %d",
                    237:                        GreenSuspendCnt);
                    238:               MessageBox(hWnd, Buf, "Suspension Count", MB_OK);
                    239:               return (0);
                    240: 
                    241:             case IDM_SUSPENDRED:             // Suspends red thread.
                    242:               SuspendThread (hThread2);
                    243:               RedSuspendCnt++;
                    244:               wsprintf(Buf, "The suspension count for the red thread is now %d",
                    245:                        RedSuspendCnt);
                    246:               MessageBox(hWnd, Buf, "Suspension Count", MB_OK);
                    247:               return (0);
                    248: 
                    249:             case IDM_RESUMEGREEN:            // Resumes green thread.
                    250:               ResumeThread (hThread1);
                    251:               if (GreenSuspendCnt > 0)
                    252:                 GreenSuspendCnt--;
                    253:               wsprintf(Buf, "The suspension count for the green thread is now %d",
                    254:                        GreenSuspendCnt);
                    255:               MessageBox(hWnd, Buf, "Suspension Count", MB_OK);
                    256:               return (0);
                    257: 
                    258:             case IDM_RESUMERED:              // Resumes red thread.
                    259:               ResumeThread (hThread2);
                    260:               if (RedSuspendCnt > 0)
                    261:                 RedSuspendCnt--;
                    262:               wsprintf(Buf, "The suspension count for the red thread is now %d",
                    263:                        RedSuspendCnt);
                    264:               MessageBox(hWnd, Buf, "Suspension Count", MB_OK);
                    265:               return (0);
                    266: 
                    267: 
1.1.1.2 ! root      268:             case IDM_GIDLE:                   // Sets green idle.
        !           269:               SetThreadPriority (hThread1, THREAD_PRIORITY_IDLE);
        !           270:               return (0);
        !           271: 
        !           272: 
        !           273:             case IDM_GLOW:                   // Sets green lowest.
1.1       root      274:               SetThreadPriority (hThread1, THREAD_PRIORITY_LOWEST);
                    275:               return (0);
                    276: 
                    277:             case IDM_GBNORM:                 // Sets green below normal.
                    278:               SetThreadPriority (hThread1, THREAD_PRIORITY_BELOW_NORMAL);
                    279:               return (0);
                    280: 
                    281:             case IDM_GNORM:                  // Sets green to normal.
                    282:               SetThreadPriority (hThread1, THREAD_PRIORITY_NORMAL);
                    283:               return (0);
                    284: 
                    285:             case IDM_GANORM:                 // Sets green above normal.
                    286:               SetThreadPriority (hThread1, THREAD_PRIORITY_ABOVE_NORMAL);
                    287:               return (0);
                    288: 
1.1.1.2 ! root      289:             case IDM_GHIGH:                  // Sets green to highest.
1.1       root      290:               SetThreadPriority (hThread1, THREAD_PRIORITY_HIGHEST);
                    291:               return (0);
                    292: 
1.1.1.2 ! root      293:             case IDM_GTC:                   // Sets green time critical.
        !           294:               SetThreadPriority (hThread1, THREAD_PRIORITY_TIME_CRITICAL);
        !           295:               return (0);
        !           296: 
        !           297: 
        !           298: 
        !           299: 
        !           300:             case IDM_RIDLE:                   // Sets red idle.
        !           301:               SetThreadPriority (hThread1, THREAD_PRIORITY_IDLE);
        !           302:               return (0);
1.1       root      303: 
                    304:             case IDM_RLOW:                   // Sets red to lowest possible
                    305:               SetThreadPriority (hThread2, THREAD_PRIORITY_LOWEST);
                    306:               return (0);
                    307: 
                    308:             case IDM_RBNORM:                 // Sets red below normal.
                    309:               SetThreadPriority (hThread2, THREAD_PRIORITY_BELOW_NORMAL);
                    310:               return (0);
                    311: 
                    312:             case IDM_RNORM:                  // Sets red to normal.
                    313:               SetThreadPriority (hThread2, THREAD_PRIORITY_NORMAL);
                    314:               return (0);
                    315: 
                    316:             case IDM_RANORM:                 // Sets red above normal.
                    317:               SetThreadPriority (hThread2, THREAD_PRIORITY_ABOVE_NORMAL);
                    318:               return (0);
                    319: 
                    320:             case IDM_RHIGH:                  // Sets red to highest.
                    321:               SetThreadPriority (hThread2, THREAD_PRIORITY_HIGHEST);
                    322:               return (0);
                    323: 
1.1.1.2 ! root      324:             case IDM_RTC:                   // Sets green time critical.
        !           325:               SetThreadPriority (hThread1, THREAD_PRIORITY_TIME_CRITICAL);
        !           326:               return (0);
        !           327: 
1.1       root      328:             default:
                    329:               return (0);
                    330: 
                    331: 
                    332:             }
                    333: 
                    334:         case WM_DESTROY :
                    335:             TerminateThread(hThread1, 0);
                    336:             TerminateThread(hThread2, 0);
                    337:             free (pColor1);
                    338:             free (pColor2);
                    339:             PostQuitMessage (0);
                    340:             return (0);
                    341: 
                    342:        }
                    343:     return DefWindowProc (hwnd, message, wParam, lParam);
                    344: }
                    345: 
                    346: /*************************************************************************\
                    347: *
                    348: *  FUNCTION:  ThreadProc (LPVOID)
                    349: *
                    350: *  PURPOSE:   A thread procedure which calculates position on the window
                    351: *             and draws a colored rectangle.  The color of the rectangle
                    352: *             is determined by the input parameter, it's border is
                    353: *             always black (or whatever the pen color is); and since
                    354: *             the window does not paint between rectangle draws, the
                    355: *             rectangle leaves a black path in it's wake.
                    356: *
                    357: *  VARIABLES USED:
                    358: *
                    359: *    - horizontal, vertical:
                    360: *             Local int used to indicate the next directional move the
                    361: *             rectangle will make.
                    362: *
                    363: *    - ulx, uly:
                    364: *             Local DWORD used for the Upper Left X corner and Upper
                    365: *             Upper Left Y position of the rectangle.
                    366: *
                    367: *    - rect:  A RECT structure used to determin the current size of the
                    368: *             window (in case the user resizes it).
                    369: *
                    370: *    - hdc:   HDC of the rectangle.
                    371: *
                    372: *    - Time:  A SYSTEMTIME structure.  It's milli-second field is used
                    373: *             to create an apparent random starting point for the
                    374: *             rectangles.
                    375: *
                    376: *    -hBrush: A handle to a Brush object, used to set the color of the
                    377: *             rectangle.
                    378: *
                    379: *    -width, height:
                    380: *             Local DWORDs used for the width and height of the rectangles.
                    381: *
                    382: *  CALLED BY:
                    383: *
                    384: *    MainWndProc();
                    385: *
                    386: \*************************************************************************/
                    387: 
                    388: 
                    389: VOID ThreadProc ( LPVOID *Color)
                    390: {
                    391:   int  horizontal, vertical;
                    392:   DWORD ulx, uly;
                    393:   RECT rect;
                    394:   HDC  hDC;
                    395:   SYSTEMTIME Time;
                    396:   HANDLE hBrush;
                    397:   DWORD width, height;
                    398: 
                    399:   width =  10;
                    400:   height = 10;
                    401: 
                    402:   GetSystemTime (&Time);                     // Get the time.
                    403: 
                    404:   do{}while(!GetClientRect(hWnd, &rect));    // Loop, making sure window
                    405:                                              // exists.
                    406: 
                    407:   ulx = (Time.wMilliseconds % rect.right);   // Use MOD to get a random
                    408:   uly = (Time.wMilliseconds % rect.bottom);  // position.
                    409: 
                    410:   if(Time.wMilliseconds % 2 == 0)            // Use MOD to pick random
                    411:     {                                        // directions.
                    412:      horizontal = 1;
                    413:      vertical = 1;
                    414:     }
                    415:   else
                    416:     {
                    417:      horizontal = 1;
                    418:      vertical = -1;
                    419:     }
                    420:                                              // Set color as per input
                    421:                                              // parameter.
                    422:   hBrush = CreateSolidBrush((COLORREF)*Color);
                    423: 
                    424:   do
                    425:     {                                        // do forever ...
                    426:      GetClientRect( hWnd, &rect);
                    427: 
                    428:      if ( (ulx+width) > (DWORD)rect.right)   // ... check for right edge,
                    429:       {
                    430:       ulx = rect.right - width;
                    431:       horizontal = -1;                       //   ... if so change direction;
                    432:       }
                    433: 
                    434:      if ((uly+height) > (DWORD)rect.bottom)  // ... check for bottom edge,
                    435:       {
                    436:       uly = rect.bottom - height;            //   ... if so change dir.
                    437:       vertical = -1;
                    438:       }
                    439: 
                    440:      if (uly <= 1)                           // ... check for right edge,
                    441:       {
                    442:       uly = 1;
                    443:       vertical = 1;
                    444:       }
                    445: 
                    446:      if (ulx <= 1)
                    447:       {                                      // ... check for top edge;
                    448:       ulx = 1;
                    449:       horizontal = 1;
                    450:       }
                    451: 
                    452:      hDC = GetDC(hWnd);                      // ... Get DC,
                    453:      SelectObject( hDC, hBrush);             // ... Set brush color,
                    454:                                              // ... Draw rectangle,
                    455:      Rectangle (hDC, ulx, uly, ulx+width, uly+height);
                    456:      ReleaseDC(hWnd, hDC);                   // ... Release DC
                    457:      ulx += horizontal;                      // ... Increment/decrement
                    458:      uly += vertical;                        // ... position.
                    459: 
                    460:     }while(1);
                    461: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.