Annotation of os232sdk/toolkt20/c/samples/hanoi/hanoi.c, revision 1.1

1.1     ! root        1: /*************************************************************
        !             2: 
        !             3:  This program implements a tower of hanoi program.  This
        !             4:  sample app was written to demonstrate the use of a multi-
        !             5:  threaded program.  The main thread handles the PM interface,
        !             6:  the second thread is started to do the recursive execution
        !             7:  of the hanoi algorithm.
        !             8: 
        !             9:  Created by Microsoft, IBM Corporation 1990
        !            10: 
        !            11:  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is 
        !            12:  sample code created by Microsoft Corporation and/or IBM 
        !            13:  Corporation. This sample code is not part of any standard 
        !            14:  Microsoft or IBM product and is provided to you solely for 
        !            15:  the purpose of assisting you in the development of your 
        !            16:  applications.  The code is provided "AS IS", without 
        !            17:  warranty of any kind.  Neither Microsoft nor IBM shall be 
        !            18:  liable for any damages arising out of your use of the sample 
        !            19:  code, even if they have been advised of the possibility of 
        !            20:  such damages.
        !            21: 
        !            22:  Procedures in this file:
        !            23:    main()             Sets up the PM environment and heap and
        !            24:                       calls the main window procedure ClientWndProc
        !            25:    ClientWndProc()    Handles the main window messages
        !            26:    CalcThread()       Sets up and terminates the secondary thread
        !            27:    DrawDisk()         Draws or erases a disk on one of the poles
        !            28:    MoveDisk()         Moves a disk from one pole to another
        !            29:    Hanoi()            Recursive alogrithm for tower of hanoi prog
        !            30:    EnableMenuItem()   Activates/deactivates a menu choice
        !            31:    EntryFldDlgProc()  Handles the set number of disks dialog box
        !            32:    SetupTowers()      Sets up the global tower data
        !            33: 
        !            34: **************************************************************/
        !            35: 
        !            36: #include "hanoi.h"
        !            37: 
        !            38: /********************* GLOBALS *******************************/
        !            39: 
        !            40: CHAR szClientClass[] = "Hanoi";
        !            41: 
        !            42: /* Note that this use of global data precludes multiple windows
        !            43:    of hanoi running at the same time.  Thus, from an object-
        !            44:    oriented perspective, this is less than desireable and the
        !            45:    data should be passed into the window, rather than used
        !            46:    explicitly. */
        !            47: 
        !            48: BYTE    abTowers[3][MAXDISKCNT];     /* Used to hold disk numbers on each post */
        !            49: BYTE    abTowersNdx[3];              /* Current number of disks on each post   */
        !            50: BYTE    cTowerSize = DEFAULTSIZE;   /* Holds the total number of disks        */
        !            51: USHORT  ausPolePos[3]= { POSTOFFSET, /* Holds offset drawing information     */
        !            52:                        POSTOFFSET + POSTSPACE,
        !            53:                        POSTOFFSET + 2*POSTSPACE };
        !            54: ULONG   ulIterations;
        !            55: TID     tidCalcThread;
        !            56: BOOL    fContinueCalc;
        !            57: HWND    hwndFrame, hwndClient;
        !            58: 
        !            59: 
        !            60: /*************************************************************/
        !            61: 
        !            62: 
        !            63: /*
        !            64:  * Function name: main()
        !            65:  *
        !            66:  * Parameters:  argc, argv.  If the user places a number (1 thru MAXDISKCNT)
        !            67:  *              on the command line, that number will become the default
        !            68:  *              number of disks on the stack. Otherwise there will be
        !            69:  *              DEFUALTSIZE disks initially.
        !            70:  *
        !            71:  * Returns: Always returns 0
        !            72:  *
        !            73:  * Purpose: Parses the command line, sets up the PM environment, prepares
        !            74:  *          the Tower arrays, calls the main window proc, handles the
        !            75:  *          window's messages then cleans up and exits.
        !            76:  *
        !            77:  * Usage/Warnings:
        !            78:  *
        !            79:  * Calls: ClientWndProc() (thru PM)
        !            80:  */
        !            81: 
        !            82: int main(int argc, char *argv[])
        !            83: {
        !            84: 
        !            85:    HAB          hab;
        !            86:    HMQ          hmq;
        !            87:    QMSG         qmsg;
        !            88:    
        !            89:    ULONG flFramefContinueCalcFlags = FCF_TITLEBAR      | FCF_SYSMENU | FCF_MINBUTTON |
        !            90:                         FCF_SHELLPOSITION | FCF_MENU    | FCF_TASKLIST  |
        !            91:                         FCF_ICON          | FCF_BORDER  | FCF_ACCELTABLE;
        !            92: 
        !            93:    SHORT  sHold;
        !            94: 
        !            95:    if(argc > 1)  /* If command line arg, use as the initial number of disks */
        !            96:    {
        !            97:       sHold = atoi(argv[1]);
        !            98:       if(sHold>0 && sHold<=MAXDISKCNT)
        !            99:          cTowerSize = (BYTE) sHold;
        !           100:    }
        !           101:    SetupTowers();
        !           102: 
        !           103:    /* These PM calls should be error checked */
        !           104:    hab = WinInitialize(0);
        !           105:    hmq = WinCreateMsgQueue(hab, 0);
        !           106: 
        !           107:    if(!WinRegisterClass(hab, szClientClass,(PFNWP)ClientWndProc,0L,0))
        !           108:    {
        !           109:       WinAlarm(HWND_DESKTOP, WA_ERROR);        /* Register failed */
        !           110:       DosExit(EXIT_PROCESS,1);
        !           111:    }
        !           112: 
        !           113:    hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
        !           114:                                   &flFramefContinueCalcFlags, szClientClass, NULL,
        !           115:                                   0L, NULL, ID_RESOURCE, &hwndClient);
        !           116:    if(!hwndFrame)
        !           117:    {
        !           118:       WinAlarm(HWND_DESKTOP, WA_ERROR); /* Window create failed */
        !           119:       DosExit(EXIT_PROCESS,1);
        !           120:    }
        !           121: 
        !           122:    while(WinGetMsg(hab,&qmsg,NULL,0,0))        /* Message loop */
        !           123:       WinDispatchMsg(hab,&qmsg);
        !           124: 
        !           125:    WinDestroyWindow(hwndFrame);                /* Clean up     */
        !           126:    WinDestroyMsgQueue(hmq);
        !           127:    WinTerminate(hab);
        !           128:    return 0;
        !           129: }
        !           130: 
        !           131: 
        !           132: /*
        !           133:  * Function name: ClientWndProc()
        !           134:  *
        !           135:  * Parameters:  hwnd, msg, mp1, mp2.  Standard PM Window Proc params.
        !           136:  *              No user data is expected in the WM_CREATE.
        !           137:  *
        !           138:  * Returns:
        !           139:  *
        !           140:  * Purpose: Handles all the messages associated with the main window
        !           141:  *          and calls the appropriate handling procedures.
        !           142:  *
        !           143:  * Usage/Warnings: Called only by main().  Note that when WM_PAINT executes,
        !           144:  *                 the secondary thread may change data during the update
        !           145:  *                 which may cause a problem.  However, this is NOT a write
        !           146:  *                 conflict, as only 1 thread does the writing.
        !           147:  *
        !           148:  * Calls:  DrawDisk(), CalcThread() (thru Thread), EntryFldDlgProc() (thru PM)
        !           149:  */
        !           150: 
        !           151: MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
        !           152: {
        !           153:    HPS    hps;                         /* Handle for painting           */
        !           154:    RECTL  rcl;                         /* Rectangle struct for painting */
        !           155:    POINTL ptl;                         /* Point struct for painting     */
        !           156:    BYTE   cPole,bCnt,bHeight,cnt;      /* Utility variables             */
        !           157:    CHAR   szMsg[MSGBUFSIZE];           /* sprintf buffer                */
        !           158: 
        !           159:    switch(msg)
        !           160:    {
        !           161:       case WM_PAINT:
        !           162:          hps = WinBeginPaint(hwnd,NULL,NULL);   /* Get paint handle     */
        !           163:          WinQueryWindowRect(hwnd,&rcl);
        !           164: 
        !           165:          DrawRect(rcl.xLeft,rcl.yBottom,        /* White out the screen */
        !           166:                   rcl.xRight,rcl.yTop,CLR_WHITE);
        !           167: 
        !           168:          /* Draw the base */
        !           169:          DrawRect(BASEXOFFSET,           BASEYOFFSET,
        !           170:                   BASEXOFFSET+BASELEN-1, BASEYOFFSET+BASETHICK-1,
        !           171:                   CLR_DARKGREEN);
        !           172: 
        !           173:          /* Draw the 3 posts */
        !           174:          bHeight = cTowerSize*DISKSPACE + POSTEXTRAHT;
        !           175:          for(cnt=0;cnt<3;cnt++)
        !           176:          {
        !           177:             DrawRect(ausPolePos[cnt]-POSTHALF,          BASEYOFFSET,
        !           178:                      ausPolePos[cnt]-POSTHALF+POSTWIDTH,bHeight,
        !           179:                      CLR_DARKGREEN);
        !           180:          }
        !           181: 
        !           182:          /* Place the appropriate disks on each pole */
        !           183:          for(cPole=0;cPole<3;cPole++)
        !           184:          {
        !           185:             for(bCnt=0;bCnt<abTowersNdx[cPole];bCnt++)
        !           186:             {
        !           187:                DrawDisk(hps,cPole,bCnt,fDRAW);
        !           188:             }
        !           189:          }
        !           190: 
        !           191:          WinEndPaint(hps);
        !           192:          return 0L;
        !           193: 
        !           194:       case WM_COMMAND:
        !           195:          switch(SHORT1FROMMP(mp1))
        !           196:          {
        !           197:             case IDM_START:
        !           198:                           /* Set continuation fContinueCalc  */
        !           199:                fContinueCalc = TRUE;
        !           200:                ulIterations = 0;         /* Zero iteration counter */
        !           201: 
        !           202:                if (DosCreateThread (&tidCalcThread, CalcThread,
        !           203:                                          (ULONG)NULL, 0L, STACK))
        !           204:                {
        !           205:                   DosBeep (440, 175);
        !           206:                   return 0L;
        !           207:                }
        !           208: 
        !           209:                /* Disallow menu items that could change data while the second
        !           210:                   thread is running */
        !           211:                EnableMenuItem(hwnd,IDM_START,FALSE); /* Disable Start & set */
        !           212:                EnableMenuItem(hwnd,IDM_SET,FALSE);
        !           213:                EnableMenuItem(hwnd,IDM_STOP,TRUE);   /* Enable Stop item    */
        !           214:                return 0L;
        !           215: 
        !           216:             case IDM_STOP:
        !           217:                fContinueCalc = FALSE;  /* Notify thread to quit          */
        !           218:                return 0L;
        !           219: 
        !           220:             case IDM_SET:
        !           221:                if(WinDlgBox(HWND_DESKTOP, hwnd, /* Pop up the query/set box */
        !           222:                          (PFNWP)EntryFldDlgProc,NULL,ID_SETCOUNT,NULL))
        !           223:                {
        !           224:                   SetupTowers();                          /* Reset towers   */
        !           225:                   WinInvalidateRect(hwnd,NULL,FALSE);     /* Force a redraw */
        !           226:                }
        !           227:                return 0L;
        !           228:                break;
        !           229: 
        !           230:             case IDM_ABOUT:
        !           231:                 WinDlgBox(HWND_DESKTOP,
        !           232:                           hwnd,
        !           233:                           (PFNWP)AboutDlgProc,
        !           234:                           NULL,
        !           235:                           IDD_ABOUTBOX,
        !           236:                           NULL);
        !           237:                 break;
        !           238: 
        !           239: 
        !           240:              default:
        !           241:                 return WinDefWindowProc(hwnd, msg, mp1, mp2);
        !           242:          }
        !           243: 
        !           244:       case UM_CALC_DONE:
        !           245:          EnableMenuItem(hwnd,IDM_START,TRUE);  /* Reenable Start & set      */
        !           246:          EnableMenuItem(hwnd,IDM_SET,TRUE);
        !           247:          EnableMenuItem(hwnd,IDM_STOP,FALSE);  /* Disable stop              */
        !           248: 
        !           249:          sprintf(szMsg,"%lu disks were moved.",ulIterations);  /* Print msg */
        !           250:          WinMessageBox(HWND_DESKTOP, hwnd, szMsg, "Done!", 0, MB_OK);
        !           251: 
        !           252:          SetupTowers();                        /* Reset towers              */
        !           253:          WinInvalidateRect(hwnd,NULL,FALSE);   /* Force a screen redraw     */
        !           254:          return 0L;
        !           255: 
        !           256:        default:
        !           257:           return WinDefWindowProc(hwnd, msg, mp1, mp2);
        !           258:    }
        !           259: }
        !           260: 
        !           261: 
        !           262: /*
        !           263:  * Function name: CalcThread()
        !           264:  *
        !           265:  * Parameters: none 
        !           266:  *
        !           267:  * Returns: VOID
        !           268:  *
        !           269:  * Purpose: Calls the recursive Hanoi with initial setting of 0,2,1 meaning
        !           270:  *          from pole 0, to pole 2, using pole 1 as a temporary.  Hanoi
        !           271:  *          returns when finished, or the user says stop.  This proc then
        !           272:  *          sets a critical section so the posted message won't be handled
        !           273:  *          until the thread is terminated.
        !           274:  *
        !           275:  * Usage/Warnings: No DosExitCritSec() is called since _endthread() supposedly
        !           276:  *                 clears the critical section when the thread is
        !           277:  *                 terminated.
        !           278:  *
        !           279:  * Calls:  Hanoi()
        !           280:  */
        !           281: 
        !           282: VOID CalcThread ()
        !           283: {
        !           284:    HAB hab;
        !           285: 
        !           286:    hab = WinInitialize(0);    /* Called to increase Ring 2 stack size */
        !           287:    Hanoi(cTowerSize,0,2,1);      /* Execute the recursive routine */
        !           288:    WinTerminate(hab);
        !           289: 
        !           290:    DosEnterCritSec(); /* Set Crit so the UM_CALC_DONE isn't processed */
        !           291:                       /* until this thread has completely terminated  */
        !           292:    WinPostMsg(hwndClient,UM_CALC_DONE,NULL,NULL);         /* Post done */
        !           293: 
        !           294:    DosExit (EXIT_THREAD, 0);                      /* Terminate thread */
        !           295: }
        !           296: 
        !           297: 
        !           298: /*
        !           299:  * Function name: DrawDisk()
        !           300:  *
        !           301:  * Parameters:  hps is a handle to the main PS space.
        !           302:  *              cPole is the pole (0-2) to draw the disk on.
        !           303:  *              bLevel is the number of spaces from the bottom to draw disk.
        !           304:  *              fDraw if =0, erase disk, if =1 draw disk.
        !           305:  *
        !           306:  * Returns: VOID
        !           307:  *
        !           308:  * Purpose: This routine takes a PS handle, the hanoi spindle and disk level
        !           309:  *          and draws an appropriately sized disk.
        !           310:  *
        !           311:  * Usage/Warnings: Does not grab exclusive access to the screen before
        !           312:  *                 drawing which may cause a problem.
        !           313:  *
        !           314:  * Calls:
        !           315:  */
        !           316: 
        !           317: VOID DrawDisk(HPS hps,BYTE cPole, BYTE bLevel,BYTE fDraw)
        !           318: {
        !           319:    USHORT usXstart,usYstart,usWidth;
        !           320:    POINTL ptl;
        !           321: 
        !           322:    usYstart = BOTDISKYPOS + DISKSPACE*bLevel;  /* Calculate Bottom of disk   */
        !           323: 
        !           324:    usWidth  = (MAXDISKWIDTH-MINDISKWIDTH)*abTowers[cPole][bLevel]/cTowerSize
        !           325:               + MINDISKWIDTH;                  /* Calculate the disk's width */
        !           326: 
        !           327:    usXstart = ausPolePos[cPole] - usWidth/2;   /* Center disk on pole        */
        !           328: 
        !           329:    if(fDraw == fDRAW)  /* If we are to draw the disk */
        !           330:    {
        !           331:       DrawRect(usXstart,usYstart,usXstart+usWidth,
        !           332:                usYstart+DISKTHICK-1,CLR_RED);
        !           333:    }
        !           334:    else         /* We are to erase the disk, then redraw the pole */
        !           335:    {
        !           336:       DrawRect(usXstart,usYstart,usXstart+usWidth,
        !           337:                usYstart+DISKTHICK-1,CLR_WHITE);
        !           338:       DrawRect(ausPolePos[cPole]-POSTHALF,usYstart,
        !           339:                ausPolePos[cPole]-POSTHALF+POSTWIDTH,usYstart+DISKTHICK-1,
        !           340:                CLR_DARKGREEN);
        !           341:    }
        !           342: }
        !           343: 
        !           344: 
        !           345: /*
        !           346:  * Function name: MoveDisk()
        !           347:  *
        !           348:  * Parameters:  hps is a handle to the main PS space.
        !           349:  *              bFrom is the spindle to take the top disk from.
        !           350:  *              bTo is the spindle to place the disk on.
        !           351:  *
        !           352:  * Returns: VOID
        !           353:  *
        !           354:  * Purpose: This routine moves the top disk from the bFrom spindle to the top
        !           355:  *          of the bTo spindle.
        !           356:  *
        !           357:  * Usage/Warnings: Does error checking for trying to move a disk from a
        !           358:  *                 spindle that does not have any disks on it.
        !           359:  *
        !           360:  * Calls:  MoveDisk()
        !           361:  */
        !           362: 
        !           363: VOID MoveDisk(HPS hps,BYTE bFrom,BYTE bTo)
        !           364: {
        !           365:    CHAR bTOSndx;  /* Top of stack index  */
        !           366:    BYTE bDiskNum; /* Disk number to move */
        !           367: 
        !           368:    bTOSndx = abTowersNdx[bFrom]-1;
        !           369:    if(bTOSndx < 0)
        !           370:       return;
        !           371: 
        !           372:    DrawDisk(hps,bFrom,bTOSndx,fERASE);   /* Remove disk off from stack     */
        !           373: 
        !           374:    bDiskNum = abTowers[bFrom][bTOSndx];  /* Get move disk number           */
        !           375:    abTowersNdx[bFrom]--;                 /* Decrease count on from spindle */
        !           376: 
        !           377:    bTOSndx = abTowersNdx[bTo]++;         /* Offset to place the disk at    */
        !           378:    abTowers[bTo][bTOSndx] = bDiskNum;    /* Place on stack in memory       */
        !           379: 
        !           380:    DrawDisk(hps,bTo,bTOSndx,fDRAW);      /* Draw disk on the to stack      */
        !           381: }
        !           382: 
        !           383: 
        !           384: /*
        !           385:  * Function name: Hanoi()
        !           386:  *
        !           387:  * Parameters:  pcp is a struct which contains the hwnd handle and the
        !           388:  *                  continue fContinueCalcFlag which is initially set to TRUE.
        !           389:  *              bHeight is the number of disks in the from stack to move.
        !           390:  *              bFrom is the from spindle number, 0-2.
        !           391:  *              bTo is the to spindle number.
        !           392:  *              bTemp is the temporary spindle number.
        !           393:  *
        !           394:  * Returns: VOID
        !           395:  *
        !           396:  * Purpose: This routine implements a recursive hanoi program that works as
        !           397:  *          follows:  By recursion, move all the disks, except for the
        !           398:  *          bottom disk to the temporary stack.  Then move the bottom
        !           399:  *          disk to the target spindle.  Now recursively move the stack
        !           400:  *          on the temporary spindle to the target spindle.  The limiting
        !           401:  *          case is when Hanoi() is called with a bHeight of 0 in which
        !           402:  *          case the depth recursion is terminated.
        !           403:  *
        !           404:  * Usage/Warnings: This routine checks the ->fContClac fContinueCalcFlag, which is set
        !           405:  *                 by the main thread when the user selects stop, to see if
        !           406:  *                 the user wishes to abort the algorithm.  If so, it backs
        !           407:  *                 out and exits.
        !           408:  *
        !           409:  * Calls:  MoveDisk()
        !           410:  */
        !           411: 
        !           412: VOID Hanoi(BYTE bHeight, BYTE bFrom, BYTE bTo, BYTE bTemp)
        !           413: {
        !           414:    HPS hps;
        !           415: 
        !           416:    if(bHeight<=0 || !fContinueCalc)       /* Exit up if no more disks or */
        !           417:       return;                             /* the user said Stop          */
        !           418: 
        !           419:    Hanoi(bHeight-1,bFrom,bTemp,bTo);  /* Move all but bottom disk    */
        !           420: 
        !           421:    if(!fContinueCalc)                /* If user said to stop        */
        !           422:       return;
        !           423: 
        !           424:    /* Display bFrom -> bTo */
        !           425:    hps = WinGetPS(hwndClient);
        !           426:    MoveDisk(hps,bFrom,bTo);               /* Move the bottom disk        */
        !           427:    WinReleasePS(hps);
        !           428:    ulIterations++;
        !           429: 
        !           430:    Hanoi(bHeight-1,bTemp,bTo,bFrom);  /* Move disks over             */
        !           431: }
        !           432: 
        !           433: 
        !           434: /*
        !           435:  * Function name: EnableMenuItem()
        !           436:  *
        !           437:  * Parameters:  hwnd is a handle of the current window.
        !           438:  *              sMenuItem is the ID of the item to Enable/Disable.
        !           439:  *              fEnable will enable item if TRUE, otherwise disables it.
        !           440:  *
        !           441:  * Returns: VOID
        !           442:  *
        !           443:  * Purpose: This routine handles enabling/disabling of menu items.  This
        !           444:  *          is done by getting Parent and Menu hwnd handles then sending
        !           445:  *          the appropriate message.
        !           446:  *
        !           447:  * Usage/Warnings:
        !           448:  *
        !           449:  * Calls:
        !           450:  */
        !           451: 
        !           452: VOID EnableMenuItem(HWND hwnd, SHORT sMenuItem, BOOL fEnable)
        !           453: {
        !           454:    HWND hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE);
        !           455:    HWND hwndMenu   = WinWindowFromID(hwndParent, FID_MENU);
        !           456: 
        !           457:    WinSendMsg(hwndMenu, MM_SETITEMATTR,
        !           458:               MPFROM2SHORT(sMenuItem, TRUE),
        !           459:               MPFROM2SHORT(MIA_DISABLED, fEnable ? 0 : MIA_DISABLED));
        !           460: }
        !           461: 
        !           462: 
        !           463: /*
        !           464:  * Function name: EntryFldDlgProc()
        !           465:  *
        !           466:  * Parameters:  hwnd, msg, mp1, mp2.  Standard PM Dialog Proc params.
        !           467:  *              No user data is expected in the WM_CREATE.
        !           468:  *
        !           469:  * Returns: Terminates with a TRUE iff a new valid Tower Size has been entered.
        !           470:  *
        !           471:  * Purpose: Handles all the messages associated with the set entry field
        !           472:  *          and calls the appropriate handling procedures.  The purpose
        !           473:  *          of this dialog box is to get a new number of disks for the
        !           474:  *          hanoi routine.
        !           475:  *
        !           476:  *
        !           477:  * Usage/Warnings: If the value entered is valid, global cTowerSize is
        !           478:  *                 changed to the new value, and TRUE is returned.
        !           479:  *
        !           480:  * Calls:
        !           481:  */
        !           482: 
        !           483: MRESULT EXPENTRY EntryFldDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
        !           484: {
        !           485:    SHORT sNewSize;            /* Holds new number of disks        */
        !           486: 
        !           487:    switch(msg)
        !           488:    {
        !           489:       case WM_INITDLG:
        !           490:          WinSendDlgItemMsg(hwnd, ID_ENTRYFLD,EM_SETTEXTLIMIT,  /* Limit len */
        !           491:                                  MPFROM2SHORT(2,0),NULL);
        !           492:          WinSetDlgItemShort(hwnd, ID_ENTRYFLD,(SHORT) cTowerSize,TRUE);
        !           493:          return 0L;                           /* Allow normal focus setting */
        !           494: 
        !           495:       case WM_COMMAND:
        !           496:          switch(SHORT1FROMMP(mp1))
        !           497:          {
        !           498:             case DID_OK:
        !           499:                WinQueryDlgItemShort(hwnd, ID_ENTRYFLD,
        !           500:                                     &sNewSize, TRUE); /* Get the short      */
        !           501:                if(sNewSize>0 && sNewSize<=MAXDISKCNT) /* Set new Tower size */
        !           502:                {
        !           503:                   cTowerSize = (BYTE) sNewSize;
        !           504:                   WinDismissDlg(hwnd,TRUE);
        !           505:                }
        !           506:                else                                   /* Invalid value      */
        !           507:                {
        !           508:                    WinMessageBox (HWND_DESKTOP, hwndFrame, "You may only select up to 16 disks",
        !           509:                                   "OOPS! Too many disks!", ID_MSGBOX, MB_OK |
        !           510:                                    MB_ICONEXCLAMATION);
        !           511:                }
        !           512: 
        !           513:                return 0L;
        !           514: 
        !           515:             case DID_CANCEL:
        !           516:                WinDismissDlg(hwnd,FALSE);
        !           517:                return 0L;
        !           518: 
        !           519:             default:
        !           520:                return WinDefDlgProc(hwnd, msg, mp1, mp2);
        !           521:          }
        !           522: 
        !           523:       default:
        !           524:          return WinDefDlgProc(hwnd, msg, mp1, mp2);
        !           525:    }
        !           526: }
        !           527: 
        !           528: /*
        !           529:  * Function name: AboutDlgProc()
        !           530:  *
        !           531:  * Parameters:  hwnd, msg, mp1, mp2.  Standard PM Dialog Proc params.
        !           532:  *              No user data is expected in the WM_CREATE.
        !           533:  *
        !           534:  * Returns:
        !           535:  *
        !           536:  * Purpose: Handles all the messages associated with the About Box
        !           537:  *
        !           538:  *
        !           539:  * Usage/Warnings:
        !           540:  *
        !           541:  * Calls:
        !           542:  */
        !           543: 
        !           544: MRESULT EXPENTRY AboutDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
        !           545: {
        !           546: 
        !           547:    switch(msg)
        !           548:    {
        !           549:       case WM_COMMAND:
        !           550:          WinDismissDlg(hwnd, TRUE);
        !           551:          break;
        !           552: 
        !           553:       default:
        !           554:          return WinDefDlgProc(hwnd, msg, mp1, mp2);
        !           555:    }
        !           556: }
        !           557: 
        !           558: /*
        !           559:  * Function name: SetupTowers()
        !           560:  *
        !           561:  * Parameters:  None
        !           562:  *
        !           563:  * Returns: VOID
        !           564:  *
        !           565:  * Purpose: This routine initializes the global arrays that represent the
        !           566:  *          hanoi stacks.  This involves placing all the disks on the
        !           567:  *          first peg, emptying the other 2 pegs and setting the associated
        !           568:  *          counts.
        !           569:  *
        !           570:  * Usage/Warnings: Calling uses the global variable cTowerSize to determine
        !           571:  *                 how many disks there are.
        !           572:  *
        !           573:  * Calls:
        !           574:  */
        !           575: 
        !           576: VOID SetupTowers()
        !           577: {
        !           578:    USHORT cnt;
        !           579: 
        !           580:    for(cnt=0;cnt<cTowerSize;cnt++)       /* Setup the intial post with disks */
        !           581:       abTowers[0][cnt] = cTowerSize-cnt-1;
        !           582: 
        !           583:    abTowersNdx[0] = cTowerSize;          /* Set disk count for initial post  */
        !           584:    abTowersNdx[1] = abTowersNdx[2] = 0;  /* Zero other post counts           */
        !           585: }

unix.superglobalmegacorp.com

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