Annotation of mstools/samples/mandel/julia.c, revision 1.1.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.