Annotation of mstools/samples/mandel/julia.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: julia.c
        !             3: *
        !             4: * Main module for the Mandelbrot Dream
        !             5: *       contains almost everything; windows procedure + misc stuff
        !             6: *
        !             7: * Created: 24-Oct-1991 18:34:08
        !             8: * Author: Petrus Wong
        !             9: *
        !            10: * Copyright (c) 1990 Microsoft Corporation
        !            11: *
        !            12: * The Mandelbrot Dream serves to demonstrate the GDI and USER
        !            13: * functionalities in the setting of fractals.
        !            14: *
        !            15: * The Mandelbrot Dream provides the following functions:
        !            16: *       1.  Drawing the Mandelbrot set and the corresponding julia set
        !            17: *       2.  Zooming into any of the set
        !            18: *       3.  MDI fractal drawing windows
        !            19: *       4.  Floating Point Math/Fix Point Math
        !            20: *       5.  Shifting color table entries
        !            21: *       6.  Changing palette entries and animating palatte aka color cycling
        !            22: *       7.  Loading/Saving bitmap created with special effect
        !            23: *       8.  Changing bitmap color with flood fill
        !            24: *       9.  Boundary tracing and creating a clip region out of it for
        !            25: *           creating special effect
        !            26: *      10.  Enumerate printers for printing
        !            27: *
        !            28: * Dependencies:
        !            29: *
        !            30: *       none
        !            31: *
        !            32: \**************************************************************************/
        !            33: #include <windows.h>
        !            34: #include <stdlib.h>
        !            35: #include <commdlg.h>
        !            36: #include <stdarg.h>
        !            37: #include <math.h>
        !            38: #include <stdio.h>
        !            39: #include "julia.h"
        !            40: 
        !            41: //#define CYCLETHRD
        !            42: #define PRTTHRD
        !            43: #define NEWPRTAPI
        !            44: 
        !            45: //#define DEBUG
        !            46: 
        !            47: #ifndef DEBUG
        !            48:    #undef OutputDebugString
        !            49:    #define OutputDebugString(LPCSTR)
        !            50: #endif
        !            51: 
        !            52: 
        !            53: 
        !            54: //
        !            55: // Forward declarations.
        !            56: //
        !            57: BOOL InitializeApp   (INT*);
        !            58: LONG MainWndProc     (HWND, UINT, DWORD, LONG);
        !            59: LONG ChildWndProc   (HWND, UINT, DWORD, LONG);
        !            60: LONG About          (HWND, UINT, DWORD, LONG);
        !            61: LONG TextWndProc     (HWND, UINT, DWORD, LONG);
        !            62: LONG JuliaWndProc    (HWND, UINT, DWORD, LONG);
        !            63: LONG DrawWndProc     (HWND, UINT, DWORD, LONG);
        !            64: BOOL APIENTRY SuspendDrawThrd (HWND, LONG);
        !            65: BOOL APIENTRY ResumeDrawThrd  (HWND, LONG);
        !            66: BOOL StartDraw       (PINFO);
        !            67: BOOL StartDrawFix    (PINFO);
        !            68: BOOL StartDraw2      (PINFO);
        !            69: BOOL StartMandelbrot (PINFO);
        !            70: BOOL StartMandelbrotFix (PINFO);
        !            71: HBITMAP SaveBitmap   (HWND);
        !            72: void DrawBitmap      (HDC, PINFO, int, int, int, int);
        !            73: LONG lMul(LONG, LONG);
        !            74: LONG lDiv(LONG, LONG);
        !            75: PINFO pGetInfoData(HWND);
        !            76: BOOL bReleaseInfoData(HWND);
        !            77: BOOL bCheckMutexMenuItem(HMENU, UINT);
        !            78: BOOL bInitInfo(PINFO);
        !            79: BOOL bResetGlobal(VOID);
        !            80: HBRUSH hBrCreateBrush(HDC, DWORD);
        !            81: BOOL bPrintBmp(PPRTDATA);
        !            82: extern BOOL bCycle(HWND);
        !            83: extern BOOL bCleanupPrinter(VOID);
        !            84: extern INT  iCreatePenFrPal(HDC, PVOID *);
        !            85: 
        !            86: /******************************Public*Routine******************************\
        !            87: *
        !            88: * WinMain
        !            89: *
        !            90: * History:
        !            91: *  13-Jun-1992 -by- Petrus Wong     Creates an array of pens
        !            92: *  17-Apr-1991 -by- Petrus Wong
        !            93: * Wrote it.
        !            94: \**************************************************************************/
        !            95: 
        !            96: int APIENTRY WinMain(
        !            97:     HINSTANCE hInstance,
        !            98:     HINSTANCE hPrevInstance,
        !            99:     LPSTR lpCmdLine,
        !           100:     int nShowCmd)
        !           101: {
        !           102:     MSG    msg;
        !           103:     INT    i;
        !           104: 
        !           105:     ghModule = GetModuleHandle(NULL);
        !           106:     if (!InitializeApp(&giPen)) {
        !           107:        MessageBox(ghwndMain, "memory: InitializeApp failure!", "Error", MB_OK);
        !           108:         return 0;
        !           109:     }
        !           110: 
        !           111:     if (!(ghAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
        !           112:        MessageBox(ghwndMain, "memory: Load Accel failure!", "Error", MB_OK);
        !           113: 
        !           114: 
        !           115:     while (GetMessage(&msg, NULL, 0, 0)) {
        !           116:         if (!TranslateAccelerator( ghwndMain, ghAccel, &msg) &&
        !           117:             !TranslateMDISysAccel(  ghwndClient, &msg)          ) {
        !           118:             TranslateMessage(&msg);
        !           119:             DispatchMessage(&msg);
        !           120:         }
        !           121:     }
        !           122: 
        !           123:     //
        !           124:     // Delete all the pens created and free the array of hPens;
        !           125:     // The pens and the array of hPens was created and allocated respectively
        !           126:     // in InitializeApp
        !           127:     //
        !           128:     if (gprghPen != NULL) {
        !           129:         for (i = 0; i <= giPen; i++) {
        !           130:             DeleteObject((HPEN) gprghPen[i]);
        !           131:         }
        !           132:         GlobalFree(gprghPen);
        !           133:     }
        !           134: 
        !           135: 
        !           136:     return 1;
        !           137: 
        !           138:     UNREFERENCED_PARAMETER(lpCmdLine);
        !           139:     UNREFERENCED_PARAMETER(nShowCmd);
        !           140:     UNREFERENCED_PARAMETER(hInstance);
        !           141:     UNREFERENCED_PARAMETER(hPrevInstance);
        !           142: }
        !           143: 
        !           144: 
        !           145: /***************************************************************************\
        !           146: * InitializeApp
        !           147: *
        !           148: * History:
        !           149: * 13-Jun-1992   Petrus Wong     creates pens
        !           150: * 29-May-1992   Petrus Wong     check if device supports palette for cycling
        !           151: * 09-09-91      Petrus Wong    Created.
        !           152: \***************************************************************************/
        !           153: 
        !           154: BOOL InitializeApp(INT *piPen)
        !           155: {
        !           156:     WNDCLASS wc;
        !           157:     HDC      hDC;
        !           158:     INT      iNumClr;
        !           159: 
        !           160:     wc.style            = CS_OWNDC;
        !           161:     wc.lpfnWndProc      = (WNDPROC)MainWndProc;
        !           162:     wc.cbClsExtra       = 0;
        !           163:     wc.cbWndExtra      = sizeof(LONG);
        !           164:     wc.hInstance        = ghModule;
        !           165:     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
        !           166:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        !           167:     wc.hbrBackground   = (HBRUSH)(COLOR_APPWORKSPACE);
        !           168:     wc.lpszMenuName     = "MainMenu";
        !           169:     wc.lpszClassName   = "MandelClass";
        !           170: 
        !           171:     if (!RegisterClass(&wc))
        !           172:        return FALSE;
        !           173: 
        !           174:     wc.lpfnWndProc     = (WNDPROC)ChildWndProc;
        !           175:     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
        !           176:     wc.lpszMenuName    = NULL;
        !           177:     wc.lpszClassName   = "ChildClass";
        !           178: 
        !           179:     if (!RegisterClass(&wc))
        !           180:         return FALSE;
        !           181: 
        !           182:     wc.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        !           183:     wc.lpfnWndProc     = (WNDPROC)TextWndProc;
        !           184:     wc.hIcon           = NULL;
        !           185:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        !           186:     wc.hbrBackground   = (HBRUSH)(COLOR_BTNSHADOW);
        !           187:     wc.lpszMenuName    = NULL;
        !           188:     wc.lpszClassName   = "Text";
        !           189: 
        !           190:     if (!RegisterClass(&wc))
        !           191:             return FALSE;
        !           192: 
        !           193:     wc.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        !           194:     wc.lpfnWndProc     = (WNDPROC)JuliaWndProc;
        !           195:     wc.hIcon           = NULL;
        !           196: 
        !           197:     //
        !           198:     // Nope.  Can't have this, screw up my Paint Can cursor
        !           199:     //
        !           200:     //wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        !           201: 
        !           202:     wc.hCursor          = NULL;
        !           203:     wc.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
        !           204:     wc.lpszMenuName    = NULL;
        !           205:     wc.lpszClassName   = "Julia";
        !           206: 
        !           207:     if (!RegisterClass(&wc))
        !           208:             return FALSE;
        !           209: 
        !           210: 
        !           211:     //
        !           212:     // Notice, submenu is zero-based
        !           213:     //
        !           214:     hMenu      = LoadMenu(ghModule, "MainMenu");
        !           215:     hChildMenu  = LoadMenu(ghModule, "ChildMenu");
        !           216:     hSubMenuOne = GetSubMenu(hMenu, 1);
        !           217:     hSubMenuThree = GetSubMenu(hChildMenu, 8);
        !           218:     hPrinterMenu = GetSubMenu(hChildMenu, 7);
        !           219: 
        !           220:     //
        !           221:     // Disable color-cycling for display devices that does not support
        !           222:     // palette like the VGA.  As as 29-May-1992, the MIPS display driver
        !           223:     // is the only one that supports palette
        !           224:     //
        !           225:     hDC = GetDC(NULL);
        !           226:     if (!((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE)) {
        !           227:         EnableMenuItem(hChildMenu, MM_CYCLE, MF_GRAYED);
        !           228:     }
        !           229: 
        !           230:     if ((iNumClr = iCreatePenFrPal(hDC, NULL)) != 0) {
        !           231:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
        !           232:         OutputDebugString( gtext);
        !           233: 
        !           234:         if ((gprghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !           235:             MessageBox(ghwndMain, "Failed in Memory Allocation for gprghPen!", "Error", MB_OK);
        !           236:         } else {
        !           237:             if ((*piPen = iCreatePenFrPal(hDC, gprghPen)) == 0)
        !           238:                 MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
        !           239:         }
        !           240:     }
        !           241: 
        !           242:     ReleaseDC(NULL, hDC);
        !           243: 
        !           244:     ghwndMain = CreateWindowEx(0L, "MandelClass", "Mandelbrot Dream",
        !           245:            WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
        !           246:            WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
        !           247:            WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
        !           248:            80, 70, 550, 550,
        !           249:            NULL, hMenu, ghModule, NULL);
        !           250: 
        !           251:     if (ghwndMain == NULL)
        !           252:        return FALSE;
        !           253: 
        !           254:     bInitPrinter(ghwndMain);
        !           255: 
        !           256:     SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
        !           257: 
        !           258:     SetFocus(ghwndMain);    /* set initial focus */
        !           259: 
        !           260:     return TRUE;
        !           261: }
        !           262: 
        !           263: 
        !           264: /******************************Public*Routine******************************\
        !           265: *
        !           266: * MainWndProc
        !           267: *
        !           268: * History:
        !           269: *  09-Sept-1991 -by- Petrus Wong
        !           270: * Wrote it.
        !           271: \**************************************************************************/
        !           272: 
        !           273: long MainWndProc(
        !           274:     HWND hwnd,
        !           275:     UINT message,
        !           276:     DWORD wParam,
        !           277:     LONG lParam)
        !           278: {
        !           279:     static int         iJuliaCount=1;
        !           280:     static int        iMandelCount=1;
        !           281:     CLIENTCREATESTRUCT clientcreate;
        !           282:     HWND               hwndChildWindow;
        !           283:     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
        !           284: 
        !           285: 
        !           286:     switch (message) {
        !           287: 
        !           288:       case WM_CREATE:
        !           289:        SetWindowLong(hwnd, 0, (LONG)NULL);
        !           290: 
        !           291:        clientcreate.hWindowMenu  = hSubMenuOne;
        !           292:        clientcreate.idFirstChild = 1;
        !           293: 
        !           294:        ghwndClient = CreateWindow("MDICLIENT", NULL,
        !           295:                                    WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
        !           296:                                    0,0,0,0,
        !           297:                                    hwnd, NULL, ghModule, (LPVOID)&clientcreate);
        !           298:         lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
        !           299:         lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
        !           300:         return 0L;
        !           301: 
        !           302:       case WM_DESTROY: {
        !           303:         bCleanupPrinter();
        !           304:        PostQuitMessage(0);
        !           305:        return 0L;
        !           306:       }
        !           307: 
        !           308:       //
        !           309:       // Wait! User is going to zero out our app's visible region.  This
        !           310:       // is going to mess up our drawing (we are not keeping any shadow
        !           311:       // bitmap in this version yet.) So, let's suspend our drawing thread
        !           312:       // first before user does that.  We will resume after user is done.
        !           313:       //
        !           314:       case WM_SYSCOMMAND: {
        !           315:         LONG        lResult;
        !           316: 
        !           317:         //
        !           318:         // We'll enumerate our children and suspend their drawing thread.
        !           319:         //
        !           320:         EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
        !           321: 
        !           322:         //
        !           323:         // Now, let user does it supposed to do
        !           324:         //
        !           325:         lResult = DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
        !           326: 
        !           327:         //
        !           328:         // User's done, we'll resume the suspended threads in our children
        !           329:         //
        !           330:         EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
        !           331: 
        !           332:         return lResult;
        !           333:         break;
        !           334:       }
        !           335: #if 0
        !           336:       //
        !           337:       // Our window's size is going to change, we'll make sure the new
        !           338:       // window is a square.
        !           339:       //
        !           340:       case WM_WINDOWPOSCHANGING: {
        !           341:             PWINDOWPOS pWndPos;
        !           342:             RECT       rect;
        !           343:             LONG       lcx, lcy;
        !           344: 
        !           345:             GetWindowRect(hwnd, &rect);
        !           346:             lcx = rect.right-rect.left;
        !           347:             lcy = rect.bottom-rect.top;
        !           348:             pWndPos = (PWINDOWPOS)lParam;
        !           349:             if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx))
        !           350:                 pWndPos->cx =  pWndPos->cy =
        !           351:                    ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy : pWndPos->cx);
        !           352:             else if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx))
        !           353:                      pWndPos->cx =  pWndPos->cy =
        !           354:                         ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy : pWndPos->cx);
        !           355:             break;
        !           356:       }
        !           357: #endif
        !           358:       case WM_COMMAND:
        !           359: 
        !           360:        switch (LOWORD(wParam)) {
        !           361:            case IDM_TILE:
        !           362:                SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
        !           363:                return 0L;
        !           364:            case IDM_CASCADE:
        !           365:                SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
        !           366:                return 0L;
        !           367:            case IDM_ARRANGE:
        !           368:                SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
        !           369:                return 0L;
        !           370: 
        !           371:             //
        !           372:             // Create Julia or Mandelbrot set
        !           373:             //
        !           374:            case MM_JULIA:
        !           375:            case MM_MANDEL: {
        !           376:                HANDLE hInfo;
        !           377:                PINFO  pInfo;
        !           378:                 MDICREATESTRUCT mdicreate;
        !           379: 
        !           380:                hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
        !           381:                if (hInfo == NULL) {
        !           382:                     MessageBox(ghwndMain, "Failed to Allocate Info!", "Error", MB_OK);
        !           383:                     return 0L;
        !           384:                 }
        !           385:                if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
        !           386:                    MessageBox(ghwndMain, "Failed in LocalLock, hInfo", "Error", MB_OK);
        !           387:                     return 0L;
        !           388:                 }
        !           389: 
        !           390:                 bInitInfo(pInfo);
        !           391:                 wsprintf((LPSTR) &(pInfo->CaptionBarText),
        !           392:                          (LOWORD(wParam) == MM_JULIA) ? "Julia %d" : "Mandelbrot %d",
        !           393:                          (LOWORD(wParam) == MM_JULIA) ? iJuliaCount : iMandelCount   );
        !           394:                 if (LOWORD(wParam) == MM_JULIA) {
        !           395:                     c1 = 0.360284;
        !           396:                     c2 = 0.100376;
        !           397:                     lc1 = 738;          //.3603515
        !           398:                     lc2 = 206;          //.1005859
        !           399:                     pInfo->bMandel = FALSE;
        !           400:                 } else {
        !           401:                     pInfo->bMandel = TRUE;
        !           402:                 }
        !           403: 
        !           404:                 //
        !           405:                 // Fill in the MDICREATE structure for MDI child creation
        !           406:                 //
        !           407:                mdicreate.szClass = "ChildClass";
        !           408:                 mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
        !           409:                 mdicreate.hOwner  = ghModule;
        !           410:                 mdicreate.x       =
        !           411:                 mdicreate.y       = CW_USEDEFAULT;
        !           412:                 mdicreate.cx      = 300;
        !           413:                 mdicreate.cy      = 300;
        !           414:                 mdicreate.style   = 0L;
        !           415:                 mdicreate.lParam  = (LONG) hInfo;
        !           416: 
        !           417:                 /*Create Child Window*/
        !           418:                 hwndChildWindow =
        !           419:                     (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
        !           420:                                 0L,
        !           421:                                 (LONG)(LPMDICREATESTRUCT)&mdicreate);
        !           422: 
        !           423:                 if (hwndChildWindow == NULL) {
        !           424:                     MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK);
        !           425:                     return 0L;
        !           426:                 }
        !           427: 
        !           428:                 (LOWORD(wParam) == MM_JULIA) ? iJuliaCount++ : iMandelCount++ ;
        !           429:                 LocalUnlock(hInfo);
        !           430:                return ((LONG)hwndChildWindow);
        !           431:            }
        !           432: 
        !           433:            case MM_ABOUT:
        !           434:                if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
        !           435:                        MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
        !           436:                return 0L;
        !           437: 
        !           438:             //
        !           439:             // Only my children know how to deal with these messages, so
        !           440:             // pass these to children for processing
        !           441:             //
        !           442:            case MM_CREATE_JULIA_THREAD:
        !           443:            case MM_SET_XFORM_ATTR:
        !           444:            case MM_CREATE_MANDEL_THREAD:
        !           445:            case MM_OPT_4:              // currently not used
        !           446:            case MM_DRAW_SET:
        !           447:             case MM_SETDIB2DEVICE:
        !           448:            case MM_BW:
        !           449:            case MM_SHIFT:
        !           450:            case MM_CUSTOM:
        !           451:             case MM_CYCLE:
        !           452:             case MM_FLOAT:
        !           453:             case MM_FIX:
        !           454:             case MM_ITERATION_TEN:
        !           455:             case MM_ITERATION_TWENTY:
        !           456:             case MM_ITERATION_THIRTY:
        !           457:             case MM_ITERATION_FIFTY:
        !           458:             case MM_ITERATION_DOUBLE:
        !           459:             case MM_STEP_ONE:
        !           460:             case MM_STEP_TWO:
        !           461:             case MM_STEP_THREE:
        !           462:             case MM_SAVE:
        !           463:             case MM_SAVE_MONO:
        !           464:             case MM_LOAD:
        !           465:             case MM_STRETCHBLT:
        !           466:             case MM_BITBLT:
        !           467:             case MM_BLACKONWHITE:
        !           468:             case MM_COLORONCOLOR:
        !           469:             case MM_WHITEONBLACK:
        !           470:             case MM_HALFTONE:
        !           471:             case MM_CLIP:
        !           472:             case MM_RM_CLIP:
        !           473:             case MM_ERASE:
        !           474:             case MM_PORTRAIT:
        !           475:             case MM_LANDSCAPE:
        !           476:             case MM_PRINTER:
        !           477:             case MM_PRINTER + 1:
        !           478:             case MM_PRINTER + 2:
        !           479:             case MM_PRINTER + 3:
        !           480:             case MM_PRINTER + 4:
        !           481:             case MM_PRINTER + 5:
        !           482:             case MM_PRINTER + 6:
        !           483:             case MM_PRINTER + 7:
        !           484:             case MM_PRINTER + 8:
        !           485:             case MM_PRINTER + 9:
        !           486:             {
        !           487:                HWND hActiveChild;
        !           488: 
        !           489:                hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
        !           490:                if (hActiveChild)
        !           491:                    SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
        !           492:                return 0L;
        !           493:            }
        !           494: 
        !           495:            default:
        !           496:                return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
        !           497:         }
        !           498:     default:
        !           499: 
        !           500:        return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
        !           501:     }
        !           502: }
        !           503: 
        !           504: /***************************************************************************\
        !           505: * ChildWndProc
        !           506: *
        !           507: * History:
        !           508: * 04-17-91 ????         Created.
        !           509: * 09-09-91 Petrus Wong Rewrote.
        !           510: \***************************************************************************/
        !           511: 
        !           512: long ChildWndProc(
        !           513:     HWND hwnd,
        !           514:     UINT message,
        !           515:     DWORD wParam,
        !           516:     LONG lParam)
        !           517: {
        !           518:     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
        !           519:     static BOOL        bDIB2Device = FALSE;
        !           520: 
        !           521:     sprintf( gtext,"message = %lx\n", message);
        !           522:     OutputDebugString( gtext);
        !           523: 
        !           524:     switch (message) {
        !           525: 
        !           526:        case WM_COMMAND: {
        !           527:           PINFO       pInfo;
        !           528:           HWND        hTextWnd;
        !           529: 
        !           530:          switch (LOWORD(wParam)) {
        !           531:             //
        !           532:             // Create a Julia drawing thread
        !           533:             //
        !           534:            case MM_CREATE_JULIA_THREAD: {
        !           535:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           536:                     return 0L;
        !           537:                 }
        !           538: 
        !           539:                 hTextWnd = pInfo->hTextWnd;
        !           540:                 sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
        !           541:                 SetWindowText(hTextWnd, gtext);
        !           542:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
        !           543:                 OutputDebugString( gtext );
        !           544: 
        !           545:                 pInfo->hThrd = CreateThread(NULL, 0,
        !           546:                                  (gFloat ? (LPTHREAD_START_ROUTINE)StartDraw : (LPTHREAD_START_ROUTINE)StartDrawFix),
        !           547:                                  pInfo,
        !           548:                                  STANDARD_RIGHTS_REQUIRED,
        !           549:                                  &pInfo->dwThreadId );
        !           550: 
        !           551:                bReleaseInfoData(hwnd);
        !           552:                return 0L;
        !           553:             }
        !           554: 
        !           555:             //
        !           556:             // Reset pInfo reflecting new transformation
        !           557:             //
        !           558:            case MM_SET_XFORM_ATTR: {
        !           559:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           560:                     return 0L;
        !           561:                 }
        !           562: 
        !           563:                 hTextWnd = pInfo->hTextWnd;
        !           564:                 SetWindowText(hTextWnd, "Click here for viewing info");
        !           565: 
        !           566:                 pInfo->xFrom      = xFrom;
        !           567:                 pInfo->xTo        = xTo;
        !           568:                 pInfo->yFrom      = yFrom;
        !           569:                 pInfo->yTo        = yTo;
        !           570:                 pInfo->c1         = c1;
        !           571:                 pInfo->c2         = c2;
        !           572:                 pInfo->lxFrom      = lxFrom;
        !           573:                 pInfo->lxTo        = lxTo;
        !           574:                 pInfo->lyFrom      = lyFrom;
        !           575:                 pInfo->lyTo        = lyTo;
        !           576:                 pInfo->lc1         = lc1;
        !           577:                 pInfo->lc2         = lc2;
        !           578: 
        !           579:                bReleaseInfoData(hwnd);
        !           580:               return 0L;
        !           581:            }
        !           582: 
        !           583:             //
        !           584:             // Create a Mandelbrot drawing thread
        !           585:             //
        !           586:            case MM_CREATE_MANDEL_THREAD: {
        !           587:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           588:                     return 0L;
        !           589:                 }
        !           590: 
        !           591:                 hTextWnd = pInfo->hTextWnd;
        !           592:                 sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
        !           593:                 SetWindowText(hTextWnd, gtext);
        !           594:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
        !           595:                 OutputDebugString( gtext );
        !           596: 
        !           597:                 pInfo->hThrd = CreateThread(NULL, 0,
        !           598:                                  (gFloat ? (LPTHREAD_START_ROUTINE)StartMandelbrot : (LPTHREAD_START_ROUTINE)StartMandelbrotFix),
        !           599:                                  pInfo,
        !           600:                                  STANDARD_RIGHTS_REQUIRED,
        !           601:                                  &pInfo->dwThreadId );
        !           602:                bReleaseInfoData(hwnd);
        !           603:                return 0L;
        !           604:            }
        !           605: 
        !           606:             //
        !           607:             // Create a Julia drawing thread using algorithm StartDraw2
        !           608:             // Currently not used
        !           609:             //
        !           610:            case MM_OPT_4: {
        !           611:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           612:                     return 0L;
        !           613:                 }
        !           614: 
        !           615:                 hTextWnd = pInfo->hTextWnd;
        !           616:                 SetWindowText(hTextWnd, "MM_OPT_4");
        !           617: 
        !           618:                 sprintf( gtext,"xFrom = %g, xTo = %g, yFrom = %g, yTo = %g\n", pInfo->xFrom, pInfo->xTo, pInfo->yFrom, pInfo->yTo);
        !           619:                 OutputDebugString( gtext );
        !           620: 
        !           621:                 pInfo->hThrd = CreateThread(NULL, 0,
        !           622:                                  (LPTHREAD_START_ROUTINE)StartDraw2,
        !           623:                                  pInfo,
        !           624:                                  STANDARD_RIGHTS_REQUIRED,
        !           625:                                  &pInfo->dwThreadId );
        !           626: 
        !           627:                bReleaseInfoData(hwnd);
        !           628:               return 0L;
        !           629:            }
        !           630: 
        !           631:             case MM_DRAW_SET: {
        !           632:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           633:                     return 0L;
        !           634:                 }
        !           635: 
        !           636:                 PostMessage(hwnd, WM_COMMAND,
        !           637:                     pInfo->bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
        !           638:                     (LONG)0L);
        !           639: 
        !           640:                bReleaseInfoData(hwnd);
        !           641:                return 0L;
        !           642:             }
        !           643: 
        !           644:             case MM_FLOAT: {
        !           645:                 bCheckMutexMenuItem(hChildMenu, MM_FLOAT);
        !           646:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           647:                 gFloat = TRUE;
        !           648:                 return 0L;
        !           649:             }
        !           650:             case MM_FIX: {
        !           651:                 bCheckMutexMenuItem(hChildMenu, MM_FIX);
        !           652:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           653:                 gFloat = FALSE;
        !           654:                 return 0L;
        !           655:             }
        !           656:             case MM_ITERATION_TEN: {
        !           657:                 bCheckMutexMenuItem(hChildMenu, MM_ITERATION_TEN);
        !           658:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           659:                 gIteration = 10;
        !           660:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           661:                     return 0L;
        !           662:                 }
        !           663:                 pInfo->iIteration = 10;
        !           664: 
        !           665:                 bReleaseInfoData(hwnd);
        !           666:                 return 0L;
        !           667:             }
        !           668:             case MM_ITERATION_TWENTY: {
        !           669:                 bCheckMutexMenuItem(hChildMenu, MM_ITERATION_TWENTY);
        !           670:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           671:                 gIteration = 20;
        !           672:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
        !           673:                     return 0L;
        !           674:                 }
        !           675: 
        !           676:                 pInfo->iIteration = 20;
        !           677: 
        !           678:                 bReleaseInfoData(hwnd);
        !           679:                 return 0L;
        !           680:             }
        !           681:             case MM_ITERATION_THIRTY: {
        !           682:                 bCheckMutexMenuItem(hChildMenu, MM_ITERATION_THIRTY);
        !           683:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           684:                 gIteration = 30;
        !           685:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           686:                     return 0L;
        !           687:                 }
        !           688:                 pInfo->iIteration = 30;
        !           689: 
        !           690:                 bReleaseInfoData(hwnd);
        !           691:                 return 0L;
        !           692:             }
        !           693:             case MM_ITERATION_FIFTY: {
        !           694:                 bCheckMutexMenuItem(hChildMenu, MM_ITERATION_FIFTY);
        !           695:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           696:                 gIteration = 50;
        !           697:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           698:                     return 0L;
        !           699:                 }
        !           700:                 pInfo->iIteration = 50;
        !           701: 
        !           702:                 bReleaseInfoData(hwnd);
        !           703:                 return 0L;
        !           704:             }
        !           705:             case MM_ITERATION_DOUBLE: {
        !           706:                 bCheckMutexMenuItem(hChildMenu, MM_ITERATION_DOUBLE);
        !           707:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           708:                 gIteration *= 2;
        !           709:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           710:                     return 0L;
        !           711:                 }
        !           712:                 pInfo->iIteration = gIteration;
        !           713: 
        !           714:                 bReleaseInfoData(hwnd);
        !           715:                 return 0L;
        !           716:             }
        !           717:             case MM_STEP_ONE: {
        !           718:                 bCheckMutexMenuItem(hChildMenu, MM_STEP_ONE);
        !           719:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           720:                 gStep = 1;
        !           721:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           722:                     return 0L;
        !           723:                 }
        !           724:                 pInfo->iStep = 1;
        !           725: 
        !           726:                 bReleaseInfoData(hwnd);
        !           727:                 return 0L;
        !           728:             }
        !           729:             case MM_STEP_TWO:  {
        !           730:                 bCheckMutexMenuItem(hChildMenu, MM_STEP_TWO);
        !           731:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           732:                 gStep = 2;
        !           733:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
        !           734:                     return 0L;
        !           735:                 }
        !           736:                 pInfo->iStep = 2;
        !           737: 
        !           738:                 bReleaseInfoData(hwnd);
        !           739:                 return 0L;
        !           740:             }
        !           741:             case MM_STEP_THREE: {
        !           742:                 bCheckMutexMenuItem(hChildMenu, MM_STEP_THREE);
        !           743:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           744:                 gStep = 3;
        !           745:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           746:                     return 0L;
        !           747:                 }
        !           748:                 pInfo->iStep = 3;
        !           749: 
        !           750:                 bReleaseInfoData(hwnd);
        !           751:                 return 0L;
        !           752:             }
        !           753: 
        !           754:             case MM_LOAD: {
        !           755:                 HDC hDC;
        !           756:                 OPENFILENAME ofn;
        !           757:                 char szDirName[256];
        !           758:                 char szFile[256], szFileTitle[256];
        !           759:                 static char *szFilter;
        !           760:                 RECT    rc;
        !           761: 
        !           762:                 szFilter =
        !           763:                   "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0";
        !           764: 
        !           765:                 GetSystemDirectory((LPSTR) szDirName, 256);
        !           766:                 strcpy(szFile, "*.bmp\0");
        !           767:                 ofn.lStructSize = sizeof(OPENFILENAME);
        !           768:                 ofn.hwndOwner = hwnd;
        !           769:                 ofn.lpstrFilter = szFilter;
        !           770:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
        !           771:                 ofn.nMaxCustFilter = 0L;
        !           772:                 ofn.nFilterIndex = 1;
        !           773:                 ofn.lpstrFile = szFile;
        !           774:                 ofn.nMaxFile = sizeof(szFile);
        !           775:                 ofn.lpstrFileTitle = szFileTitle;
        !           776:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
        !           777:                 ofn.lpstrInitialDir = szDirName;
        !           778:                 ofn.lpstrTitle = (LPSTR) NULL;
        !           779:                 ofn.Flags = 0L;
        !           780:                 ofn.nFileOffset = 0;
        !           781:                 ofn.nFileExtension = 0;
        !           782:                 ofn.lpstrDefExt = "BMP";
        !           783: 
        !           784:                 if (!GetOpenFileName(&ofn))
        !           785:                     return 0L;
        !           786:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
        !           787:                     return 0L;
        !           788:                 }
        !           789:                 GetClientRect(pInfo->hwnd, &rc);
        !           790:                 hDC = GetDC(pInfo->hwnd);
        !           791:                 if (LoadBitmapFile(hDC, pInfo, szFile))
        !           792:                   DrawBitmap(hDC, pInfo, 0, 0, rc.right, rc.bottom);
        !           793:                 ReleaseDC(hwnd, hDC);
        !           794: 
        !           795:                 bReleaseInfoData(hwnd);
        !           796: 
        !           797:                 return 0L;
        !           798:             }
        !           799: 
        !           800:             case MM_SAVE: {
        !           801:                 HDC hDC;
        !           802:                 OPENFILENAME ofn;
        !           803:                 char szDirName[256];
        !           804:                 char szFile[256], szFileTitle[256];
        !           805:                 static char *szFilter;
        !           806:                 szFilter = "DIB files (*.bmp)\0\0";
        !           807: 
        !           808:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           809:                     return 0L;
        !           810:                 }
        !           811:                 hDC = GetDC(pInfo->hwnd);
        !           812: 
        !           813:                 //
        !           814:                 // saving special effects user might have created in window
        !           815:                 //
        !           816:                 if (pInfo->hBmpSaved)
        !           817:                     DeleteObject(pInfo->hBmpSaved);
        !           818:                 pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
        !           819: 
        !           820:                 GetSystemDirectory((LPSTR) szDirName, 256);
        !           821:                 strcpy(szFile, "*.bmp\0");
        !           822:                 ofn.lStructSize = sizeof(OPENFILENAME);
        !           823:                 ofn.hwndOwner = hwnd;
        !           824:                 ofn.lpstrFilter = szFilter;
        !           825:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
        !           826:                 ofn.nMaxCustFilter = 0L;
        !           827:                 ofn.nFilterIndex = 0L;
        !           828:                 ofn.lpstrFile = szFile;
        !           829:                 ofn.nMaxFile = sizeof(szFile);
        !           830:                 ofn.lpstrFileTitle = szFileTitle;
        !           831:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
        !           832:                 ofn.lpstrInitialDir = szDirName;
        !           833:                 ofn.lpstrTitle = (LPSTR) NULL;
        !           834:                 ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
        !           835:                 ofn.nFileOffset = 0;
        !           836:                 ofn.nFileExtension = 0;
        !           837:                 ofn.lpstrDefExt = (LPSTR)NULL;
        !           838: 
        !           839:                 if (!GetSaveFileName(&ofn)) {
        !           840:                     ReleaseDC(pInfo->hwnd, hDC);
        !           841:                     bReleaseInfoData(hwnd);
        !           842:                     return 0L;
        !           843:                 }
        !           844: 
        !           845:                 SaveBitmapFile(hDC, pInfo->hBmpSaved, szFile);
        !           846:                 ReleaseDC(pInfo->hwnd, hDC);
        !           847: 
        !           848:                 bReleaseInfoData(hwnd);
        !           849:                 return 0L;
        !           850:             }
        !           851:             case MM_SAVE_MONO: {
        !           852:                 HDC hDC;
        !           853:                 OPENFILENAME ofn;
        !           854:                 char szDirName[256];
        !           855:                 char szFile[256], szFileTitle[256];
        !           856:                 static char *szFilter;
        !           857:                 szFilter = "DIB files (*.bmp)\0\0";
        !           858: 
        !           859:                 GetSystemDirectory((LPSTR) szDirName, 256);
        !           860:                 strcpy(szFile, "*.bmp\0");
        !           861:                 ofn.lStructSize = sizeof(OPENFILENAME);
        !           862:                 ofn.hwndOwner = hwnd;
        !           863:                 ofn.lpstrFilter = szFilter;
        !           864:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
        !           865:                 ofn.nMaxCustFilter = 0L;
        !           866:                 ofn.nFilterIndex = 0L;
        !           867:                 ofn.lpstrFile = szFile;
        !           868:                 ofn.nMaxFile = sizeof(szFile);
        !           869:                 ofn.lpstrFileTitle = szFileTitle;
        !           870:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
        !           871:                 ofn.lpstrInitialDir = szDirName;
        !           872:                 ofn.lpstrTitle = "Saving Monochrome Bitmap";
        !           873:                 ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
        !           874:                 ofn.nFileOffset = 0;
        !           875:                 ofn.nFileExtension = 0;
        !           876:                 ofn.lpstrDefExt = (LPSTR)NULL;
        !           877: 
        !           878:                 if (!GetSaveFileName(&ofn))
        !           879:                     return 0L;
        !           880:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           881:                     return 0L;
        !           882:                 }
        !           883:                 hDC = GetDC(pInfo->hwnd);
        !           884: 
        !           885:                 SaveBitmapFile(hDC, pInfo->hBmpMono, szFile);
        !           886:                 ReleaseDC(pInfo->hwnd, hDC);
        !           887: 
        !           888:                 bReleaseInfoData(hwnd);
        !           889:                 return 0L;
        !           890:             }
        !           891:             case MM_STRETCHBLT: {
        !           892:                 gbStretch = TRUE;
        !           893:                 bCheckMutexMenuItem(hChildMenu, MM_STRETCHBLT);
        !           894:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           895:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
        !           896:                     return 0L;
        !           897:                 }
        !           898:                 pInfo->bStretch = gbStretch;
        !           899:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !           900: 
        !           901:                 bReleaseInfoData(hwnd);
        !           902:                 return 0L;
        !           903: 
        !           904:             }
        !           905:             case MM_BITBLT: {
        !           906:                 gbStretch = FALSE;
        !           907:                 bCheckMutexMenuItem(hChildMenu, MM_BITBLT);
        !           908:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           909:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           910:                     return 0L;
        !           911:                 }
        !           912:                 pInfo->bStretch = gbStretch;
        !           913:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !           914: 
        !           915:                 bReleaseInfoData(hwnd);
        !           916:                 return 0L;
        !           917: 
        !           918:             }
        !           919:             case MM_BLACKONWHITE: {
        !           920:                 giStretchMode = BLACKONWHITE;
        !           921:                 bCheckMutexMenuItem(hChildMenu, MM_BLACKONWHITE);
        !           922:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           923:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           924:                     return 0L;
        !           925:                 }
        !           926:                 pInfo->iStretchMode = giStretchMode;
        !           927:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !           928: 
        !           929:                 bReleaseInfoData(hwnd);
        !           930:                 return 0L;
        !           931: 
        !           932:             }
        !           933:             case MM_COLORONCOLOR: {
        !           934:                 giStretchMode = COLORONCOLOR;
        !           935:                 bCheckMutexMenuItem(hChildMenu, MM_COLORONCOLOR);
        !           936:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           937:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           938:                     return 0L;
        !           939:                 }
        !           940:                 pInfo->iStretchMode = giStretchMode;
        !           941:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !           942: 
        !           943:                 bReleaseInfoData(hwnd);
        !           944:                 return 0L;
        !           945: 
        !           946:             }
        !           947:             case MM_WHITEONBLACK: {
        !           948:                 giStretchMode = WHITEONBLACK;
        !           949:                 bCheckMutexMenuItem(hChildMenu, MM_WHITEONBLACK);
        !           950:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           951:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           952:                     return 0L;
        !           953:                 }
        !           954:                 pInfo->iStretchMode = giStretchMode;
        !           955:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !           956: 
        !           957:                 bReleaseInfoData(hwnd);
        !           958:                 return 0L;
        !           959: 
        !           960:             }
        !           961:             case MM_HALFTONE: {
        !           962:                 giStretchMode = HALFTONE;
        !           963:                 bCheckMutexMenuItem(hChildMenu, MM_HALFTONE);
        !           964:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           965:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           966:                     return 0L;
        !           967:                 }
        !           968:                 pInfo->iStretchMode = giStretchMode;
        !           969:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !           970: 
        !           971:                 bReleaseInfoData(hwnd);
        !           972:                 return 0L;
        !           973:             }
        !           974:             case MM_SETDIB2DEVICE: {
        !           975:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           976:                     return 0L;
        !           977:                 }
        !           978:                 bDIB2Device = (bDIB2Device ? FALSE : TRUE);
        !           979:                 pInfo->bSetDIBsToDevice = bDIB2Device;
        !           980:                 CheckMenuItem(hChildMenu, MM_SETDIB2DEVICE, (bDIB2Device ? MF_CHECKED : MF_UNCHECKED));
        !           981:                 bReleaseInfoData(hwnd);
        !           982:                 return 0L;
        !           983:             }
        !           984:            case MM_BW: {
        !           985:                 HDC hDC;
        !           986: 
        !           987:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           988:                     return 0L;
        !           989:                 }
        !           990:                 hDC = GetDC(pInfo->hwnd);
        !           991:                 bChangeDIBColor(hDC, pInfo, MM_BW);
        !           992:                 ReleaseDC(hwnd, hDC);
        !           993:                 bReleaseInfoData(hwnd);
        !           994:                 return 0L;
        !           995:             }
        !           996:            case MM_SHIFT: {
        !           997:                 HDC hDC;
        !           998: 
        !           999:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1000:                     return 0L;
        !          1001:                 }
        !          1002:                 hDC = GetDC(pInfo->hwnd);
        !          1003:                 bChangeDIBColor(hDC, pInfo, MM_SHIFT);
        !          1004:                 ReleaseDC(hwnd, hDC);
        !          1005:                 bReleaseInfoData(hwnd);
        !          1006:                 return 0L;
        !          1007:             }
        !          1008:            case MM_CUSTOM: {
        !          1009:                 static DWORD argbCust[16] = {
        !          1010:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1011:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1012:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1013:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1014:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1015:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1016:                     RGB(255, 255, 255), RGB(255, 255, 255),
        !          1017:                     RGB(255, 255, 255), RGB(255, 255, 255)
        !          1018:                 };
        !          1019:                 CHOOSECOLOR cc;
        !          1020:                 BOOL bResult;
        !          1021:                 DWORD rgbOld;
        !          1022:                 HBRUSH hBrush;
        !          1023:                 HDC hDC;
        !          1024: 
        !          1025:                 rgbOld = RGB(255, 255, 255);
        !          1026:                 cc.lStructSize = sizeof(CHOOSECOLOR);
        !          1027:                 cc.hwndOwner = ghwndMain;
        !          1028:                 cc.hInstance = ghModule;
        !          1029:                 cc.rgbResult = rgbOld;
        !          1030:                 cc.lpCustColors = argbCust;
        !          1031:                 cc.Flags = CC_RGBINIT | CC_SHOWHELP;
        !          1032:                 cc.lCustData = 0;
        !          1033:                 cc.lpfnHook = NULL;
        !          1034:                 cc.lpTemplateName = NULL;
        !          1035: 
        !          1036:                 bResult = ChooseColor(&cc);
        !          1037:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1038:                     return 0L;
        !          1039:                 }
        !          1040:                 if (bResult) {
        !          1041:                     hDC = GetDC(pInfo->hwnd);
        !          1042:                     hBrush = hBrCreateBrush(hDC, cc.rgbResult);
        !          1043:                     ReleaseDC(pInfo->hwnd, hDC);
        !          1044:                     if (pInfo->hBrush)
        !          1045:                         DeleteObject(pInfo->hBrush);
        !          1046:                     pInfo->hBrush = hBrush;
        !          1047:                     pInfo->bFill = TRUE;
        !          1048:                 }
        !          1049:                 bReleaseInfoData(hwnd);
        !          1050:                 return 0L;
        !          1051:                 }
        !          1052: 
        !          1053: #ifndef CYCLETHRD
        !          1054:             case MM_CYCLE: {
        !          1055:                 HDC hDC;
        !          1056: 
        !          1057:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1058:                     return 0L;
        !          1059:                 }
        !          1060:                 hDC = GetDC(pInfo->hwnd);
        !          1061: 
        !          1062:                 if (pInfo->bClrCycle) {
        !          1063:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
        !          1064:                     pInfo->bClrCycle = FALSE;
        !          1065:                 } else {
        !          1066:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
        !          1067:                     pInfo->bClrCycle = TRUE;
        !          1068:                     bChangeDIBColor(hDC, pInfo, MM_CYCLE);
        !          1069:                 }
        !          1070: 
        !          1071:                 ReleaseDC(hwnd, hDC);
        !          1072:                 bReleaseInfoData(hwnd);
        !          1073:                 return 0L;
        !          1074:             }
        !          1075: #else
        !          1076: 
        !          1077:             case MM_CYCLE: {
        !          1078:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1079:                     return 0L;
        !          1080:                 }
        !          1081: 
        !          1082:                 if (pInfo->bFirstTime) {
        !          1083:                     if (!SetEvent(pInfo->hQuitEvent)) {
        !          1084:                         MessageBox(ghwndMain, "Can't set Quit Event!",
        !          1085:                                    "Error", MB_OK);
        !          1086:                         return 0L;
        !          1087:                     }
        !          1088: 
        !          1089:                     pInfo->hCycleThrd = CreateThread(NULL, 0,
        !          1090:                                      (LPTHREAD_START_ROUTINE)bCycle,
        !          1091:                                      hwnd,
        !          1092:                                      STANDARD_RIGHTS_REQUIRED,
        !          1093:                                      &pInfo->dwCycleThrdID );
        !          1094:                     pInfo->bClrCycle = TRUE;
        !          1095:                     pInfo->bFirstTime = FALSE;
        !          1096:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
        !          1097:                 } else {
        !          1098:                     if (pInfo->bClrCycle) {
        !          1099:                         CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
        !          1100:                         pInfo->bClrCycle = FALSE;
        !          1101:                         pInfo->dwSuspend = SuspendThread(pInfo->hCycleThrd);
        !          1102:                     } else {
        !          1103:                         CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
        !          1104:                         pInfo->bClrCycle = TRUE;
        !          1105:                         pInfo->dwSuspend = ResumeThread(pInfo->hCycleThrd);
        !          1106:                     }
        !          1107:                     if (pInfo->dwSuspend == -1) {
        !          1108:                         (pInfo->bClrCycle ?
        !          1109:                          sprintf( gtext,"Error in resuming thread\n") :
        !          1110:                          sprintf( gtext,"Error in suspending thread\n")  );
        !          1111:                         OutputDebugString( gtext );
        !          1112:                     }
        !          1113:                 }
        !          1114: 
        !          1115:                 bReleaseInfoData(hwnd);
        !          1116:                 return 0L;
        !          1117:             }
        !          1118: #endif
        !          1119:             case MM_CLIP: {
        !          1120:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1121:                     return 0L;
        !          1122:                 }
        !          1123: 
        !          1124:                 hTextWnd = pInfo->hTextWnd;
        !          1125:                 sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
        !          1126:                 SetWindowText(hTextWnd, gtext);
        !          1127:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
        !          1128:                 OutputDebugString( gtext );
        !          1129:                 if (!pInfo->bMandel) {
        !          1130:                     MessageBox(ghwndMain, "Boundary Tracing and Setting clip region to the boundary points only works for Mandelbrot Set.", "Error", MB_OK);
        !          1131:                     return 0L;
        !          1132:                 }
        !          1133:                 pInfo->hThrd = CreateThread(NULL, 0,
        !          1134:                                  (gFloat ? (LPTHREAD_START_ROUTINE)bBoundaryScanFix : (LPTHREAD_START_ROUTINE)bBoundaryScanFix),
        !          1135:                                  pInfo,
        !          1136:                                  STANDARD_RIGHTS_REQUIRED,
        !          1137:                                  &pInfo->dwThreadId );
        !          1138: 
        !          1139:                bReleaseInfoData(hwnd);
        !          1140:                return 0L;
        !          1141:            }
        !          1142:             case MM_RM_CLIP: {
        !          1143:                 HDC     hDC;
        !          1144: 
        !          1145:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1146:                     return 0L;
        !          1147:                 }
        !          1148: 
        !          1149:                 hDC = GetDC(pInfo->hwnd);
        !          1150:                 SelectClipRgn(hDC, (HRGN) NULL);
        !          1151:                 ReleaseDC(pInfo->hwnd, hDC);
        !          1152:                 bReleaseInfoData(hwnd);
        !          1153:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
        !          1154:                 return 0L;
        !          1155: 
        !          1156:             }
        !          1157:             case MM_ERASE: {
        !          1158:                 HDC     hDC;
        !          1159:                 RECT    rc;
        !          1160: 
        !          1161:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1162:                     return 0L;
        !          1163:                 }
        !          1164:                 hDC = GetDC(pInfo->hwnd);
        !          1165:                 if (pInfo->hRgnPath != (HRGN) NULL) {
        !          1166:                     SelectClipRgn(hDC, pInfo->hRgnPath);
        !          1167:                 }
        !          1168:                 SelectObject(hDC, GetStockObject(WHITE_BRUSH));
        !          1169:                 GetClientRect(pInfo->hwnd, &rc);
        !          1170:                 PatBlt(hDC, 0, 0, rc.right, rc.bottom, PATCOPY);
        !          1171:                 ReleaseDC(pInfo->hwnd, hDC);
        !          1172:                 bReleaseInfoData(hwnd);
        !          1173:                 return 0L;
        !          1174:             }
        !          1175:             case MM_PORTRAIT: {
        !          1176:                 giDmOrient = DMORIENT_PORTRAIT;
        !          1177:                 bCheckMutexMenuItem(hChildMenu, MM_PORTRAIT);
        !          1178:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          1179:                 return 0L;
        !          1180:             }
        !          1181:             case MM_LANDSCAPE: {
        !          1182:                 giDmOrient = DMORIENT_LANDSCAPE;
        !          1183:                 bCheckMutexMenuItem(hChildMenu, MM_LANDSCAPE);
        !          1184:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          1185:                 return 0L;
        !          1186:             }
        !          1187:             case MM_PRINTER:
        !          1188:             case MM_PRINTER + 1:
        !          1189:             case MM_PRINTER + 2:
        !          1190:             case MM_PRINTER + 3:
        !          1191:             case MM_PRINTER + 4:
        !          1192:             case MM_PRINTER + 5:
        !          1193:             case MM_PRINTER + 6:
        !          1194:             case MM_PRINTER + 7:
        !          1195:             case MM_PRINTER + 8:
        !          1196: 
        !          1197: #ifdef PRTTHRD
        !          1198:             case MM_PRINTER + 9: {
        !          1199:                 PINFO       pInfo;
        !          1200:                 PRTDATA     PrtData, *pPrtData;
        !          1201:                 ULONG       sizINFO;
        !          1202:                 PBYTE       pjTmpInfo, pjTmp;
        !          1203: 
        !          1204:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1205:                     return 0L;
        !          1206:                 }
        !          1207: 
        !          1208:                 if (pInfo->hBmpSaved == NULL) {
        !          1209:                     MessageBox(ghwndMain, "No Saved bitmap to print", "Error", MB_OK);
        !          1210:                     return 0L;
        !          1211:                 }
        !          1212: 
        !          1213:                 //
        !          1214:                 // Copy the info structure to PrtData
        !          1215:                 //
        !          1216:                 pPrtData = &PrtData;
        !          1217:                 pjTmp    = (PBYTE)&(pPrtData->info);
        !          1218:                 pjTmpInfo = (PBYTE)pInfo;
        !          1219:                 sizINFO = sizeof(INFO);
        !          1220: 
        !          1221:                 while(sizINFO--)
        !          1222:                 {
        !          1223:                     *(((PBYTE)pjTmp)++) = *((pjTmpInfo)++);
        !          1224:                 }
        !          1225: 
        !          1226:                 PrtData.index = LOWORD(wParam) - MM_PRINTER;
        !          1227: 
        !          1228:                 if (giDmOrient == DMORIENT_PORTRAIT) {
        !          1229:                     PrtData.bUseDefault = TRUE;
        !          1230:                 } else {
        !          1231:                     PrtData.bUseDefault = FALSE;
        !          1232:                     PrtData.DevMode.dmSize = sizeof(DEVMODE);
        !          1233:                     PrtData.DevMode.dmDriverExtra = 0;
        !          1234:                     PrtData.DevMode.dmOrientation = DMORIENT_LANDSCAPE;
        !          1235:                     PrtData.DevMode.dmFields = DM_ORIENTATION;
        !          1236:                 }
        !          1237: 
        !          1238:                 pInfo->hPrtThrd = CreateThread(NULL, 0,
        !          1239:                                  (LPTHREAD_START_ROUTINE)bPrintBmp,
        !          1240:                                  &PrtData,
        !          1241:                                  STANDARD_RIGHTS_REQUIRED,
        !          1242:                                  &pInfo->dwPrtThrdID );
        !          1243: 
        !          1244:                 bReleaseInfoData(hwnd);
        !          1245:                 return 0L;
        !          1246:             }
        !          1247: 
        !          1248: #else
        !          1249:             case MM_PRINTER + 9: {
        !          1250:                 HDC         hdcPrinter, hDC;
        !          1251:                 int         index;
        !          1252:                 DEVMODE     devmode;
        !          1253:                 DEVMODE     *pdevmode;
        !          1254:                 PINFO       pInfo;
        !          1255:                 int         iWidth, iHeight;
        !          1256: 
        !          1257: 
        !          1258:                 index = LOWORD(wParam) - MM_PRINTER;
        !          1259: 
        !          1260:                 if (giDmOrient == DMORIENT_PORTRAIT)
        !          1261:                     pdevmode = NULL;
        !          1262:                 else {
        !          1263:                     pdevmode = &devmode;
        !          1264:                     devmode.dmSize = sizeof(DEVMODE);
        !          1265:                     devmode.dmDriverExtra = 0;
        !          1266:                     devmode.dmOrientation = DMORIENT_LANDSCAPE;
        !          1267:                     devmode.dmFields = DM_ORIENTATION;
        !          1268:                 }
        !          1269: 
        !          1270:                 if (!(hdcPrinter = CreateDC( "", gpszPrinterNames[index],
        !          1271:                                              "", pdevmode)))
        !          1272:                 {
        !          1273:                     return(0L);
        !          1274:                 }
        !          1275: 
        !          1276:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1277:                     return 0L;
        !          1278:                 }
        !          1279: 
        !          1280:                 iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
        !          1281:                 iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
        !          1282: 
        !          1283:                 if (pInfo->hBmpSaved)
        !          1284:                     DeleteObject(pInfo->hBmpSaved);
        !          1285: 
        !          1286:                 pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
        !          1287: 
        !          1288:                Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
        !          1289:                 DrawBitmap(hdcPrinter, pInfo, 0, 0, iWidth, iHeight);
        !          1290:                 Escape(hdcPrinter, NEWFRAME, NULL, NULL, NULL);
        !          1291:                 Escape(hdcPrinter, ENDDOC, NULL, NULL, NULL);
        !          1292:                 ReleaseDC(pInfo->hwnd, hDC);
        !          1293:                 bReleaseInfoData(hwnd);
        !          1294:                 DeleteDC(hdcPrinter);
        !          1295:                 return 0L;
        !          1296:             }
        !          1297: #endif
        !          1298:             default:
        !          1299:                return 0L;
        !          1300: 
        !          1301:          }
        !          1302: 
        !          1303:        }
        !          1304:        case WM_SETFOCUS:
        !          1305:            break;
        !          1306: 
        !          1307:        case WM_MDIACTIVATE: {
        !          1308:             PINFO       pInfo;
        !          1309: 
        !          1310:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1311:                 return 0L;
        !          1312:             }
        !          1313: 
        !          1314:            if ((HWND) lParam == hwnd) {
        !          1315:                SendMessage(GetParent(hwnd), WM_MDISETMENU,
        !          1316:                            (DWORD)  hChildMenu,
        !          1317:                            (LONG)   hSubMenuThree) ;
        !          1318:                DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          1319: 
        !          1320:                 (pInfo->bClrCycle ?
        !          1321:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED) :
        !          1322:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED) );
        !          1323:            }
        !          1324: 
        !          1325:             bReleaseInfoData(hwnd);
        !          1326:            return 0L;
        !          1327:         }
        !          1328: #if 0
        !          1329:         case WM_WINDOWPOSCHANGING: {
        !          1330:             PWINDOWPOS  pWndPos;
        !          1331:             PINFO       pInfo;
        !          1332:             HWND        hTextWnd;
        !          1333:             int         iCyText, iCxBorder, iCyBorder, iCyCaption;
        !          1334:             RECT        rect, rcl;
        !          1335:             LONG        lcx, lcy;
        !          1336: 
        !          1337:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1338:                 break;
        !          1339:             }
        !          1340: 
        !          1341:             hTextWnd = pInfo->hTextWnd;
        !          1342: 
        !          1343:             bReleaseInfoData(hwnd);
        !          1344: 
        !          1345:             iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
        !          1346:             iCxBorder = GetSystemMetrics(SM_CXBORDER);
        !          1347:             iCyBorder = GetSystemMetrics(SM_CYBORDER);
        !          1348:             iCyCaption = GetSystemMetrics(SM_CYCAPTION) - iCyBorder;
        !          1349:             GetClientRect(GetParent(hwnd), &rcl);
        !          1350:             GetWindowRect(hwnd, &rect);
        !          1351:             lcx = rect.right-rect.left;
        !          1352:             lcy = rect.bottom-rect.top;
        !          1353:             pWndPos = (PWINDOWPOS)lParam;
        !          1354:             if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx)) {
        !          1355:                 pWndPos->cx =
        !          1356:                    ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
        !          1357:                 pWndPos->cy = pWndPos->cx + iCyText;
        !          1358:             } else { if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx)) {
        !          1359:                      pWndPos->cx =
        !          1360:                         ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
        !          1361:                      pWndPos->cy = pWndPos->cx + iCyText;
        !          1362:                    }
        !          1363:             }
        !          1364:             break;
        !          1365:         }
        !          1366: #endif
        !          1367:        case WM_SIZE: {
        !          1368:             HANDLE      hThrd;
        !          1369:             PINFO       pInfo;
        !          1370:             HWND        hTextWnd, hJulia;
        !          1371:             BOOL        bMandel;
        !          1372:             WORD        wCx;
        !          1373:             int         iCyText;
        !          1374: 
        !          1375:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1376:                 break;
        !          1377:             }
        !          1378: 
        !          1379:             hTextWnd = pInfo->hTextWnd;
        !          1380:             hJulia   = pInfo->hwnd;
        !          1381:             hThrd    = pInfo->hThrd;
        !          1382:             bMandel  = pInfo->bMandel;
        !          1383:             bReleaseInfoData(hwnd);
        !          1384:             iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
        !          1385:             wCx = (WORD) (HIWORD(lParam) - iCyText);
        !          1386: 
        !          1387:             MoveWindow(hJulia, 0, 0,
        !          1388:                           LOWORD(lParam),
        !          1389:                            wCx,
        !          1390:                           TRUE);
        !          1391: 
        !          1392:            MoveWindow(hTextWnd,
        !          1393:                       0,
        !          1394:                       wCx,
        !          1395:                       LOWORD(lParam),
        !          1396:                        iCyText,
        !          1397:                       TRUE);
        !          1398: 
        !          1399:             if (hThrd) {
        !          1400:                 TerminateThread(hThrd, (DWORD)0L);
        !          1401:                 /*
        !          1402:                 PostMessage(hwnd, WM_COMMAND,
        !          1403:                     bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
        !          1404:                     (LONG)0L);
        !          1405:                   */
        !          1406:             }
        !          1407: 
        !          1408:            break;
        !          1409:         }
        !          1410: 
        !          1411:         //
        !          1412:         // display info in the status window
        !          1413:         //
        !          1414:         case WM_USER+0xa: {
        !          1415:             PINFO       pInfo;
        !          1416:             static ULONG ulClick = 0;
        !          1417:             HWND        hTextWnd;
        !          1418: 
        !          1419:             ulClick++;
        !          1420:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1421:                 return 0L;
        !          1422:             }
        !          1423: 
        !          1424:             hTextWnd = pInfo->hTextWnd;
        !          1425:             switch (ulClick % 6) {
        !          1426:                 case 0: sprintf( gtext,"%g <= x <= %g, %g <= y <= %g", pInfo->xFrom, pInfo->xTo, pInfo->yTo, pInfo->yFrom);
        !          1427:                         break;
        !          1428:                 case 1: sprintf( gtext,"c1 = %g, c2 = %g", pInfo->c1, pInfo->c2);
        !          1429:                         break;
        !          1430:                 case 2: sprintf( gtext,"Elapsed Time = %ld", (ULONG) pInfo->dwElapsed);
        !          1431:                         break;
        !          1432:                 case 3: sprintf( gtext,"Iteration = %d", pInfo->iIteration);
        !          1433:                         break;
        !          1434:                 case 4: sprintf( gtext,"Step = %d", pInfo->iStep);
        !          1435:                         break;
        !          1436:                 case 5: (gFloat ? sprintf( gtext,"Floating point math")
        !          1437:                                        : sprintf( gtext,"Fix point math")) ;
        !          1438:                         break;
        !          1439: 
        !          1440:                 default: break;
        !          1441:             }
        !          1442:             SetWindowText(hTextWnd, gtext);
        !          1443:             bReleaseInfoData(hwnd);
        !          1444:             return 0L;
        !          1445:         }
        !          1446: 
        !          1447:         case WM_SYSCOMMAND: {
        !          1448:             LONG        lResult;
        !          1449: 
        !          1450:             EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
        !          1451: 
        !          1452:             lResult = DefMDIChildProc(hwnd, message, wParam, lParam);
        !          1453: 
        !          1454:             EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
        !          1455: 
        !          1456:             return lResult;
        !          1457:             break;
        !          1458:         }
        !          1459: 
        !          1460:        case WM_CREATE: {
        !          1461:             PINFO           pInfo;
        !          1462:             HANDLE          hInfo;
        !          1463:             HWND            hTextWnd, hJulia;
        !          1464:            RECT            rcl;
        !          1465: 
        !          1466:             //
        !          1467:             // CR! MakeProcInstance is noop!
        !          1468:             //
        !          1469:             lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
        !          1470:             lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
        !          1471: 
        !          1472:             hTextWnd = CreateWindow("Text", NULL,
        !          1473:                                     WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
        !          1474:                                     0, 0, 0, 0,
        !          1475:                                     hwnd,
        !          1476:                                     (HMENU) 2,
        !          1477:                                     ghModule,
        !          1478:                                     NULL);
        !          1479: 
        !          1480:             GetClientRect(hwnd, &rcl);
        !          1481:             hJulia = CreateWindow("Julia", (LPSTR) NULL,
        !          1482:                           WS_CHILD      | WS_VISIBLE     |
        !          1483:                           WS_BORDER,
        !          1484:                           0,0, rcl.right-rcl.left,
        !          1485:                           rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
        !          1486:                           hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
        !          1487: 
        !          1488:             SetWindowText(hTextWnd, "Select the 'Draw Set' menu item to start drawing.");
        !          1489:             hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
        !          1490:             if (hInfo) {
        !          1491:                 if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
        !          1492:                     MessageBox(ghwndMain, "Failed in LocalLock, hNode", "Error", MB_OK);
        !          1493:                     break;
        !          1494:                 } else {
        !          1495:                     if (!GetClientRect(hwnd, &pInfo->rcClient))
        !          1496:                         MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK);
        !          1497: 
        !          1498:                     pInfo->hTextWnd = hTextWnd;
        !          1499:                     pInfo->hwnd = hJulia;
        !          1500: #ifdef CYCLETHRD
        !          1501:                     //
        !          1502:                     // Creating a signal quit color cycling event
        !          1503:                     //
        !          1504:                     if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
        !          1505:                         MessageBox(ghwndMain, "Failed in creating Quit Event!", "Error", MB_OK);
        !          1506: #endif
        !          1507:                     SetWindowLong(hwnd, 0, (LONG) hInfo);
        !          1508:                     LocalUnlock(hInfo);
        !          1509:                 }
        !          1510:            } else {
        !          1511:                MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK);
        !          1512:            }
        !          1513: 
        !          1514: #if 0
        !          1515:             //
        !          1516:             // Initialize printers here will detect printers availiability
        !          1517:             // more often, but kind of overkill.
        !          1518:             //
        !          1519:             bInitPrinter(hwnd);
        !          1520: #endif
        !          1521:             break;
        !          1522:        }
        !          1523: 
        !          1524:         case WM_CLOSE: {
        !          1525:            SendMessage(GetParent(hwnd), WM_MDISETMENU,
        !          1526:                            (DWORD) hMenu,
        !          1527:                            (LONG)  hSubMenuOne) ;
        !          1528:            DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          1529:             break;
        !          1530:         }
        !          1531: 
        !          1532:         case WM_DESTROY: {
        !          1533:             PINFO            pInfo;
        !          1534:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1535:                 break;
        !          1536:             }
        !          1537: 
        !          1538:             TerminateThread(pInfo->hThrd, (DWORD)0L);
        !          1539:             TerminateThread(pInfo->hPrtThrd, (DWORD)0L);
        !          1540: 
        !          1541: #ifdef CYCLETHRD
        !          1542:             //
        !          1543:             // Cleanup color cycling
        !          1544:             //
        !          1545:             if (!ResetEvent(pInfo->hQuitEvent))
        !          1546:                 MessageBox(ghwndMain, "Failed in reseting quit event!", "Error", MB_OK);
        !          1547: #endif
        !          1548:             if (pInfo->hBmpMono)
        !          1549:                 DeleteObject(pInfo->hBmpMono);
        !          1550: 
        !          1551:             if (pInfo->hBmpSaved)
        !          1552:                 DeleteObject(pInfo->hBmpSaved);
        !          1553: 
        !          1554:             if (pInfo->hBrush)
        !          1555:                 DeleteObject(pInfo->hBrush);
        !          1556: 
        !          1557:             bReleaseInfoData(hwnd);
        !          1558:             LocalFree((HANDLE) GetWindowLong(hwnd, 0));
        !          1559:             break;
        !          1560:        }
        !          1561: 
        !          1562:        default:
        !          1563:            return DefMDIChildProc(hwnd, message, wParam, lParam);
        !          1564: 
        !          1565:     } //switch
        !          1566:     return DefMDIChildProc(hwnd, message, wParam, lParam);
        !          1567: }
        !          1568: 
        !          1569: /***************************************************************************\
        !          1570: * About
        !          1571: *
        !          1572: * About dialog proc.
        !          1573: *
        !          1574: * History:
        !          1575: * 04-13-91 ????         Created.
        !          1576: * 09-09-91 Petrus Wong Rewrote.
        !          1577: \***************************************************************************/
        !          1578: 
        !          1579: long About(
        !          1580:     HWND hDlg,
        !          1581:     UINT message,
        !          1582:     DWORD wParam,
        !          1583:     LONG lParam)
        !          1584: {
        !          1585:     switch (message) {
        !          1586:     case WM_INITDIALOG:
        !          1587:         return TRUE;
        !          1588: 
        !          1589:     case WM_COMMAND:
        !          1590:         if (wParam == IDOK)
        !          1591:             EndDialog(hDlg, wParam);
        !          1592:         break;
        !          1593:     }
        !          1594: 
        !          1595:     return FALSE;
        !          1596: 
        !          1597:     UNREFERENCED_PARAMETER(lParam);
        !          1598:     UNREFERENCED_PARAMETER(hDlg);
        !          1599: }
        !          1600: 
        !          1601: /*************************************************************************
        !          1602: *
        !          1603: * TextWndProc
        !          1604: *
        !          1605: * Text Window proc.
        !          1606: *
        !          1607: * History:
        !          1608: * 10-07-91  Petrus Wong        Created.
        !          1609: *
        !          1610: \***************************************************************************/
        !          1611: 
        !          1612: LONG TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
        !          1613: {
        !          1614:     static HFONT hFont = (HFONT) NULL;
        !          1615: 
        !          1616:     switch (message)
        !          1617:     {
        !          1618:     case WM_CREATE:
        !          1619:         {
        !          1620:            LOGFONT    lf;
        !          1621:            HDC        hDC;
        !          1622:            HFONT      hOldFont;
        !          1623:             TEXTMETRIC tm;
        !          1624:            RECT       rect;
        !          1625:            LONG       lHeight;
        !          1626: 
        !          1627:             SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, FALSE);
        !          1628: 
        !          1629:            hDC = GetDC(hwnd);
        !          1630:            // this is the height for 8 point size font in pixels
        !          1631:            lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
        !          1632: 
        !          1633:            hFont = CreateFontIndirect(&lf);
        !          1634:            hOldFont = SelectObject(hDC, hFont);
        !          1635:            GetTextMetrics(hDC, &tm);
        !          1636:            GetClientRect(GetParent(hwnd), &rect);
        !          1637: 
        !          1638:            // base the height of the window on size of text
        !          1639:            lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
        !          1640:            // saved the height for later reference
        !          1641:            SetWindowLong(hwnd, GWL_USERDATA, lHeight);
        !          1642:            SetWindowPos(hwnd, NULL,
        !          1643:                    0,
        !          1644:                    rect.bottom-lHeight,
        !          1645:                    rect.right-rect.left,
        !          1646:                    lHeight,
        !          1647:                    SWP_NOZORDER | SWP_NOMOVE);
        !          1648: 
        !          1649:             ReleaseDC(hwnd, hDC);
        !          1650:             break;
        !          1651:         }
        !          1652: 
        !          1653:     case WM_LBUTTONDOWN: {
        !          1654:         PostMessage(GetParent(hwnd), WM_USER+0xa, (DWORD)0L, (LONG)0L);
        !          1655:         break;
        !          1656:     }
        !          1657: 
        !          1658:     case WM_DESTROY:
        !          1659:            if (hFont)
        !          1660:                DeleteObject(hFont);
        !          1661:            break;
        !          1662: 
        !          1663:     case WM_SETTEXT:
        !          1664:             DefWindowProc(hwnd, message, wParam, lParam);
        !          1665:             InvalidateRect(hwnd,NULL,TRUE);
        !          1666:             UpdateWindow(hwnd);
        !          1667:             return 0L;
        !          1668: 
        !          1669:     case WM_PAINT:
        !          1670:         {
        !          1671:             PAINTSTRUCT ps;
        !          1672:             RECT   rc;
        !          1673:             char   ach[128];
        !          1674:             int    len, nxBorder, nyBorder;
        !          1675:             HFONT  hOldFont = NULL;
        !          1676: 
        !          1677:             BeginPaint(hwnd, &ps);
        !          1678: 
        !          1679:             GetClientRect(hwnd,&rc);
        !          1680: 
        !          1681:             nxBorder = GetSystemMetrics(SM_CXBORDER);
        !          1682:            rc.left  += 9*nxBorder;
        !          1683:             rc.right -= 9*nxBorder;
        !          1684: 
        !          1685:             nyBorder = GetSystemMetrics(SM_CYBORDER);
        !          1686:            rc.top    += 3*nyBorder;
        !          1687:            rc.bottom -= 3*nyBorder;
        !          1688: 
        !          1689:            // 3D Text
        !          1690:             len = GetWindowText(hwnd, ach, sizeof(ach));
        !          1691:            SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
        !          1692: 
        !          1693:            SetBkMode(ps.hdc, TRANSPARENT);
        !          1694:            SetTextColor(ps.hdc, RGB(64,96,96));
        !          1695:            if (hFont)
        !          1696:                hOldFont = SelectObject(ps.hdc, hFont);
        !          1697:            ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
        !          1698:                        &rc, ach, len, NULL);
        !          1699: 
        !          1700:            SetTextColor(ps.hdc, RGB(128,128,128));
        !          1701:            if (hFont)
        !          1702:                hOldFont = SelectObject(ps.hdc, hFont);
        !          1703:            ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
        !          1704:                        &rc, ach, len, NULL);
        !          1705: 
        !          1706:            SetTextColor(ps.hdc, RGB(255,255,255));
        !          1707:            if (hFont)
        !          1708:                hOldFont = SelectObject(ps.hdc, hFont);
        !          1709:            ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
        !          1710:                        &rc, ach, len, NULL);
        !          1711: 
        !          1712:            SetBkMode(ps.hdc, OPAQUE);
        !          1713: 
        !          1714:            if (hOldFont)
        !          1715:                SelectObject(ps.hdc, hOldFont);
        !          1716: 
        !          1717:             EndPaint(hwnd, &ps);
        !          1718:             return 0L;
        !          1719:         }
        !          1720:     }
        !          1721:     return DefWindowProc(hwnd, message, wParam, lParam);
        !          1722: }
        !          1723: 
        !          1724: 
        !          1725: /**************************************************************************\
        !          1726: *
        !          1727: * JuliaWndProc
        !          1728: *
        !          1729: * History:
        !          1730: *  14-Jun-1992 -by- Petrus Wong     removed pens except red & black
        !          1731: *  22-Nov-1991 -by- Petrus Wong
        !          1732: * Wrote it.
        !          1733: \**************************************************************************/
        !          1734: 
        !          1735: LONG JuliaWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
        !          1736: {
        !          1737:     //
        !          1738:     // These statics are shared by all the Julia windows.  But, this is
        !          1739:     // fine because only one Julia window is tracking at any one time.
        !          1740:     // Ideally, we should place this in the per-window INFO data structure.
        !          1741:     // But, this is not necessary.
        !          1742:     //
        !          1743:     static BOOL    bTrack = FALSE;
        !          1744:     static int     OrgX, OrgY;
        !          1745:     static int     PrevX, PrevY;
        !          1746:     static HDC     hDC;
        !          1747:     static HCURSOR hCurArrow, hCurPaintCan;
        !          1748: 
        !          1749:     switch (message)
        !          1750:     {
        !          1751:        case WM_CREATE: {
        !          1752: 
        !          1753:             hpnRed     = CreatePen(PS_SOLID, 0, RGB(0xFF, 0,    0));
        !          1754:             hpnGreen   = CreatePen(PS_SOLID, 0, RGB(0,    0xFF, 0));
        !          1755:             hpnBlack   = CreatePen(PS_SOLID, 0, RGB(0,    0,    0));
        !          1756: 
        !          1757:             hCurPaintCan = LoadCursor(ghModule, MAKEINTRESOURCE(PAINTCURSOR));
        !          1758:             hCurArrow = LoadCursor(NULL, IDC_ARROW);
        !          1759:            break;
        !          1760:        }
        !          1761: 
        !          1762:        case WM_DESTROY: {
        !          1763: 
        !          1764:             DeleteObject(hpnRed);
        !          1765:             DeleteObject(hpnGreen);
        !          1766:             DeleteObject(hpnBlack);
        !          1767:             break;
        !          1768:        }
        !          1769:        case WM_PAINT:
        !          1770:          {
        !          1771:              PAINTSTRUCT ps;
        !          1772:              HWND        hParent;
        !          1773:              PINFO       pInfo;
        !          1774:              HDC         hDC;
        !          1775:              RECT        rc;
        !          1776: 
        !          1777:              GetClientRect(hwnd,&rc);
        !          1778:              hDC = BeginPaint(hwnd, &ps);
        !          1779:              EndPaint(hwnd, &ps);
        !          1780:              if ((hParent=GetParent(hwnd)) == NULL) {
        !          1781:                  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          1782:                  return 0L;
        !          1783:              }
        !          1784:              if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          1785:                   return 0L;
        !          1786:                 }
        !          1787: 
        !          1788:              if (pInfo->hBmpSaved) {
        !          1789:                 hDC = GetDC(hwnd);
        !          1790:                 DrawBitmap(hDC, pInfo, 0, 0, rc.right, rc.bottom);
        !          1791:                 ReleaseDC(hwnd, hDC);
        !          1792:              }
        !          1793:              bReleaseInfoData(hParent);
        !          1794: 
        !          1795:              //EndPaint(hwnd, &ps);
        !          1796:              return 0L;
        !          1797:          }
        !          1798: 
        !          1799:        case WM_RBUTTONDOWN: {
        !          1800:          RECT   rc;
        !          1801:         HANDLE hParent;
        !          1802:         PINFO  pInfo;
        !          1803:          int    x, y;
        !          1804:          HWND   hJulia;
        !          1805:          HANDLE hTextWnd;
        !          1806: 
        !          1807:          x = (int) LOWORD(lParam);
        !          1808:          y = (int) HIWORD(lParam);
        !          1809:          if ((hParent=GetParent(hwnd)) == NULL) {
        !          1810:              MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          1811:              break;
        !          1812:          }
        !          1813: 
        !          1814:          if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          1815:              break;
        !          1816:          }
        !          1817: 
        !          1818:          hTextWnd = pInfo->hTextWnd;
        !          1819: 
        !          1820:          if (GetWindowLong(GetParent(hwnd), GWL_STYLE) & WS_MAXIMIZE) {
        !          1821:              GetClientRect(ghwndMain, &rc);
        !          1822:              rc.bottom -= GetWindowLong(hTextWnd,GWL_USERDATA);
        !          1823:          } else {
        !          1824:              GetClientRect(hwnd, &rc);
        !          1825:          }
        !          1826: 
        !          1827:          if (pInfo->bMandel) {
        !          1828: 
        !          1829:              hJulia = (HWND) SendMessage(ghwndMain, WM_COMMAND,
        !          1830:                                          (DWORD)((WORD)MM_JULIA), 0L);
        !          1831:              if (hJulia) {
        !          1832:                  //GetClientRect(hwnd, &rc);
        !          1833:                  //
        !          1834:                  // calculate the c value corresponding to the point
        !          1835:                  //
        !          1836:                  c1 = Xform((double) x, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          1837:                  c2 = Xform((double) y, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          1838:                  lc1 = XformFix(x, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          1839:                  lc2 = XformFix(y, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          1840: 
        !          1841:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n", c1, c2);
        !          1842:                 OutputDebugString( gtext );
        !          1843: 
        !          1844:                  //
        !          1845:                  // Reset globals to default values for creating Julia set
        !          1846:                  // (Entire set, not zoom in)
        !          1847:                  //
        !          1848:                  bResetGlobal();
        !          1849:                  PostMessage(hJulia, WM_COMMAND, (DWORD)((WORD) MM_SET_XFORM_ATTR), 0L);
        !          1850:              } else {
        !          1851:                  MessageBox(ghwndMain, "Can't create hJulia!", "Error", MB_OK);
        !          1852:              }
        !          1853:          }
        !          1854:          bReleaseInfoData(hParent);
        !          1855:          break;
        !          1856:        }
        !          1857:        case WM_LBUTTONDOWN: {
        !          1858:         HANDLE hParent;
        !          1859:         PINFO  pInfo;
        !          1860:          int    x, y;
        !          1861:          DWORD  dwRGB;
        !          1862:          HBRUSH hBrOld;
        !          1863: 
        !          1864:          x = (int) LOWORD(lParam);
        !          1865:          y = (int) HIWORD(lParam);
        !          1866:          if ((hParent=GetParent(hwnd)) == NULL) {
        !          1867:              MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          1868:              break;
        !          1869:          }
        !          1870: 
        !          1871:          if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          1872:              break;
        !          1873:          }
        !          1874: 
        !          1875:          if (pInfo->bFill) {
        !          1876:             hDC = GetDC(hwnd);
        !          1877:             hBrOld = SelectObject(hDC, pInfo->hBrush);
        !          1878:             dwRGB = GetPixel(hDC, x, y);
        !          1879:             ExtFloodFill(hDC, x, y, (COLORREF)dwRGB, FLOODFILLSURFACE);
        !          1880:             SelectObject(hDC, hBrOld);
        !          1881:             ReleaseDC(hwnd, hDC);
        !          1882:             pInfo->bFill = FALSE;
        !          1883: 
        !          1884:             if (pInfo->hBmpSaved)
        !          1885:                 DeleteObject(pInfo->hBmpSaved);
        !          1886: 
        !          1887:             pInfo->hBmpSaved = SaveBitmap(hwnd);
        !          1888:             SetCursor(hCurArrow);
        !          1889:          } else {
        !          1890:             bTrack = TRUE;
        !          1891:             OrgX = PrevX = x = LOWORD(lParam);
        !          1892:             OrgY = PrevY = y = HIWORD(lParam);
        !          1893: 
        !          1894:             hDC = GetDC(hwnd);
        !          1895:             SetCapture(hwnd);
        !          1896:          }
        !          1897:          bReleaseInfoData(hParent);
        !          1898:          break;
        !          1899:        }
        !          1900:        case WM_MOUSEMOVE: {
        !          1901:          RECT rectClient;
        !          1902:          int NextX;
        !          1903:          int NextY;
        !          1904:         HANDLE hParent;
        !          1905:         PINFO  pInfo;
        !          1906: 
        !          1907:          if ((hParent=GetParent(hwnd)) == NULL) {
        !          1908:              MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          1909:              break;
        !          1910:          }
        !          1911: 
        !          1912:          if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          1913:              break;
        !          1914:          }
        !          1915: 
        !          1916:          if (pInfo->bFill) {
        !          1917:                  SetCursor(hCurPaintCan);
        !          1918:          } else {
        !          1919:                  SetCursor(hCurArrow);
        !          1920:          }
        !          1921: 
        !          1922:          bReleaseInfoData(hParent);
        !          1923: 
        !          1924:          // Update the selection region
        !          1925:          if (bTrack) {
        !          1926:              NextX = (SHORT) LOWORD(lParam);
        !          1927:              NextY = (SHORT) HIWORD(lParam);
        !          1928: 
        !          1929:              // Do not draw outside the window's client area
        !          1930: 
        !          1931:              GetClientRect (hwnd, &rectClient);
        !          1932:              if (NextX < rectClient.left) {
        !          1933:                  NextX = rectClient.left;
        !          1934:              } else if (NextX >= rectClient.right) {
        !          1935:                  NextX = rectClient.right - 1;
        !          1936:              }
        !          1937:              if (NextY < rectClient.top) {
        !          1938:                  NextY = rectClient.top;
        !          1939:              } else if (NextY >= rectClient.bottom) {
        !          1940:                  NextY = rectClient.bottom - 1;
        !          1941:              }
        !          1942:              if ((NextX != PrevX) || (NextY != PrevY)) {
        !          1943:                 SetROP2(hDC, R2_NOT);           // Erases the previous box
        !          1944: 
        !          1945:                 MoveToEx(hDC, OrgX, OrgY, NULL);
        !          1946:                 LineTo(hDC, OrgX, PrevY);
        !          1947:                 LineTo(hDC, PrevX, PrevY);
        !          1948:                 LineTo(hDC, PrevX, OrgY);
        !          1949:                 LineTo(hDC, OrgX, OrgY);
        !          1950:              // Get the current mouse position
        !          1951: 
        !          1952:                 PrevX = NextX;
        !          1953:                 PrevY = NextY;
        !          1954:                 MoveToEx(hDC, OrgX, OrgY, NULL);   // Draws the new box
        !          1955:                 LineTo(hDC, OrgX, PrevY);
        !          1956:                 LineTo(hDC, PrevX, PrevY);
        !          1957:                 LineTo(hDC, PrevX, OrgY);
        !          1958:                 LineTo(hDC, OrgX, OrgY);
        !          1959:              }
        !          1960:          }
        !          1961:          break;
        !          1962: 
        !          1963:        }
        !          1964: 
        !          1965:        case WM_LBUTTONUP: {
        !          1966:         RECT rc;
        !          1967:         HANDLE hParent;
        !          1968:         PINFO  pInfo;
        !          1969:          int NextX;
        !          1970:          int NextY;
        !          1971:          int iDistX, iDistY, iAbsDstX, iAbsDstY;
        !          1972:          HWND hZoom;
        !          1973:          HANDLE hTextWnd;
        !          1974: 
        !          1975:          if (!bTrack)
        !          1976:             break;
        !          1977: 
        !          1978:          // End the selection
        !          1979:             ReleaseCapture();
        !          1980:             bTrack = FALSE;
        !          1981: 
        !          1982:             MoveToEx(hDC, OrgX, OrgY, NULL);   // Erases the box
        !          1983:             LineTo(hDC, OrgX, PrevY);
        !          1984:             LineTo(hDC, PrevX, PrevY);
        !          1985:             LineTo(hDC, PrevX, OrgY);
        !          1986:             LineTo(hDC, OrgX, OrgY);
        !          1987: 
        !          1988:             NextX = LOWORD(lParam);
        !          1989:             NextY = HIWORD(lParam);
        !          1990: 
        !          1991:             iDistX = NextX - OrgX;
        !          1992:             iDistY = NextY - OrgY;
        !          1993:             iAbsDstX = (iDistX > 0 ? iDistX : -iDistX);
        !          1994:             iAbsDstY = (iDistY > 0 ? iDistY : -iDistY);
        !          1995:             if (iAbsDstX > iAbsDstY) {
        !          1996:                 NextY = OrgY + (iDistY > 0 ? iAbsDstX : -iAbsDstX);
        !          1997:             } else if (iAbsDstX < iAbsDstY) {
        !          1998:                         NextX = OrgX + (iDistX > 0 ? iAbsDstY : -iAbsDstY);
        !          1999:             }
        !          2000: 
        !          2001:             MoveToEx(hDC, OrgX, OrgY, NULL);   // Draws the new box
        !          2002:             LineTo(hDC, OrgX, NextY);
        !          2003:             LineTo(hDC, NextX, NextY);
        !          2004:             LineTo(hDC, NextX, OrgY);
        !          2005:             LineTo(hDC, OrgX, OrgY);
        !          2006: 
        !          2007:             SetROP2(hDC, R2_COPYPEN);
        !          2008: 
        !          2009:             ReleaseDC(hwnd, hDC);
        !          2010:             if ((hParent=GetParent(hwnd)) == NULL) {
        !          2011:                 MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2012:                 break;
        !          2013:             }
        !          2014: 
        !          2015:             if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2016:                 break;
        !          2017:             }
        !          2018: 
        !          2019:             hTextWnd = pInfo->hTextWnd;
        !          2020:             sprintf(gtext, "Mouse (%d, %d), (%d, %d)\n", OrgX, OrgY, NextX, NextY);
        !          2021:             //SetWindowText(hTextWnd, gtext);
        !          2022:             OutputDebugString(gtext);
        !          2023: 
        !          2024: 
        !          2025:             if (GetWindowLong(GetParent(hwnd), GWL_STYLE) & WS_MAXIMIZE) {
        !          2026: 
        !          2027:                 GetClientRect(ghwndMain, &rc);
        !          2028:                 rc.bottom -= GetWindowLong(hTextWnd,GWL_USERDATA);
        !          2029:                 sprintf(gtext, "(%d, %d), (%d, %d)\n", rc.left, rc.top, rc.right, rc.bottom);
        !          2030:                 //SetWindowText(hTextWnd, gtext);
        !          2031:                 OutputDebugString(gtext);
        !          2032: 
        !          2033:             } else {
        !          2034:                 GetClientRect(hwnd, &rc);
        !          2035:             }
        !          2036: 
        !          2037:             if ((OrgX == NextX) && (OrgY == NextY)) {
        !          2038:                 bReleaseInfoData(hParent);
        !          2039:                 break;
        !          2040:             }
        !          2041: 
        !          2042:             hZoom = (HWND) SendMessage(ghwndMain, WM_COMMAND,
        !          2043:                        pInfo->bMandel ? (DWORD)((WORD)MM_MANDEL) : (DWORD)((WORD)MM_JULIA),
        !          2044:                        0L);
        !          2045:             if (hZoom) {
        !          2046:                 //GetClientRect(hwnd, &rc);
        !          2047:                 xFrom = Xform((double) OrgX, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          2048:                 xTo   = Xform((double) NextX, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          2049:                 yFrom = Xform((double) OrgY, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          2050:                 yTo   = Xform((double) NextY, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          2051:                 lxFrom = XformFix(OrgX, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          2052:                 lxTo   = XformFix(NextX, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          2053:                 lyFrom = XformFix(OrgY, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          2054:                 lyTo   = XformFix(NextY, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          2055:                 if (!pInfo->bMandel) {
        !          2056:                     c1 = pInfo->c1;
        !          2057:                     c2 = pInfo->c2;
        !          2058:                     lc1 = pInfo->lc1;
        !          2059:                     lc2 = pInfo->lc2;
        !          2060:                 }
        !          2061:                 PostMessage(hZoom, WM_COMMAND, (DWORD)((WORD) MM_SET_XFORM_ATTR), 0L);
        !          2062:             } else {
        !          2063:                 MessageBox(ghwndMain, "Can't create hZoom!", "Error", MB_OK);
        !          2064:             }
        !          2065:          bReleaseInfoData(hParent);
        !          2066:          break;
        !          2067:        } // case WM_LBUTTONUP
        !          2068:     } // switch
        !          2069:     return DefWindowProc(hwnd, message, wParam, lParam);
        !          2070: }
        !          2071: 
        !          2072: 
        !          2073: /******************************Public*Routine******************************\
        !          2074: *
        !          2075: * SuspendDrawThrd
        !          2076: *
        !          2077: * Effects: Enumerates all the MDI children.  Suspending the drawing thread
        !          2078: *          in those windows, if any.
        !          2079: *
        !          2080: * Warnings: assumes the MDI children has class name "ChildClass."
        !          2081: *
        !          2082: * History:
        !          2083: *  09-Dec-1991 -by- Petrus Wong
        !          2084: * Wrote it.
        !          2085: \**************************************************************************/
        !          2086: 
        !          2087: 
        !          2088: BOOL APIENTRY SuspendDrawThrd (HWND hwnd, LONG lParam) {
        !          2089:    HANDLE      hThrd;
        !          2090:    PINFO       pInfo;
        !          2091:    DWORD       dwSuspend;
        !          2092:    BOOL        bDrawing;
        !          2093:    char        sz[30];
        !          2094: 
        !          2095:    GetClassName(hwnd, sz, 15);
        !          2096:    if (strcmp(sz, "ChildClass") != 0)
        !          2097:         return 1L;
        !          2098:        if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2099:            return 1L;
        !          2100:        }
        !          2101: 
        !          2102:        bDrawing = pInfo->bDrawing;
        !          2103:        hThrd    = pInfo->hThrd;
        !          2104:        bReleaseInfoData(hwnd);
        !          2105: 
        !          2106:        if (hThrd && bDrawing) {
        !          2107:            dwSuspend = SuspendThread(hThrd);
        !          2108:            sprintf( gtext,"\nSuspend: dwSuspend = %d, dwSuspend = %g\n", dwSuspend, dwSuspend);
        !          2109:            OutputDebugString( gtext );
        !          2110: 
        !          2111:            if (dwSuspend == -1) {
        !          2112:                sprintf( gtext,"Error in suspending thread\n");
        !          2113:                OutputDebugString( gtext );
        !          2114:            }
        !          2115:        }
        !          2116:    return 1L;
        !          2117:    UNREFERENCED_PARAMETER(lParam);
        !          2118: }
        !          2119: 
        !          2120: 
        !          2121: /******************************Public*Routine******************************\
        !          2122: *
        !          2123: * ResumeDrawThrd
        !          2124: *
        !          2125: * Effects: Enumerates all the MDI children.  Resuming the drawing thread
        !          2126: *          in those windows, if any.
        !          2127: *
        !          2128: * Warnings: Assumes the MDI children has class name "ChildClass." Also,
        !          2129: *           assumes the drawing has been suspended by SuspendDrawThrd.
        !          2130: *
        !          2131: * History:
        !          2132: *  09-Dec-1991 -by- Petrus Wong
        !          2133: * Wrote it.
        !          2134: \**************************************************************************/
        !          2135: 
        !          2136: 
        !          2137: BOOL APIENTRY ResumeDrawThrd  (HWND hwnd, LONG lParam) {
        !          2138:    HANDLE      hThrd;
        !          2139:    PINFO       pInfo;
        !          2140:    DWORD       dwSuspend;
        !          2141:    BOOL        bDrawing;
        !          2142:    char        sz[30];
        !          2143: 
        !          2144:    GetClassName(hwnd, sz, 15);
        !          2145:    if (strcmp(sz, "ChildClass") != 0)
        !          2146:         return 1L;
        !          2147:       if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2148:           return 1L;
        !          2149:       }
        !          2150: 
        !          2151:       bDrawing = pInfo->bDrawing;
        !          2152:       hThrd    = pInfo->hThrd;
        !          2153:       bReleaseInfoData(hwnd);
        !          2154: 
        !          2155:       if (hThrd && bDrawing) {
        !          2156:           dwSuspend = ResumeThread(hThrd);
        !          2157:           sprintf( gtext,"Resume: dwSuspend = %d, dwSuspend = %g\n", dwSuspend, dwSuspend);
        !          2158:           OutputDebugString( gtext );
        !          2159: 
        !          2160:           if (dwSuspend == -1) {
        !          2161:               sprintf( gtext,"Error in resuming thread\n");
        !          2162:               OutputDebugString( gtext );
        !          2163:           }
        !          2164:       }
        !          2165:    return 1L;
        !          2166:    UNREFERENCED_PARAMETER(lParam);
        !          2167: }
        !          2168: 
        !          2169: 
        !          2170: /******************************Public*Routine******************************\
        !          2171: *
        !          2172: * lMul
        !          2173: *
        !          2174: * Effects: Fix point multiplication
        !          2175: *
        !          2176: * Warnings: 20.11 fix point representation used. This is only good for
        !          2177: *           multiplication in a limited range.  Will overflow.
        !          2178: *           CR! Will be implemented as macros in the future
        !          2179: *
        !          2180: * History:
        !          2181: *  20-Nov-1991 -by- Petrus Wong
        !          2182: * Wrote it.
        !          2183: \**************************************************************************/
        !          2184: 
        !          2185: LONG lMul(LONG l1, LONG l2)
        !          2186: {
        !          2187:     return( (l1 * l2) >> 11);
        !          2188: }
        !          2189: 
        !          2190: /******************************Public*Routine******************************\
        !          2191: *
        !          2192: * lDiv
        !          2193: *
        !          2194: * Effects: fix point division
        !          2195: *
        !          2196: * Warnings: 20.11 fix point representation used. This is only good for
        !          2197: *           division in a limited range.  Will overflow.
        !          2198: *           CR! Will be implemented as macros in the future
        !          2199: *
        !          2200: * History:
        !          2201: *  20-Nov-1991 -by- Petrus Wong
        !          2202: * Wrote it.
        !          2203: \**************************************************************************/
        !          2204: 
        !          2205: LONG lDiv(long l1, long l2)
        !          2206: {
        !          2207:     return( (l1 << 11) / l2);
        !          2208: }
        !          2209: 
        !          2210: 
        !          2211: /**************************************************************************\
        !          2212: *
        !          2213: * StartDrawFix
        !          2214: *                                           2
        !          2215: * Effects: Draw'g the Julia Set for Q (z) = z  + c, where z, c are complex
        !          2216: *                                   c
        !          2217: *         Fact:   |Q (0)| = |c| > 2, the orbit of 0 escapes immediately
        !          2218: *                   c
        !          2219: *         claim:  |z| >= |c| = 2 + l, l > 0 escapes under Q
        !          2220: *                                                          c
        !          2221: *         The Julia Set: Basin Boundaries algorithm.
        !          2222: *
        !          2223: * Warnings:
        !          2224: *
        !          2225: * History:
        !          2226: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array
        !          2227: *  20-Nov-1991 -by- Petrus Wong
        !          2228: * Wrote it.
        !          2229: \**************************************************************************/
        !          2230: BOOL StartDrawFix(PINFO pInfo)
        !          2231: {
        !          2232:    DWORD       dwTick1;
        !          2233:    HDC         hDC;
        !          2234:    RECT        rc;
        !          2235: 
        !          2236:    int m, n, i, iPrev;
        !          2237:    int xCurr, yCurr;
        !          2238:    int iPen;
        !          2239: 
        !          2240:    LONG c1, c2;
        !          2241:    LONG x0, y0, x1, y1, x, y, z;
        !          2242: 
        !          2243:    iPen = giPen + 1;
        !          2244:    iPrev = FIRST_PIXEL;           // a big value to signal the first pixel
        !          2245:    //iPrev = pInfo->iIteration + FIRST_PIXEL;
        !          2246:    c1 = pInfo->lc1;
        !          2247:    c2 = pInfo->lc2;
        !          2248: 
        !          2249:    pInfo->bMandel = FALSE;
        !          2250:    pInfo->bDrawing = TRUE;
        !          2251:    hDC = GetDC(pInfo->hwnd);
        !          2252: 
        !          2253:    GetClientRect(pInfo->hwnd, &rc);
        !          2254:    yCurr = rc.top;
        !          2255: 
        !          2256:    dwTick1 = GetTickCount();
        !          2257: 
        !          2258:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          2259:        xCurr = rc.left;                      // since LineTo excludes last point
        !          2260:        MoveToEx(hDC, 0, yCurr, NULL);
        !          2261:        y0 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          2262: 
        !          2263:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          2264:           x0 = XformFix(m, rc.left, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          2265:            x = x0;
        !          2266:            y = y0;
        !          2267: 
        !          2268:            for (i=1; i<=pInfo->iIteration; i++) {
        !          2269:                x1 = lMul(x - y, x + y) + c1;    // Z = x1 + i x2
        !          2270: 
        !          2271:               y1 = (lMul(x, y) * 2) + c2;
        !          2272:                x = x1;
        !          2273:               y = y1;                          //    2       2     2 1/2     2
        !          2274:               z = lMul(x, x) + lMul(y, y);     // |Z|  = ((x1  + x2 )   ) > 2
        !          2275: 
        !          2276:               if (z > 8192)
        !          2277:                    break;
        !          2278:            }
        !          2279: 
        !          2280:           if (i != iPrev)
        !          2281:           {
        !          2282:              if (iPrev != FIRST_PIXEL)
        !          2283:              {
        !          2284:                switch(iPrev)
        !          2285:                {
        !          2286:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2287:                    default:
        !          2288: 
        !          2289:                        if (iPrev >= pInfo->iIteration) {
        !          2290:                           SelectObject(hDC, hpnBlack);
        !          2291:                           break;
        !          2292:                        }
        !          2293:                        SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
        !          2294:                        break;
        !          2295:                }
        !          2296:                iPrev = i;
        !          2297:                 LineTo(hDC,xCurr,yCurr);
        !          2298:              }
        !          2299:              else
        !          2300:                 iPrev = i;     // remember the color for the first pixel
        !          2301:           }
        !          2302:        }
        !          2303:                switch(i)
        !          2304:                {
        !          2305:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2306:                    default:
        !          2307:                        if (iPrev >= pInfo->iIteration) {
        !          2308:                           SelectObject(hDC, hpnBlack);
        !          2309:                           break;
        !          2310:                        }
        !          2311:                        SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
        !          2312:                        break;
        !          2313:                }
        !          2314: 
        !          2315:                 LineTo(hDC,xCurr,yCurr);
        !          2316:    }
        !          2317:    ReleaseDC(pInfo->hwnd, hDC);
        !          2318: 
        !          2319:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !          2320: 
        !          2321:    if (pInfo->hBmpSaved)
        !          2322:        DeleteObject(pInfo->hBmpSaved);
        !          2323: 
        !          2324:    pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
        !          2325:    pInfo->bDrawing = FALSE;
        !          2326: 
        !          2327:    ExitThread(0);
        !          2328:    if (!CloseHandle(pInfo->hThrd))
        !          2329:        MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
        !          2330: 
        !          2331:    return TRUE;
        !          2332: }
        !          2333: 
        !          2334: /**************************************************************************\
        !          2335: *
        !          2336: * StartDraw
        !          2337: *                                           2
        !          2338: * Effects: Draw'g the Julia Set for Q (z) = z  + c, where z, c are complex
        !          2339: *                                   c
        !          2340: *         Fact:   |Q (0)| = |c| > 2, the orbit of 0 escapes immediately
        !          2341: *                   c
        !          2342: *         claim:  |z| >= |c| = 2 + l, l > 0 escapes under Q
        !          2343: *                                                          c
        !          2344: *         The Julia Set: Basin Boundaries algorithm.
        !          2345: *
        !          2346: * Warnings:
        !          2347: *
        !          2348: * History:
        !          2349: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array and LineTo
        !          2350: *  20-Nov-1991 -by- Petrus Wong
        !          2351: * Wrote it.
        !          2352: \**************************************************************************/
        !          2353: BOOL StartDraw(PINFO pInfo)
        !          2354: {
        !          2355:    DWORD       dwTick1;
        !          2356:    HDC         hDC;
        !          2357:    RECT        rc;
        !          2358: 
        !          2359:    int m, n, i, iPrev;
        !          2360:    int xCurr, yCurr;
        !          2361:    int iPen;
        !          2362: 
        !          2363:    double c1, c2;
        !          2364:    double x0, y0, x1, y1, x, y, z;
        !          2365: 
        !          2366: 
        !          2367:    iPen = giPen + 1;
        !          2368:    iPrev = FIRST_PIXEL;           // a big value to signal the first pixel
        !          2369:    //iPrev = pInfo->iIteration + FIRST_PIXEL;
        !          2370:    c1 = pInfo->c1;
        !          2371:    c2 = pInfo->c2;
        !          2372: 
        !          2373:    pInfo->bMandel = FALSE;
        !          2374:    pInfo->bDrawing = TRUE;
        !          2375:    hDC = GetDC(pInfo->hwnd);
        !          2376: 
        !          2377:    GetClientRect(pInfo->hwnd, &rc);
        !          2378:    yCurr = rc.top;
        !          2379: 
        !          2380:    dwTick1 = GetTickCount();
        !          2381: 
        !          2382:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          2383:        xCurr = rc.left;                      // since LineTo excludes last point
        !          2384:        MoveToEx(hDC, 0, yCurr, NULL);
        !          2385:        y0 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          2386: 
        !          2387:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          2388:            x0 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          2389:            x = x0;
        !          2390:            y = y0;
        !          2391: 
        !          2392:            for (i=1; i<=pInfo->iIteration; i++) {
        !          2393:                x1 = (x - y) * (x + y) + c1;     // Z = x1 + i x2
        !          2394: 
        !          2395:                y1 = 2 * x * y + c2;
        !          2396:                x = x1;
        !          2397:               y = y1;                          //    2       2     2 1/2     2
        !          2398:               z = x * x + y * y;               // |Z|  = ((x1  + x2 )   ) > 2
        !          2399: 
        !          2400:               if (z > 4.0)
        !          2401:                    break;
        !          2402:            }
        !          2403: 
        !          2404:           if (i != iPrev)
        !          2405:           {
        !          2406:              if (iPrev != FIRST_PIXEL)
        !          2407:              {
        !          2408:                switch(iPrev)
        !          2409:                {
        !          2410:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2411:                    default:
        !          2412: 
        !          2413:                        if (iPrev >= pInfo->iIteration) {
        !          2414:                           SelectObject(hDC, hpnBlack);
        !          2415:                           break;
        !          2416:                        }
        !          2417:                        SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
        !          2418:                        break;
        !          2419:                }
        !          2420:                iPrev = i;
        !          2421:                 LineTo(hDC,xCurr,yCurr);
        !          2422:              }
        !          2423:              else
        !          2424:                 iPrev = i;     // remember the color for the first pixel
        !          2425:           }
        !          2426:        }
        !          2427:                switch(i)
        !          2428:                {
        !          2429:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2430:                    default:
        !          2431:                        if (iPrev >= pInfo->iIteration) {
        !          2432:                           SelectObject(hDC, hpnBlack);
        !          2433:                           break;
        !          2434:                        }
        !          2435:                        SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
        !          2436:                        break;
        !          2437:                }
        !          2438: 
        !          2439:                 LineTo(hDC,xCurr,yCurr);
        !          2440:    }
        !          2441:    ReleaseDC(pInfo->hwnd, hDC);
        !          2442: 
        !          2443:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !          2444: 
        !          2445:    if (pInfo->hBmpSaved)
        !          2446:        DeleteObject(pInfo->hBmpSaved);
        !          2447: 
        !          2448:    pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
        !          2449:    pInfo->bDrawing = FALSE;
        !          2450: 
        !          2451:    ExitThread(0);
        !          2452:    if (!CloseHandle(pInfo->hThrd))
        !          2453:        MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
        !          2454: 
        !          2455:    return TRUE;
        !          2456: }
        !          2457: 
        !          2458: /**************************************************************************\
        !          2459: *
        !          2460: * StartDraw2
        !          2461: *                                           2
        !          2462: * Effects: Draw'g the Julia Set for Q (z) = z  + c, where z, c are complex
        !          2463: *
        !          2464: *         The Julia Set: Backward iteration algorithm.
        !          2465: *
        !          2466: * Warnings:
        !          2467: *
        !          2468: * History:
        !          2469: *  20-Nov-1991 -by- Petrus Wong
        !          2470: * Wrote it.
        !          2471: \**************************************************************************/
        !          2472: 
        !          2473: BOOL StartDraw2(PINFO pInfo)
        !          2474: {
        !          2475:    HDC         hDC;
        !          2476:    RECT        rc;
        !          2477:    int        m, n, i;
        !          2478:    double      c1, c2;
        !          2479:    double      x0, y0, w0, w1, pi, theta, r;
        !          2480: 
        !          2481:    pi = 22.0/7.0;
        !          2482:    c1 = 0.360284;
        !          2483:    c2 = 0.100376;
        !          2484:    x0 = 1.5;
        !          2485:    y0 = 1.5;
        !          2486: 
        !          2487:    hDC = GetDC(pInfo->hwnd);
        !          2488: 
        !          2489:    GetClientRect(pInfo->hwnd, &rc);
        !          2490:    for (i=0; i<=15000; i++) {
        !          2491:     w0 = x0 - c1;
        !          2492:     w1 = y0 - c2;
        !          2493:     sprintf( gtext,"w(%g, %g) xy(%g, %g)\n", w0, w1, x0, y0);
        !          2494:     OutputDebugString( gtext );
        !          2495: 
        !          2496:     if (w0 == 0.0) {
        !          2497:        theta = pi/2;
        !          2498:         sprintf( gtext,"(w0 == 0.0) theta = %g\n\n", theta);
        !          2499:         OutputDebugString( gtext );
        !          2500: 
        !          2501:     } else {
        !          2502:        if (w0 > 0.0) {
        !          2503:            theta = atan(w1/w0);
        !          2504:             sprintf( gtext,"(w0 > 0.0) theta = %g\n\n", theta);
        !          2505:             OutputDebugString( gtext );
        !          2506: 
        !          2507:        } else { // w0 < 0.0
        !          2508:            theta = pi + atan(w1/w0);
        !          2509:             sprintf( gtext,"(w0 < 0.0) theta = %g\n\n", theta);
        !          2510:             OutputDebugString( gtext );
        !          2511:        }
        !          2512:     }
        !          2513:     r = sqrt(w0 * w0 + w1 + w1);
        !          2514:     theta = theta/2.0 + ((int) ((2.0*rand()/(RAND_MAX+1.0)))*pi);
        !          2515:     r = sqrt(r);
        !          2516:     x0 = r*cos(theta);
        !          2517:     y0 = r*sin(theta);
        !          2518:     if (i > 50) {
        !          2519:        m = Xform2(x0, pInfo->xFrom, pInfo->xTo, 0.0, (double) rc.right);
        !          2520:        n = Xform2(y0, pInfo->yFrom, pInfo->yTo, 0.0, (double) rc.bottom);
        !          2521:        SetPixel(hDC, m, n, 0x000000ff);
        !          2522:     }
        !          2523:    }
        !          2524: 
        !          2525:    ReleaseDC(pInfo->hwnd, hDC);
        !          2526: 
        !          2527:    ExitThread(0);
        !          2528:    if (!CloseHandle(pInfo->hThrd))
        !          2529:        MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
        !          2530: 
        !          2531:    return TRUE;
        !          2532: }
        !          2533: 
        !          2534: /**************************************************************************\
        !          2535: *
        !          2536: * StartMandelbrotFix
        !          2537: *                                           2
        !          2538: * Effects: Draw'g the Mandelbrot Set for Q (z) = z  + c, where z, c complex
        !          2539: *
        !          2540: * Warnings:
        !          2541: *
        !          2542: * History:
        !          2543: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array
        !          2544: *  20-Nov-1991 -by- Petrus Wong
        !          2545: * Wrote it.
        !          2546: \**************************************************************************/
        !          2547: BOOL StartMandelbrotFix(PINFO pInfo)
        !          2548: {
        !          2549:    DWORD       dwTick1;
        !          2550:    HDC         hDC;
        !          2551:    RECT        rc;
        !          2552:    int        m, n, i, iPrev;
        !          2553:    int         xCurr, yCurr;
        !          2554:    int         iPen;
        !          2555: 
        !          2556:    LONG c1, c2;
        !          2557:    LONG x1, y1, x, y, r;
        !          2558: 
        !          2559:    iPen = giPen + 1;
        !          2560:    pInfo->bMandel = TRUE;
        !          2561:    pInfo->bDrawing = TRUE;
        !          2562:    hDC = GetDC(pInfo->hwnd);
        !          2563: 
        !          2564:    GetClientRect(pInfo->hwnd, &rc);
        !          2565: 
        !          2566:    dwTick1 = GetTickCount();
        !          2567:    yCurr = rc.top;
        !          2568:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          2569:        xCurr = rc.left;                   // since LineTo excludes last point
        !          2570:        MoveToEx(hDC, 0, yCurr, NULL);
        !          2571:        c2 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          2572: 
        !          2573:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          2574:            c1 = XformFix(m, rc.left, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          2575:           x = c1;
        !          2576:           y = c2;
        !          2577: 
        !          2578:           for (i=1; i<=pInfo->iIteration; i++) {
        !          2579:                x1 = lMul(x - y, x + y) + c1;
        !          2580:                y1 = (lMul(x, y) * 2) + c2;
        !          2581:               r = lMul(x1, x1) + lMul(y1, y1);
        !          2582:               x = x1;
        !          2583:               y = y1;
        !          2584:               if (r > 8192) {
        !          2585:                    break;
        !          2586:                }
        !          2587:            }
        !          2588: 
        !          2589:            if (i != iPrev) {
        !          2590:                if (iPrev != FIRST_PIXEL) {
        !          2591:                  switch(iPrev) {
        !          2592:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2593:                    default:
        !          2594:                        if (iPrev >= pInfo->iIteration) {
        !          2595:                             SelectObject(hDC, hpnBlack);
        !          2596:                             break;
        !          2597:                        }
        !          2598:                        SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
        !          2599:                        break;
        !          2600:                  }
        !          2601:                  iPrev = i;
        !          2602:                  LineTo(hDC, xCurr, yCurr);
        !          2603:                }
        !          2604:                else
        !          2605:                  iPrev = i;    // remember the color for the first pixel
        !          2606:            }
        !          2607:        }
        !          2608: 
        !          2609:             switch(i)
        !          2610:                {
        !          2611:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2612:                    default:
        !          2613:                        if (i >= pInfo->iIteration) {
        !          2614:                             SelectObject(hDC, hpnBlack);
        !          2615:                             break;
        !          2616:                        }
        !          2617:                        SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
        !          2618:                        break;
        !          2619:                }
        !          2620: 
        !          2621:                 LineTo(hDC,xCurr,yCurr);
        !          2622: 
        !          2623:    }
        !          2624:    ReleaseDC(pInfo->hwnd, hDC);
        !          2625: 
        !          2626:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !          2627: 
        !          2628:    if (pInfo->hBmpSaved)
        !          2629:        DeleteObject(pInfo->hBmpSaved);
        !          2630: 
        !          2631:    pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
        !          2632:    pInfo->bDrawing = FALSE;
        !          2633: 
        !          2634:    ExitThread(0);
        !          2635:    if (!CloseHandle(pInfo->hThrd))
        !          2636:        MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
        !          2637: 
        !          2638:    return TRUE;
        !          2639: }
        !          2640: 
        !          2641: /**************************************************************************\
        !          2642: *
        !          2643: * StartMandelbrot
        !          2644: *                                           2
        !          2645: * Effects: Draw'g the Mandelbrot Set for Q (z) = z  + c, where z, c complex
        !          2646: *
        !          2647: * Warnings:
        !          2648: *
        !          2649: * History:
        !          2650: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array and LineTo
        !          2651: *  20-Nov-1991 -by- Petrus Wong
        !          2652: * Wrote it.
        !          2653: \**************************************************************************/
        !          2654: BOOL StartMandelbrot(PINFO pInfo)
        !          2655: {
        !          2656:    DWORD       dwTick1;
        !          2657:    HDC         hDC;
        !          2658:    RECT        rc;
        !          2659:    int        m, n, i, iPrev;
        !          2660:    int         xCurr, yCurr;
        !          2661:    int         iPen;
        !          2662: 
        !          2663:    double c1, c2;
        !          2664:    double x1, y1, x, y, r;
        !          2665: 
        !          2666:    iPen = giPen + 1;
        !          2667:    pInfo->bMandel = TRUE;
        !          2668:    pInfo->bDrawing = TRUE;
        !          2669:    hDC = GetDC(pInfo->hwnd);
        !          2670: 
        !          2671:    GetClientRect(pInfo->hwnd, &rc);
        !          2672: 
        !          2673:    dwTick1 = GetTickCount();
        !          2674:    yCurr = rc.top;
        !          2675:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          2676:        xCurr = rc.left;                   // since LineTo excludes last point
        !          2677:        MoveToEx(hDC, 0, yCurr, NULL);
        !          2678:        c2 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          2679: 
        !          2680:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          2681:            c1 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          2682:           x = c1;
        !          2683:           y = c2;
        !          2684: 
        !          2685:           for (i=1; i<=pInfo->iIteration; i++) {
        !          2686:                x1 = (x - y) * (x + y) + c1;
        !          2687:                y1 = 2 * x * y + c2;
        !          2688:               r = x1 * x1 + y1 * y1;
        !          2689:               x = x1;
        !          2690:               y = y1;
        !          2691:               if (r > 4.0) {
        !          2692:                    break;
        !          2693:                }
        !          2694:            }
        !          2695: 
        !          2696:            if (i != iPrev) {
        !          2697:                if (iPrev != FIRST_PIXEL) {
        !          2698:                  switch(iPrev) {
        !          2699:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2700:                    default:
        !          2701:                        if (iPrev >= pInfo->iIteration) {
        !          2702:                             SelectObject(hDC, hpnBlack);
        !          2703:                             break;
        !          2704:                        }
        !          2705:                        SelectObject(hDC, (HPEN)gprghPen[iPrev % iPen]);
        !          2706:                        break;
        !          2707:                  }
        !          2708:                  iPrev = i;
        !          2709:                  LineTo(hDC, xCurr, yCurr);
        !          2710:                }
        !          2711:                else
        !          2712:                  iPrev = i;    // remember the color for the first pixel
        !          2713:            }
        !          2714:        }
        !          2715: 
        !          2716:             switch(i)
        !          2717:                {
        !          2718:                    case 1: SelectObject(hDC, hpnRed); break;
        !          2719:                    default:
        !          2720:                        if (i >= pInfo->iIteration) {
        !          2721:                             SelectObject(hDC, hpnBlack);
        !          2722:                             break;
        !          2723:                        }
        !          2724:                        SelectObject(hDC, (HPEN)gprghPen[i % iPen]);
        !          2725:                        break;
        !          2726:                }
        !          2727: 
        !          2728:                 LineTo(hDC,xCurr,yCurr);
        !          2729: 
        !          2730:    }
        !          2731:    ReleaseDC(pInfo->hwnd, hDC);
        !          2732: 
        !          2733:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !          2734: 
        !          2735:    if (pInfo->hBmpSaved)
        !          2736:        DeleteObject(pInfo->hBmpSaved);
        !          2737: 
        !          2738:    pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd);
        !          2739:    pInfo->bDrawing = FALSE;
        !          2740: 
        !          2741:    ExitThread(0);
        !          2742:    if (!CloseHandle(pInfo->hThrd))
        !          2743:        MessageBox(ghwndMain, "Failed in CloseHandle!", "Error", MB_OK);
        !          2744: 
        !          2745:    return TRUE;
        !          2746: }
        !          2747: 
        !          2748: 
        !          2749: /******************************Public*Routine******************************\
        !          2750: *
        !          2751: * Xform
        !          2752: *
        !          2753: * Effects: Given m, find x.
        !          2754: *
        !          2755: *          Xform(Pt) : Src |--> Dest
        !          2756: * eg.
        !          2757: *          Src |----|--------|      |-->   Dest |----|--------|
        !          2758: *              -2   x        2                  0    m       320
        !          2759: *
        !          2760: *          x = (m - 0)/(320 - 0) * (2 - -2) + -2
        !          2761: *
        !          2762: * Warnings: 1. This will become a macro in the future for speed.  For now,
        !          2763: *             it is here for debugging purposes.
        !          2764: *
        !          2765: * History:
        !          2766: *  25-Nov-1991 -by- Petrus Wong
        !          2767: * Wrote it.
        !          2768: \**************************************************************************/
        !          2769: #if 0
        !          2770: double Xform(
        !          2771:    double Pt,
        !          2772:    double SrcFrom,
        !          2773:    double SrcTo,
        !          2774:    double DestFrom,
        !          2775:    double DestTo)
        !          2776: {
        !          2777:  //sprintf( gtext,"%g = Xform(%g, %g, %g, %g, %g)\n", ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom, Pt, SrcFrom, SrcTo, DestFrom, DestTo);
        !          2778:  //OutputDebugString( gtext );
        !          2779:  return(((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom);
        !          2780: }
        !          2781: #endif
        !          2782: 
        !          2783: /******************************Public*Routine******************************\
        !          2784: *
        !          2785: * Xform2
        !          2786: *
        !          2787: * Effects: Given x, find m.
        !          2788: *
        !          2789: *          Xform(Pt) : Src |--> Dest
        !          2790: * eg.
        !          2791: *          Src |----|--------|      |-->   Dest |----|--------|
        !          2792: *             -2   x        2                  0    m       320
        !          2793: *
        !          2794: *         m = (x - -2)/(2 - -2) * 320
        !          2795: *
        !          2796: * Warnings: 1. This will become a macro in the future for speed.  For now,
        !          2797: *             it is here for debugging purposes.
        !          2798: *
        !          2799: * History:
        !          2800: *  25-Nov-1991 -by- Petrus Wong
        !          2801: * Wrote it.
        !          2802: \**************************************************************************/
        !          2803: #if 0
        !          2804: int Xform2(
        !          2805:    double Pt,
        !          2806:    double SrcFrom,
        !          2807:    double SrcTo,
        !          2808:    double DestFrom,
        !          2809:    double DestTo)
        !          2810: {
        !          2811:  //sprintf( gtext,"%g = Xform(%g, %g, %g, %g, %g)\n", ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom, Pt, SrcFrom, SrcTo, DestFrom, DestTo);
        !          2812:  //OutputDebugString( gtext );
        !          2813:  return((int) ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom)+DestFrom));
        !          2814: }
        !          2815: #endif
        !          2816: 
        !          2817: /******************************Public*Routine******************************\
        !          2818: *
        !          2819: * SaveBitmap
        !          2820: *
        !          2821: * Effects:  Returns the handle of a bitmap corresponding to the window.
        !          2822: *           using utilizing BitBlt.
        !          2823: *
        !          2824: * Warnings:
        !          2825: *
        !          2826: * History:
        !          2827: *  03-Dec-1991 -by- Petrus Wong
        !          2828: * Wrote it.
        !          2829: \**************************************************************************/
        !          2830: 
        !          2831: HBITMAP SaveBitmap(HWND hWnd) {
        !          2832:     HDC     hdcMem, hDC;
        !          2833:     HBITMAP hBitmap, hOldBitmap;
        !          2834:     RECT    rc;
        !          2835: 
        !          2836:     hDC = GetDC(hWnd);
        !          2837:     GetClientRect(hWnd, &rc);
        !          2838: 
        !          2839:     hdcMem = CreateCompatibleDC(hDC);
        !          2840: 
        !          2841:     hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right-rc.left, (int)rc.bottom-rc.top);
        !          2842: 
        !          2843:     hOldBitmap = SelectObject(hdcMem, hBitmap);
        !          2844:     BitBlt(hdcMem, 0, 0, (int)rc.right-rc.left, (int)rc.bottom-rc.top, hDC, 0, 0, SRCCOPY);
        !          2845:     hBitmap = SelectObject(hdcMem, hOldBitmap);
        !          2846: 
        !          2847:     DeleteDC(hdcMem);
        !          2848:     ReleaseDC(hWnd, hDC);
        !          2849: 
        !          2850:     return(hBitmap);
        !          2851: 
        !          2852: }
        !          2853: 
        !          2854: /******************************Public*Routine******************************\
        !          2855: *
        !          2856: * DrawBitmap
        !          2857: *
        !          2858: * Effects:
        !          2859: *
        !          2860: * Warnings:
        !          2861: *
        !          2862: * History:
        !          2863: *  03-Dec-1991 -by- Petrus Wong
        !          2864: * Wrote it.
        !          2865: \**************************************************************************/
        !          2866: 
        !          2867: void DrawBitmap(HDC hdc, PINFO pInfo, int xStart, int yStart, int cx, int cy) {
        !          2868:     BITMAP bm;
        !          2869:     HDC    hdcMem;
        !          2870:     POINT  ptSize, ptOrg;
        !          2871: 
        !          2872:     hdcMem = CreateCompatibleDC(hdc);
        !          2873:     SelectObject(hdcMem, (pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved));
        !          2874:     SetMapMode(hdcMem, GetMapMode(hdc));
        !          2875: 
        !          2876:     GetObject((pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved), sizeof(BITMAP), (LPSTR)&bm);
        !          2877:     ptSize.x = bm.bmWidth;
        !          2878:     ptSize.y = bm.bmHeight;
        !          2879:     DPtoLP(hdc, &ptSize, 1);
        !          2880: 
        !          2881:     ptOrg.x = 0;
        !          2882:     ptOrg.y = 0;
        !          2883:     DPtoLP(hdcMem, &ptOrg, 1);
        !          2884: 
        !          2885:     if (pInfo->bStretch) {
        !          2886:         SetStretchBltMode(hdc, pInfo->iStretchMode);
        !          2887:         // cx+1 and cy+1: temporary work around for a bug!
        !          2888:         StretchBlt(hdc, xStart, yStart, cx+1, cy+1,
        !          2889:                hdcMem, ptOrg.x, ptOrg.y, ptSize.x, ptSize.y,SRCCOPY);
        !          2890:     } else {
        !          2891:         BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y,
        !          2892:                hdcMem, xStart, yStart, SRCCOPY);
        !          2893:     }
        !          2894: 
        !          2895:     if (pInfo->bUseMono)
        !          2896:         pInfo->bUseMono = FALSE;
        !          2897: 
        !          2898:     DeleteDC(hdcMem);
        !          2899:     UNREFERENCED_PARAMETER(cx);
        !          2900:     UNREFERENCED_PARAMETER(cy);
        !          2901: }
        !          2902: 
        !          2903: /******************************Public*Routine******************************\
        !          2904: *
        !          2905: * pGetInfoData(HWND hwnd)
        !          2906: *
        !          2907: * Effects:  calls LocalLock, returning pointer to Info structure.
        !          2908: *           assumes hwnd contains handle to Info structure at index 0.
        !          2909: *           should call bReleaseInfoData when done.
        !          2910: *           Global alert: ghwndMain used.
        !          2911: *
        !          2912: * Warnings:
        !          2913: *
        !          2914: * History:
        !          2915: *  27-Jan-1992 -by- Petrus Wong
        !          2916: * Wrote it.
        !          2917: \**************************************************************************/
        !          2918: 
        !          2919: PINFO pGetInfoData(HWND hwnd)
        !          2920: {
        !          2921:     HANDLE hInfo;
        !          2922:     PINFO  pInfo;
        !          2923: 
        !          2924:     hInfo = (HANDLE) GetWindowLong(hwnd, 0);
        !          2925:     if (hInfo == NULL) {
        !          2926:         MessageBox(ghwndMain, "Null Info handle retrieved - GetInfo", "Error", MB_OK);
        !          2927:         return NULL;
        !          2928:     }
        !          2929: 
        !          2930:     if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
        !          2931:         return NULL;
        !          2932:     }
        !          2933: 
        !          2934:     return pInfo;
        !          2935: }
        !          2936: 
        !          2937: /******************************Public*Routine******************************\
        !          2938: *
        !          2939: * bReleaseInfoData(HWND hwnd)
        !          2940: *
        !          2941: * Effects: calls LocalUnlock.  Returns whatever LocalUnlock returns.
        !          2942: *
        !          2943: * Warnings: assumes LocalLock was called previously.
        !          2944: *           assumes hwnd contains handle to Info structure at index 0.
        !          2945: *           Global alert: ghwndMain used.
        !          2946: *
        !          2947: * History:
        !          2948: *  27-Jan-1992 -by- Petrus Wong
        !          2949: * Wrote it.
        !          2950: \**************************************************************************/
        !          2951: 
        !          2952: BOOL bReleaseInfoData(HWND hwnd)
        !          2953: {
        !          2954:     HANDLE hInfo;
        !          2955: 
        !          2956:     hInfo = (HANDLE) GetWindowLong(hwnd, 0);
        !          2957:     if (hInfo == NULL) {
        !          2958:         MessageBox(ghwndMain, "Null Info handle retrieved - ReleaseInfo", "Error", MB_OK);
        !          2959:         return FALSE;
        !          2960:     }
        !          2961: 
        !          2962:     return (LocalUnlock(hInfo));
        !          2963: }
        !          2964: 
        !          2965: 
        !          2966: /******************************Public*Routine******************************\
        !          2967: *
        !          2968: * bCheckMutexMenuItem
        !          2969: *
        !          2970: * Effects: Put a check mark on uiCheckItem in the hMenu.  Remove previous
        !          2971: *          check mark, if any, on items in the same group.  Returns TRUE
        !          2972: *          if successful, FALSE otherwise (item not exists).
        !          2973: *
        !          2974: * Warnings:
        !          2975: *
        !          2976: * History:
        !          2977: *  28-Jan-1992 -by- Petrus Wong
        !          2978: * Wrote it.
        !          2979: \**************************************************************************/
        !          2980: 
        !          2981: BOOL bCheckMutexMenuItem(HMENU hMenu, UINT uiCheckItem)
        !          2982: {
        !          2983:     switch(uiCheckItem) {
        !          2984:         case MM_FLOAT:
        !          2985:         case MM_FIX:
        !          2986:             CheckMenuItem(hMenu, MM_FLOAT, MF_UNCHECKED);
        !          2987:             CheckMenuItem(hMenu, MM_FIX,   MF_UNCHECKED);
        !          2988:             break;
        !          2989:         case MM_ITERATION_TEN:
        !          2990:         case MM_ITERATION_TWENTY:
        !          2991:         case MM_ITERATION_THIRTY:
        !          2992:         case MM_ITERATION_FIFTY:
        !          2993:         case MM_ITERATION_DOUBLE:
        !          2994:             CheckMenuItem(hMenu, MM_ITERATION_TEN,    MF_UNCHECKED);
        !          2995:             CheckMenuItem(hMenu, MM_ITERATION_TWENTY, MF_UNCHECKED);
        !          2996:             CheckMenuItem(hMenu, MM_ITERATION_THIRTY, MF_UNCHECKED);
        !          2997:             CheckMenuItem(hMenu, MM_ITERATION_FIFTY,  MF_UNCHECKED);
        !          2998:             CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, MF_UNCHECKED);
        !          2999:             break;
        !          3000:         case MM_STEP_ONE:
        !          3001:         case MM_STEP_TWO:
        !          3002:         case MM_STEP_THREE:
        !          3003:                 CheckMenuItem(hMenu, MM_STEP_ONE,   MF_UNCHECKED);
        !          3004:                 CheckMenuItem(hMenu, MM_STEP_TWO,   MF_UNCHECKED);
        !          3005:                 CheckMenuItem(hMenu, MM_STEP_THREE, MF_UNCHECKED);
        !          3006:             break;
        !          3007:         case MM_STRETCHBLT:
        !          3008:         case MM_BITBLT:
        !          3009:                 CheckMenuItem(hMenu, MM_STRETCHBLT,   MF_UNCHECKED);
        !          3010:                 CheckMenuItem(hMenu, MM_BITBLT,       MF_UNCHECKED);
        !          3011:             break;
        !          3012:         case MM_BLACKONWHITE:
        !          3013:         case MM_COLORONCOLOR:
        !          3014:         case MM_WHITEONBLACK:
        !          3015:         case MM_HALFTONE:
        !          3016:                 CheckMenuItem(hMenu, MM_BLACKONWHITE,   MF_UNCHECKED);
        !          3017:                 CheckMenuItem(hMenu, MM_COLORONCOLOR,   MF_UNCHECKED);
        !          3018:                 CheckMenuItem(hMenu, MM_WHITEONBLACK,   MF_UNCHECKED);
        !          3019:                 CheckMenuItem(hMenu, MM_HALFTONE,       MF_UNCHECKED);
        !          3020:             break;
        !          3021:         case MM_PORTRAIT:
        !          3022:         case MM_LANDSCAPE:
        !          3023:                 CheckMenuItem(hMenu, MM_PORTRAIT,   MF_UNCHECKED);
        !          3024:                 CheckMenuItem(hMenu, MM_LANDSCAPE,  MF_UNCHECKED);
        !          3025:             break;
        !          3026:         default:
        !          3027:             return FALSE;
        !          3028:     }
        !          3029:     CheckMenuItem(hMenu, uiCheckItem, MF_CHECKED);
        !          3030:     return TRUE;
        !          3031: }
        !          3032: 
        !          3033: /******************************Public*Routine******************************\
        !          3034: *
        !          3035: * bInitInfo
        !          3036: *
        !          3037: * Effects: Initialize the Info data structure
        !          3038: *
        !          3039: * Warnings:
        !          3040: *
        !          3041: * History:
        !          3042: *  28-Jan-1992 -by- Petrus Wong
        !          3043: * Wrote it.
        !          3044: \**************************************************************************/
        !          3045: 
        !          3046: BOOL bInitInfo(PINFO pInfo)
        !          3047: {
        !          3048:     pInfo->hParent      = ghwndClient;
        !          3049:     pInfo->xFrom        = -2.0;
        !          3050:     pInfo->xTo          = 2.0;
        !          3051:     pInfo->yFrom        = 2.0;
        !          3052:     pInfo->yTo          = -2.0;
        !          3053:     pInfo->lxFrom       = -4096;                // 20.11 fix point
        !          3054:     pInfo->lxTo         = 4096;                 // representation of
        !          3055:     pInfo->lyFrom       = 4096;                 // -2, 2, 2, and -2
        !          3056:     pInfo->lyTo         = -4096;                //
        !          3057:     pInfo->iIteration   = gIteration;
        !          3058:     pInfo->iStep        = gStep;
        !          3059:     pInfo->bStretch     = gbStretch;
        !          3060:     pInfo->iStretchMode = giStretchMode;
        !          3061:     wsprintf((LPSTR) &(pInfo->CaptionBarText), "");
        !          3062:     pInfo->hwnd         = NULL;
        !          3063:     pInfo->hTextWnd     = NULL;
        !          3064:     pInfo->rcClient.top    = 0;
        !          3065:     pInfo->rcClient.left   = 0;
        !          3066:     pInfo->rcClient.bottom = 0;
        !          3067:     pInfo->rcClient.right  = 0;
        !          3068:     pInfo->hdcClient    = NULL;
        !          3069:     pInfo->hRgnPath     = NULL;
        !          3070:     pInfo->hThrd        = NULL;
        !          3071:     pInfo->bDrawing     = FALSE;
        !          3072:     pInfo->dwThreadId   = 0;
        !          3073:     pInfo->dwElapsed    = 0L;
        !          3074:     pInfo->c1           = 0.0;
        !          3075:     pInfo->c2           = 0.0;
        !          3076:     pInfo->lc1          = 0L;
        !          3077:     pInfo->lc2          = 0L;
        !          3078:     pInfo->hBmpSaved    = NULL;
        !          3079:     pInfo->bSizeChng    = FALSE;
        !          3080:     pInfo->bMandel      = TRUE;
        !          3081:     pInfo->bSetDIBsToDevice = FALSE;
        !          3082:     pInfo->bFill        = FALSE;
        !          3083:     pInfo->hBrush       = NULL;
        !          3084:     pInfo->hQuitEvent   = NULL;
        !          3085:     pInfo->hCycleThrd   = NULL;
        !          3086:     pInfo->dwCycleThrdID = 0;
        !          3087:     pInfo->bClrCycle    = FALSE;
        !          3088:     pInfo->bFirstTime   = TRUE;
        !          3089:     pInfo->dwSuspend    = 0;
        !          3090:     pInfo->hBmpMono     = NULL;
        !          3091:     pInfo->bUseMono     = FALSE;
        !          3092:     pInfo->hPrtThrd     = NULL;
        !          3093:     pInfo->dwPrtThrdID  = 0;
        !          3094:     return TRUE;
        !          3095: }
        !          3096: 
        !          3097: /******************************Public*Routine******************************\
        !          3098: *
        !          3099: * bResetGlobal
        !          3100: *
        !          3101: * Effects: Set (l) x/y From/To to their default values
        !          3102: *
        !          3103: * Warnings:
        !          3104: *
        !          3105: * History:
        !          3106: *  28-Jan-1992 -by- Petrus Wong
        !          3107: * Wrote it.
        !          3108: \**************************************************************************/
        !          3109: 
        !          3110: BOOL bResetGlobal(VOID)
        !          3111: {
        !          3112:     xFrom  = -2.0;
        !          3113:     xTo    = 2.0;
        !          3114:     yFrom  = 2.0;
        !          3115:     yTo    = -2.0;
        !          3116:     lxFrom = -4096;
        !          3117:     lxTo   = 4096;
        !          3118:     lyFrom = 4096;
        !          3119:     lyTo   = -4096;
        !          3120:     return TRUE;
        !          3121: }
        !          3122: 
        !          3123: /******************************Public*Routine******************************\
        !          3124: *
        !          3125: * hBrCreateBrush
        !          3126: *
        !          3127: * Effects: Creates a brush with the specified RGB
        !          3128: *
        !          3129: * Warnings:
        !          3130: *
        !          3131: * History:
        !          3132: *  04-Mar-1992 -by- Petrus Wong
        !          3133: * Wrote it.
        !          3134: \**************************************************************************/
        !          3135: 
        !          3136: HBRUSH hBrCreateBrush(HDC hDC, DWORD dwRGB)
        !          3137: {
        !          3138:     HDC hdcMem;
        !          3139:     HBRUSH hbr;
        !          3140:     HBRUSH hbrOld;
        !          3141:     HBITMAP hbmPat;
        !          3142:     HBITMAP hbmOld;
        !          3143: 
        !          3144:     hbr = CreateSolidBrush(dwRGB);
        !          3145:     hdcMem = CreateCompatibleDC(hDC);
        !          3146: 
        !          3147:     //
        !          3148:     // Minimum size for a bitmap to be used in a fill pattern is 8x8
        !          3149:     //
        !          3150:     hbmPat = CreateCompatibleBitmap(hDC, 8, 8);
        !          3151: 
        !          3152:     hbmOld = SelectObject(hdcMem, hbmPat);
        !          3153:     hbrOld = SelectObject(hdcMem, hbr);
        !          3154:     PatBlt(hdcMem, 0, 0, 8, 8, PATCOPY);
        !          3155: 
        !          3156:     //
        !          3157:     // Deselect hbmPat and hbr
        !          3158:     //
        !          3159:     SelectObject(hdcMem, hbmOld);
        !          3160:     SelectObject(hdcMem, hbrOld);
        !          3161: 
        !          3162:     DeleteDC(hdcMem);
        !          3163:     DeleteObject(hbr);
        !          3164: 
        !          3165:     hbr = CreatePatternBrush(hbmPat);
        !          3166: 
        !          3167:     DeleteObject(hbmPat);
        !          3168: 
        !          3169:     return hbr;
        !          3170: }
        !          3171: 
        !          3172: 
        !          3173: /******************************Public*Routine******************************\
        !          3174: *
        !          3175: * bPrintBmp
        !          3176: *
        !          3177: * Effects: A Thread routine for printing bitmap
        !          3178: *
        !          3179: * Warnings:
        !          3180: *
        !          3181: * History:
        !          3182: *  31-May-1992 -by- Petrus Wong
        !          3183: * Wrote it.
        !          3184: \**************************************************************************/
        !          3185: 
        !          3186: BOOL bPrintBmp(PPRTDATA pPrtData) {
        !          3187:     HDC         hdcPrinter;
        !          3188:     int         iWidth, iHeight;
        !          3189: 
        !          3190: #ifdef NEWPRTAPI
        !          3191:     DOCINFO     DocInfo;
        !          3192: #endif
        !          3193: 
        !          3194:     if (pPrtData->bUseDefault) {
        !          3195:           hdcPrinter = CreateDC( "", gpszPrinterNames[pPrtData->index],
        !          3196:                                  "", NULL);
        !          3197:     } else {
        !          3198:           hdcPrinter = CreateDC( "", gpszPrinterNames[pPrtData->index],
        !          3199:                                  "", &(pPrtData->DevMode));
        !          3200:     }
        !          3201: 
        !          3202:     if (!hdcPrinter)
        !          3203:     {
        !          3204:         ExitThread(0);
        !          3205:         return(FALSE);
        !          3206:     }
        !          3207: 
        !          3208:     iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
        !          3209:     iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
        !          3210: 
        !          3211: #ifdef NEWPRTAPI
        !          3212: 
        !          3213:     DocInfo.cbSize      = sizeof(DOCINFO);
        !          3214:     DocInfo.lpszDocName = pPrtData->info.CaptionBarText;
        !          3215:     DocInfo.lpszOutput   = NULL;
        !          3216:     StartDoc(hdcPrinter, &DocInfo);
        !          3217:     StartPage(hdcPrinter);
        !          3218:     DrawBitmap(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight);
        !          3219:     EndPage(hdcPrinter);
        !          3220:     EndDoc(hdcPrinter);
        !          3221: 
        !          3222: #else
        !          3223: 
        !          3224:     Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
        !          3225:     DrawBitmap(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight);
        !          3226:     Escape(hdcPrinter, NEWFRAME, NULL, NULL, NULL);
        !          3227:     Escape(hdcPrinter, ENDDOC, NULL, NULL, NULL);
        !          3228: 
        !          3229: #endif
        !          3230: 
        !          3231:     DeleteDC(hdcPrinter);
        !          3232:     ExitThread(0);
        !          3233:     return(TRUE);
        !          3234: 
        !          3235: }

unix.superglobalmegacorp.com

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