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

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

unix.superglobalmegacorp.com

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