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

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: *
1.1.1.3 ! root       10: * Copyright (c) 1993 Microsoft Corporation
1.1       root       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
1.1.1.3 ! root       27: *      11.  Load RLE (or convert .bmp files to RLE) for playing in viewer
        !            28: *      12.  Save the RLE in memory to disk.
        !            29: *
        !            30: * Note: Users can now draw and saves the julia sets on disk as bmps in
        !            31: *       the Julia windows.  These bitmaps can then be read into the memory
        !            32: *       (and converted to RLE format) one by one for displaying in sequence
        !            33: *       in the viewer window.  Eg Load the julia.rle in the viewer window
        !            34: *       and select the play or play continuously menu item.     02-Jan-1993
        !            35: *
        !            36: * Note2: The fix point math in this sample makes use of the LargeInteger
        !            37: *        64 bit math library.
1.1       root       38: *
                     39: * Dependencies:
                     40: *
                     41: *       none
                     42: *
                     43: \**************************************************************************/
                     44: #include <windows.h>
                     45: #include <stdlib.h>
                     46: #include <commdlg.h>
                     47: #include <stdarg.h>
                     48: #include <math.h>
                     49: #include <stdio.h>
1.1.1.3 ! root       50: #include <shellapi.h>
1.1       root       51: #include "julia.h"
1.1.1.3 ! root       52: #include <largeint.h>
1.1       root       53: 
1.1.1.3 ! root       54: //
        !            55: // For T1 to create all pens in advance.  This is not a good approach
        !            56: // because pens are per thread basis.  The drawing threads won't be able
        !            57: // to use them if they are not created in their threads.    18-Sep-1992
        !            58: //
        !            59: //#define THRDONE
        !            60: 
        !            61: #define CYCLETHRD
1.1       root       62: 
1.1.1.3 ! root       63: #define PRTTHRD
        !            64: #define NEWPRTAPI
1.1       root       65: 
                     66: #ifndef DEBUG
                     67:    #undef OutputDebugString
                     68:    #define OutputDebugString(LPCSTR)
                     69: #endif
                     70: 
                     71: //
                     72: // Forward declarations.
                     73: //
1.1.1.3 ! root       74: BOOL InitializeApp            (INT*);
1.1.1.2   root       75: LONG APIENTRY MainWndProc     (HWND, UINT, DWORD, LONG);
1.1.1.3 ! root       76: LONG APIENTRY ChildWndProc    (HWND, UINT, DWORD, LONG);
        !            77: BOOL CALLBACK About           (HWND, UINT, DWORD, LONG);
1.1.1.2   root       78: LONG APIENTRY TextWndProc     (HWND, UINT, DWORD, LONG);
                     79: LONG APIENTRY JuliaWndProc    (HWND, UINT, DWORD, LONG);
1.1.1.3 ! root       80: LONG APIENTRY ViewerWndProc   (HWND, UINT, DWORD, LONG);
        !            81: LONG APIENTRY ViewSurfWndProc (HWND, UINT, DWORD, LONG);
1.1       root       82: BOOL APIENTRY SuspendDrawThrd (HWND, LONG);
                     83: BOOL APIENTRY ResumeDrawThrd  (HWND, LONG);
                     84: BOOL StartDraw       (PINFO);
                     85: BOOL StartDrawFix    (PINFO);
                     86: BOOL StartDraw2      (PINFO);
                     87: BOOL StartMandelbrot (PINFO);
                     88: BOOL StartMandelbrotFix (PINFO);
1.1.1.3 ! root       89: HBITMAP SaveBitmap   (HWND, HPALETTE);
1.1       root       90: void DrawBitmap      (HDC, PINFO, int, int, int, int);
1.1.1.2   root       91: BOOL bDrawDIB        (HDC, PINFO, int, int, int, int);
1.1       root       92: LONG lMul(LONG, LONG);
                     93: LONG lDiv(LONG, LONG);
                     94: PINFO pGetInfoData(HWND);
                     95: BOOL bReleaseInfoData(HWND);
1.1.1.3 ! root       96: BOOL bCheckMutexMenuItem(PINFO, HMENU, UINT);
        !            97: VOID vChkMenuItem(PINFO, HMENU, UINT);
1.1       root       98: BOOL bInitInfo(PINFO);
                     99: BOOL bResetGlobal(VOID);
                    100: HBRUSH hBrCreateBrush(HDC, DWORD);
                    101: BOOL bPrintBmp(PPRTDATA);
1.1.1.3 ! root      102: BOOL bStoreRleFile(HDC, PINFO, PSTR);
        !           103: BOOL bFreeRleFile(PINFO);
        !           104: BOOL bPlayRle(PINFO);
        !           105: BOOL bSaveRleFile(HDC, PINFO, PSTR);
        !           106: BOOL bPlayRleCont2(PINFO);
        !           107: BOOL bSelectDIBPal(HDC, PINFO, LPBITMAPINFO, BOOL);
        !           108: HBITMAP DIBfromDDB(HDC, HBITMAP, PINFO);
1.1       root      109: 
                    110: /******************************Public*Routine******************************\
                    111: *
                    112: * WinMain
                    113: *
                    114: * History:
                    115: *  13-Jun-1992 -by- Petrus Wong     Creates an array of pens
                    116: *  17-Apr-1991 -by- Petrus Wong
                    117: * Wrote it.
                    118: \**************************************************************************/
                    119: 
1.1.1.3 ! root      120: int WINAPI WinMain(
1.1       root      121:     HINSTANCE hInstance,
                    122:     HINSTANCE hPrevInstance,
                    123:     LPSTR lpCmdLine,
                    124:     int nShowCmd)
                    125: {
                    126:     MSG    msg;
                    127: 
                    128:     ghModule = GetModuleHandle(NULL);
                    129:     if (!InitializeApp(&giPen)) {
                    130:        MessageBox(ghwndMain, "memory: InitializeApp failure!", "Error", MB_OK);
                    131:         return 0;
                    132:     }
                    133: 
                    134:     if (!(ghAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
                    135:        MessageBox(ghwndMain, "memory: Load Accel failure!", "Error", MB_OK);
                    136: 
                    137: 
                    138:     while (GetMessage(&msg, NULL, 0, 0)) {
                    139:         if (!TranslateAccelerator( ghwndMain, ghAccel, &msg) &&
                    140:             !TranslateMDISysAccel(  ghwndClient, &msg)          ) {
                    141:             TranslateMessage(&msg);
                    142:             DispatchMessage(&msg);
                    143:         }
                    144:     }
                    145: 
                    146: 
1.1.1.3 ! root      147:     DeleteObject(ghPal);
1.1       root      148: 
                    149:     return 1;
                    150: 
                    151:     UNREFERENCED_PARAMETER(lpCmdLine);
                    152:     UNREFERENCED_PARAMETER(nShowCmd);
                    153:     UNREFERENCED_PARAMETER(hInstance);
                    154:     UNREFERENCED_PARAMETER(hPrevInstance);
                    155: }
                    156: 
                    157: 
                    158: /***************************************************************************\
                    159: * InitializeApp
                    160: *
                    161: * History:
                    162: * 13-Jun-1992   Petrus Wong     creates pens
                    163: * 29-May-1992   Petrus Wong     check if device supports palette for cycling
                    164: * 09-09-91      Petrus Wong    Created.
                    165: \***************************************************************************/
                    166: 
                    167: BOOL InitializeApp(INT *piPen)
                    168: {
                    169:     WNDCLASS wc;
                    170:     HDC      hDC;
1.1.1.3 ! root      171: 
        !           172: #ifdef THRDONE
1.1       root      173:     INT      iNumClr;
1.1.1.3 ! root      174: #endif
1.1       root      175: 
                    176:     wc.style            = CS_OWNDC;
                    177:     wc.lpfnWndProc      = (WNDPROC)MainWndProc;
                    178:     wc.cbClsExtra       = 0;
                    179:     wc.cbWndExtra      = sizeof(LONG);
                    180:     wc.hInstance        = ghModule;
                    181:     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
                    182:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
                    183:     wc.hbrBackground   = (HBRUSH)(COLOR_APPWORKSPACE);
                    184:     wc.lpszMenuName     = "MainMenu";
                    185:     wc.lpszClassName   = "MandelClass";
                    186: 
                    187:     if (!RegisterClass(&wc))
                    188:        return FALSE;
                    189: 
                    190:     wc.lpfnWndProc     = (WNDPROC)ChildWndProc;
                    191:     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
                    192:     wc.lpszMenuName    = NULL;
                    193:     wc.lpszClassName   = "ChildClass";
                    194: 
                    195:     if (!RegisterClass(&wc))
                    196:         return FALSE;
                    197: 
1.1.1.3 ! root      198:     wc.lpfnWndProc     = (WNDPROC)ViewerWndProc;
        !           199:     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(VIEWICON));
        !           200:     wc.lpszMenuName    = NULL;
        !           201:     wc.lpszClassName   = "ViewerClass";
        !           202: 
        !           203:     if (!RegisterClass(&wc))
        !           204:         return FALSE;
        !           205: 
1.1       root      206:     wc.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
                    207:     wc.lpfnWndProc     = (WNDPROC)TextWndProc;
                    208:     wc.hIcon           = NULL;
                    209:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
                    210:     wc.hbrBackground   = (HBRUSH)(COLOR_BTNSHADOW);
                    211:     wc.lpszMenuName    = NULL;
                    212:     wc.lpszClassName   = "Text";
                    213: 
                    214:     if (!RegisterClass(&wc))
                    215:             return FALSE;
                    216: 
                    217:     wc.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
                    218:     wc.lpfnWndProc     = (WNDPROC)JuliaWndProc;
                    219:     wc.hIcon           = NULL;
                    220: 
                    221:     //
                    222:     // Nope.  Can't have this, screw up my Paint Can cursor
                    223:     //
                    224:     //wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
                    225: 
                    226:     wc.hCursor          = NULL;
                    227:     wc.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
                    228:     wc.lpszMenuName    = NULL;
                    229:     wc.lpszClassName   = "Julia";
                    230: 
                    231:     if (!RegisterClass(&wc))
                    232:             return FALSE;
                    233: 
1.1.1.3 ! root      234:     wc.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        !           235:     wc.lpfnWndProc     = (WNDPROC)ViewSurfWndProc;
        !           236:     wc.hIcon           = NULL;
        !           237:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        !           238:     wc.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
        !           239:     wc.lpszMenuName    = NULL;
        !           240:     wc.lpszClassName   = "View";
        !           241: 
        !           242:     if (!RegisterClass(&wc))
        !           243:             return FALSE;
        !           244: 
1.1       root      245: 
                    246:     //
                    247:     // Notice, submenu is zero-based
                    248:     //
                    249:     hMenu      = LoadMenu(ghModule, "MainMenu");
                    250:     hChildMenu  = LoadMenu(ghModule, "ChildMenu");
1.1.1.3 ! root      251:     hViewMenu   = LoadMenu(ghModule, "ViewMenu");
        !           252:     hViewSubOne = GetSubMenu(hViewMenu, 1);
1.1       root      253:     hSubMenuOne = GetSubMenu(hMenu, 1);
                    254:     hSubMenuThree = GetSubMenu(hChildMenu, 8);
                    255:     hPrinterMenu = GetSubMenu(hChildMenu, 7);
                    256: 
                    257:     //
                    258:     // Disable color-cycling for display devices that does not support
                    259:     // palette like the VGA.  As as 29-May-1992, the MIPS display driver
                    260:     // is the only one that supports palette
                    261:     //
                    262:     hDC = GetDC(NULL);
                    263:     if (!((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE)) {
                    264:         EnableMenuItem(hChildMenu, MM_CYCLE, MF_GRAYED);
                    265:     }
                    266: 
1.1.1.3 ! root      267: #ifdef THRDONE
        !           268: 
        !           269:     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &ghPal)) != 0) {
1.1       root      270:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
                    271:         OutputDebugString( gtext);
                    272: 
1.1.1.3 ! root      273:         if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !           274:             MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
1.1       root      275:         } else {
1.1.1.3 ! root      276:             if ((*piPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &ghPal)) == 0)
1.1       root      277:                 MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
                    278:         }
                    279:     }
                    280: 
1.1.1.3 ! root      281: #endif
1.1       root      282:     ReleaseDC(NULL, hDC);
                    283: 
                    284:     ghwndMain = CreateWindowEx(0L, "MandelClass", "Mandelbrot Dream",
                    285:            WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
                    286:            WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
                    287:            WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
                    288:            80, 70, 550, 550,
                    289:            NULL, hMenu, ghModule, NULL);
                    290: 
                    291:     if (ghwndMain == NULL)
                    292:        return FALSE;
                    293: 
                    294:     bInitPrinter(ghwndMain);
                    295: 
                    296:     SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
                    297: 
                    298:     SetFocus(ghwndMain);    /* set initial focus */
                    299: 
1.1.1.3 ! root      300:     PostMessage(ghwndMain, WM_COMMAND, MM_MANDEL, 0L);
        !           301:     PostMessage(ghwndMain, WM_COMMAND, MM_CREATE_MANDEL_THREAD, 0L);
        !           302: 
1.1       root      303:     return TRUE;
                    304: }
                    305: 
                    306: 
                    307: /******************************Public*Routine******************************\
                    308: *
                    309: * MainWndProc
                    310: *
                    311: * History:
                    312: *  09-Sept-1991 -by- Petrus Wong
                    313: * Wrote it.
                    314: \**************************************************************************/
                    315: 
1.1.1.2   root      316: long APIENTRY MainWndProc(
1.1       root      317:     HWND hwnd,
                    318:     UINT message,
                    319:     DWORD wParam,
                    320:     LONG lParam)
                    321: {
                    322:     static int         iJuliaCount=1;
                    323:     static int        iMandelCount=1;
1.1.1.3 ! root      324:     static int         iViewerCount=1;
1.1       root      325:     CLIENTCREATESTRUCT clientcreate;
                    326:     HWND               hwndChildWindow;
                    327:     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
                    328: 
                    329: 
                    330:     switch (message) {
                    331: 
                    332:       case WM_CREATE:
                    333:        SetWindowLong(hwnd, 0, (LONG)NULL);
                    334: 
                    335:        clientcreate.hWindowMenu  = hSubMenuOne;
                    336:        clientcreate.idFirstChild = 1;
                    337: 
                    338:        ghwndClient = CreateWindow("MDICLIENT", NULL,
                    339:                                    WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
                    340:                                    0,0,0,0,
                    341:                                    hwnd, NULL, ghModule, (LPVOID)&clientcreate);
                    342:         lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
                    343:         lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
1.1.1.3 ! root      344: 
1.1       root      345:         return 0L;
                    346: 
                    347:       case WM_DESTROY: {
                    348:         bCleanupPrinter();
                    349:        PostQuitMessage(0);
                    350:        return 0L;
                    351:       }
                    352: 
                    353:       //
                    354:       // Wait! User is going to zero out our app's visible region.  This
                    355:       // is going to mess up our drawing (we are not keeping any shadow
                    356:       // bitmap in this version yet.) So, let's suspend our drawing thread
                    357:       // first before user does that.  We will resume after user is done.
                    358:       //
                    359:       case WM_SYSCOMMAND: {
                    360:         LONG        lResult;
                    361: 
                    362:         //
                    363:         // We'll enumerate our children and suspend their drawing thread.
                    364:         //
                    365:         EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
                    366: 
                    367:         //
                    368:         // Now, let user does it supposed to do
                    369:         //
                    370:         lResult = DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
                    371: 
                    372:         //
                    373:         // User's done, we'll resume the suspended threads in our children
                    374:         //
                    375:         EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
                    376: 
                    377:         return lResult;
                    378:         break;
                    379:       }
                    380: #if 0
                    381:       //
                    382:       // Our window's size is going to change, we'll make sure the new
                    383:       // window is a square.
                    384:       //
                    385:       case WM_WINDOWPOSCHANGING: {
                    386:             PWINDOWPOS pWndPos;
                    387:             RECT       rect;
                    388:             LONG       lcx, lcy;
                    389: 
                    390:             GetWindowRect(hwnd, &rect);
                    391:             lcx = rect.right-rect.left;
                    392:             lcy = rect.bottom-rect.top;
                    393:             pWndPos = (PWINDOWPOS)lParam;
                    394:             if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx))
                    395:                 pWndPos->cx =  pWndPos->cy =
                    396:                    ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy : pWndPos->cx);
                    397:             else if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx))
                    398:                      pWndPos->cx =  pWndPos->cy =
                    399:                         ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy : pWndPos->cx);
                    400:             break;
                    401:       }
                    402: #endif
1.1.1.3 ! root      403: 
1.1       root      404:       case WM_COMMAND:
                    405: 
                    406:        switch (LOWORD(wParam)) {
                    407:            case IDM_TILE:
                    408:                SendMessage(ghwndClient, WM_MDITILE, 0L, 0L);
                    409:                return 0L;
                    410:            case IDM_CASCADE:
                    411:                SendMessage(ghwndClient, WM_MDICASCADE, 0L, 0L);
                    412:                return 0L;
                    413:            case IDM_ARRANGE:
                    414:                SendMessage(ghwndClient, WM_MDIICONARRANGE, 0L, 0L);
                    415:                return 0L;
                    416: 
                    417:             //
                    418:             // Create Julia or Mandelbrot set
                    419:             //
                    420:            case MM_JULIA:
                    421:            case MM_MANDEL: {
                    422:                HANDLE hInfo;
                    423:                PINFO  pInfo;
                    424:                 MDICREATESTRUCT mdicreate;
                    425: 
                    426:                hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
                    427:                if (hInfo == NULL) {
                    428:                     MessageBox(ghwndMain, "Failed to Allocate Info!", "Error", MB_OK);
                    429:                     return 0L;
                    430:                 }
                    431:                if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
                    432:                    MessageBox(ghwndMain, "Failed in LocalLock, hInfo", "Error", MB_OK);
                    433:                     return 0L;
                    434:                 }
                    435: 
                    436:                 bInitInfo(pInfo);
                    437:                 wsprintf((LPSTR) &(pInfo->CaptionBarText),
                    438:                          (LOWORD(wParam) == MM_JULIA) ? "Julia %d" : "Mandelbrot %d",
                    439:                          (LOWORD(wParam) == MM_JULIA) ? iJuliaCount : iMandelCount   );
                    440:                 if (LOWORD(wParam) == MM_JULIA) {
                    441:                     c1 = 0.360284;
                    442:                     c2 = 0.100376;
                    443:                     lc1 = 738;          //.3603515
                    444:                     lc2 = 206;          //.1005859
                    445:                     pInfo->bMandel = FALSE;
                    446:                 } else {
                    447:                     pInfo->bMandel = TRUE;
                    448:                 }
                    449: 
                    450:                 //
                    451:                 // Fill in the MDICREATE structure for MDI child creation
                    452:                 //
                    453:                mdicreate.szClass = "ChildClass";
                    454:                 mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
                    455:                 mdicreate.hOwner  = ghModule;
                    456:                 mdicreate.x       =
                    457:                 mdicreate.y       = CW_USEDEFAULT;
                    458:                 mdicreate.cx      = 300;
                    459:                 mdicreate.cy      = 300;
                    460:                 mdicreate.style   = 0L;
                    461:                 mdicreate.lParam  = (LONG) hInfo;
                    462: 
                    463:                 /*Create Child Window*/
                    464:                 hwndChildWindow =
                    465:                     (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
                    466:                                 0L,
                    467:                                 (LONG)(LPMDICREATESTRUCT)&mdicreate);
                    468: 
                    469:                 if (hwndChildWindow == NULL) {
                    470:                     MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK);
                    471:                     return 0L;
                    472:                 }
                    473: 
                    474:                 (LOWORD(wParam) == MM_JULIA) ? iJuliaCount++ : iMandelCount++ ;
                    475:                 LocalUnlock(hInfo);
                    476:                return ((LONG)hwndChildWindow);
                    477:            }
                    478: 
1.1.1.3 ! root      479:             case MM_RLEVIEWER: {
        !           480:                HANDLE hInfo;
        !           481:                PINFO  pInfo;
        !           482:                 MDICREATESTRUCT mdicreate;
        !           483: 
        !           484:                hInfo = LocalAlloc(LHND, (WORD) sizeof(INFO));
        !           485:                if (hInfo == NULL) {
        !           486:                     MessageBox(ghwndMain, "Failed to Allocate Info!", "Error", MB_OK);
        !           487:                     return 0L;
        !           488:                 }
        !           489:                if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
        !           490:                    MessageBox(ghwndMain, "Failed in LocalLock, hInfo", "Error", MB_OK);
        !           491:                     return 0L;
        !           492:                 }
        !           493: 
        !           494:                 bInitInfo(pInfo);
        !           495:                 wsprintf((LPSTR) &(pInfo->CaptionBarText), "Viewer %d", iViewerCount );
        !           496: 
        !           497:                 //
        !           498:                 // Fill in the MDICREATE structure for MDI child creation
        !           499:                 //
        !           500:                mdicreate.szClass = "ViewerClass";
        !           501:                 mdicreate.szTitle = (LPTSTR)&(pInfo->CaptionBarText);
        !           502:                 mdicreate.hOwner  = ghModule;
        !           503:                 mdicreate.x       =
        !           504:                 mdicreate.y       = CW_USEDEFAULT;
        !           505:                 mdicreate.cx      = 300;
        !           506:                 mdicreate.cy      = 300;
        !           507:                 mdicreate.style   = 0L;
        !           508:                 mdicreate.lParam  = (LONG) hInfo;
        !           509: 
        !           510:                 /*Create Child Window*/
        !           511:                 hwndChildWindow =
        !           512:                     (HANDLE) SendMessage(ghwndClient, WM_MDICREATE,
        !           513:                                 0L,
        !           514:                                 (LONG)(LPMDICREATESTRUCT)&mdicreate);
        !           515: 
        !           516:                 if (hwndChildWindow == NULL) {
        !           517:                     MessageBox(ghwndMain, "Failed in Creating Child Window", "Error", MB_OK);
        !           518:                     return 0L;
        !           519:                 }
1.1.1.2   root      520: 
1.1.1.3 ! root      521:                 iViewerCount++ ;
        !           522:                 LocalUnlock(hInfo);
        !           523:                return ((LONG)hwndChildWindow);
        !           524: 
        !           525:             }
1.1.1.2   root      526: 
1.1.1.3 ! root      527:            case MM_ABOUT:
        !           528:                if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
        !           529:                   MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
1.1       root      530:                return 0L;
                    531: 
                    532:             //
                    533:             // Only my children know how to deal with these messages, so
                    534:             // pass these to children for processing
                    535:             //
                    536:            case MM_CREATE_JULIA_THREAD:
                    537:            case MM_SET_XFORM_ATTR:
                    538:            case MM_CREATE_MANDEL_THREAD:
                    539:            case MM_OPT_4:              // currently not used
                    540:            case MM_DRAW_SET:
                    541:             case MM_SETDIB2DEVICE:
                    542:            case MM_BW:
                    543:            case MM_SHIFT:
                    544:            case MM_CUSTOM:
                    545:             case MM_CYCLE:
1.1.1.3 ! root      546:             case MM_TP_IDLE:
        !           547:             case MM_TP_LOW:
        !           548:             case MM_TP_BELOW_NORMAL:
        !           549:             case MM_TP_NORMAL:
        !           550:             case MM_TP_ABOVE_NORMAL:
        !           551:             case MM_TP_HIGH:
        !           552:             case MM_TP_TIME_CRITICAL:
1.1       root      553:             case MM_FLOAT:
                    554:             case MM_FIX:
1.1.1.3 ! root      555:             case MM_ITERATION_100:
        !           556:             case MM_ITERATION_500:
        !           557:             case MM_ITERATION_1000:
        !           558:             case MM_ITERATION_5000:
1.1       root      559:             case MM_ITERATION_DOUBLE:
                    560:             case MM_STEP_ONE:
                    561:             case MM_STEP_TWO:
                    562:             case MM_STEP_THREE:
                    563:             case MM_SAVE:
                    564:             case MM_SAVE_MONO:
                    565:             case MM_LOAD:
                    566:             case MM_STRETCHBLT:
                    567:             case MM_BITBLT:
                    568:             case MM_BLACKONWHITE:
                    569:             case MM_COLORONCOLOR:
                    570:             case MM_WHITEONBLACK:
                    571:             case MM_HALFTONE:
                    572:             case MM_CLIP:
                    573:             case MM_RM_CLIP:
1.1.1.3 ! root      574:             case MM_SELCLIPRGN:
1.1       root      575:             case MM_ERASE:
                    576:             case MM_PORTRAIT:
                    577:             case MM_LANDSCAPE:
                    578:             case MM_PRINTER:
                    579:             case MM_PRINTER + 1:
                    580:             case MM_PRINTER + 2:
                    581:             case MM_PRINTER + 3:
                    582:             case MM_PRINTER + 4:
                    583:             case MM_PRINTER + 5:
                    584:             case MM_PRINTER + 6:
                    585:             case MM_PRINTER + 7:
                    586:             case MM_PRINTER + 8:
                    587:             case MM_PRINTER + 9:
1.1.1.3 ! root      588:             case MM_RLELOAD_DEMO:
        !           589:             case MM_RLEPLAYCONT:
        !           590:             case MM_RLELOAD:
        !           591:             case MM_RLESAVE:
        !           592:             case MM_CLEAR:
        !           593:             case MM_RLEPLAY:
1.1       root      594:             {
                    595:                HWND hActiveChild;
                    596: 
                    597:                hActiveChild = (HANDLE) SendMessage(ghwndClient, WM_MDIGETACTIVE, 0L, 0L);
                    598:                if (hActiveChild)
                    599:                    SendMessage(hActiveChild, WM_COMMAND, wParam, lParam);
                    600:                return 0L;
                    601:            }
                    602: 
                    603:            default:
                    604:                return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
                    605:         }
                    606:     default:
                    607: 
                    608:        return DefFrameProc(hwnd,  ghwndClient, message, wParam, lParam);
                    609:     }
                    610: }
                    611: 
                    612: /***************************************************************************\
                    613: * ChildWndProc
                    614: *
                    615: * History:
                    616: * 04-17-91 ????         Created.
                    617: * 09-09-91 Petrus Wong Rewrote.
                    618: \***************************************************************************/
                    619: 
1.1.1.2   root      620: long APIENTRY ChildWndProc(
1.1       root      621:     HWND hwnd,
                    622:     UINT message,
                    623:     DWORD wParam,
                    624:     LONG lParam)
                    625: {
                    626:     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
                    627:     static BOOL        bDIB2Device = FALSE;
                    628: 
                    629:     sprintf( gtext,"message = %lx\n", message);
                    630:     OutputDebugString( gtext);
                    631: 
                    632:     switch (message) {
                    633:        case WM_COMMAND: {
                    634:           PINFO       pInfo;
                    635:           HWND        hTextWnd;
                    636: 
                    637:          switch (LOWORD(wParam)) {
                    638:             //
                    639:             // Create a Julia drawing thread
                    640:             //
                    641:            case MM_CREATE_JULIA_THREAD: {
                    642:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    643:                     return 0L;
                    644:                 }
                    645: 
                    646:                 hTextWnd = pInfo->hTextWnd;
                    647:                 sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
                    648:                 SetWindowText(hTextWnd, gtext);
                    649:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
                    650:                 OutputDebugString( gtext );
                    651: 
1.1.1.3 ! root      652:                 if (pInfo->hThrd)
        !           653:                     CloseHandle(pInfo->hThrd);
        !           654: 
1.1       root      655:                 pInfo->hThrd = CreateThread(NULL, 0,
                    656:                                  (gFloat ? (LPTHREAD_START_ROUTINE)StartDraw : (LPTHREAD_START_ROUTINE)StartDrawFix),
                    657:                                  pInfo,
                    658:                                  STANDARD_RIGHTS_REQUIRED,
                    659:                                  &pInfo->dwThreadId );
                    660: 
1.1.1.3 ! root      661:                if (pInfo->hThrd && pInfo->bDrawing) {
        !           662:                    if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority))
        !           663:                         MessageBox(ghwndMain, "Can't set Priority!",
        !           664:                                    "Error", MB_OK);
        !           665:                }
        !           666: 
1.1       root      667:                bReleaseInfoData(hwnd);
                    668:                return 0L;
                    669:             }
                    670: 
                    671:             //
                    672:             // Reset pInfo reflecting new transformation
                    673:             //
                    674:            case MM_SET_XFORM_ATTR: {
                    675:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    676:                     return 0L;
                    677:                 }
                    678: 
                    679:                 hTextWnd = pInfo->hTextWnd;
                    680:                 SetWindowText(hTextWnd, "Click here for viewing info");
                    681: 
                    682:                 pInfo->xFrom      = xFrom;
                    683:                 pInfo->xTo        = xTo;
                    684:                 pInfo->yFrom      = yFrom;
                    685:                 pInfo->yTo        = yTo;
                    686:                 pInfo->c1         = c1;
                    687:                 pInfo->c2         = c2;
                    688:                 pInfo->lxFrom      = lxFrom;
                    689:                 pInfo->lxTo        = lxTo;
                    690:                 pInfo->lyFrom      = lyFrom;
                    691:                 pInfo->lyTo        = lyTo;
                    692:                 pInfo->lc1         = lc1;
                    693:                 pInfo->lc2         = lc2;
                    694: 
                    695:                bReleaseInfoData(hwnd);
                    696:               return 0L;
                    697:            }
                    698: 
                    699:             //
                    700:             // Create a Mandelbrot drawing thread
                    701:             //
                    702:            case MM_CREATE_MANDEL_THREAD: {
                    703:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    704:                     return 0L;
                    705:                 }
                    706: 
                    707:                 hTextWnd = pInfo->hTextWnd;
                    708:                 sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
                    709:                 SetWindowText(hTextWnd, gtext);
                    710:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
                    711:                 OutputDebugString( gtext );
                    712: 
1.1.1.3 ! root      713:                 if (pInfo->hThrd)
        !           714:                     CloseHandle(pInfo->hThrd);
        !           715: 
1.1       root      716:                 pInfo->hThrd = CreateThread(NULL, 0,
                    717:                                  (gFloat ? (LPTHREAD_START_ROUTINE)StartMandelbrot : (LPTHREAD_START_ROUTINE)StartMandelbrotFix),
                    718:                                  pInfo,
                    719:                                  STANDARD_RIGHTS_REQUIRED,
                    720:                                  &pInfo->dwThreadId );
1.1.1.3 ! root      721: 
        !           722:                if (pInfo->hThrd && pInfo->bDrawing) {
        !           723:                    if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority))
        !           724:                         MessageBox(ghwndMain, "Can't set Priority!",
        !           725:                                    "Error", MB_OK);
        !           726:                }
        !           727: 
        !           728: 
1.1       root      729:                bReleaseInfoData(hwnd);
                    730:                return 0L;
                    731:            }
                    732: 
                    733:             //
                    734:             // Create a Julia drawing thread using algorithm StartDraw2
                    735:             // Currently not used
                    736:             //
                    737:            case MM_OPT_4: {
                    738:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    739:                     return 0L;
                    740:                 }
                    741: 
                    742:                 hTextWnd = pInfo->hTextWnd;
                    743:                 SetWindowText(hTextWnd, "MM_OPT_4");
                    744: 
                    745:                 sprintf( gtext,"xFrom = %g, xTo = %g, yFrom = %g, yTo = %g\n", pInfo->xFrom, pInfo->xTo, pInfo->yFrom, pInfo->yTo);
                    746:                 OutputDebugString( gtext );
                    747: 
1.1.1.3 ! root      748:                 if (pInfo->hThrd)
        !           749:                     CloseHandle(pInfo->hThrd);
        !           750: 
1.1       root      751:                 pInfo->hThrd = CreateThread(NULL, 0,
                    752:                                  (LPTHREAD_START_ROUTINE)StartDraw2,
                    753:                                  pInfo,
                    754:                                  STANDARD_RIGHTS_REQUIRED,
                    755:                                  &pInfo->dwThreadId );
                    756: 
1.1.1.3 ! root      757:                if (pInfo->hThrd && pInfo->bDrawing) {
        !           758:                    if (!SetThreadPriority(pInfo->hThrd, pInfo->iPriority))
        !           759:                         MessageBox(ghwndMain, "Can't set Priority!",
        !           760:                                    "Error", MB_OK);
        !           761:                }
        !           762: 
1.1       root      763:                bReleaseInfoData(hwnd);
                    764:               return 0L;
                    765:            }
                    766: 
                    767:             case MM_DRAW_SET: {
                    768:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    769:                     return 0L;
                    770:                 }
                    771: 
                    772:                 PostMessage(hwnd, WM_COMMAND,
                    773:                     pInfo->bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
                    774:                     (LONG)0L);
                    775: 
                    776:                bReleaseInfoData(hwnd);
                    777:                return 0L;
                    778:             }
                    779: 
1.1.1.3 ! root      780:             {
        !           781:             int     iPriority;
        !           782: 
        !           783:                 case MM_TP_IDLE:
        !           784:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           785:                         return 0L;
        !           786:                     }
        !           787: 
        !           788:                     iPriority = THREAD_PRIORITY_IDLE;
        !           789:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_IDLE);
        !           790:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           791:                     goto CWP_SET_PRIORITY;
        !           792: 
        !           793:                 case MM_TP_LOW:
        !           794:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           795:                         return 0L;
        !           796:                     }
        !           797: 
        !           798:                     iPriority = THREAD_PRIORITY_LOWEST;
        !           799:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_LOW);
        !           800:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           801:                     goto CWP_SET_PRIORITY;
        !           802: 
        !           803:                 case MM_TP_BELOW_NORMAL:
        !           804:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           805:                         return 0L;
        !           806:                     }
        !           807: 
        !           808:                     iPriority = THREAD_PRIORITY_BELOW_NORMAL;
        !           809:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_BELOW_NORMAL);
        !           810:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           811:                     goto CWP_SET_PRIORITY;
        !           812: 
        !           813:                 case MM_TP_NORMAL:
        !           814:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           815:                         return 0L;
        !           816:                     }
        !           817: 
        !           818:                     iPriority = THREAD_PRIORITY_NORMAL;
        !           819:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_NORMAL);
        !           820:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           821:                     goto CWP_SET_PRIORITY;
        !           822: 
        !           823:                 case MM_TP_ABOVE_NORMAL:
        !           824:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           825:                         return 0L;
        !           826:                     }
        !           827: 
        !           828:                     iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
        !           829:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_ABOVE_NORMAL);
        !           830:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           831:                     goto CWP_SET_PRIORITY;
        !           832: 
        !           833:                 case MM_TP_HIGH:
        !           834:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           835:                         return 0L;
        !           836:                     }
        !           837: 
        !           838:                     iPriority = THREAD_PRIORITY_HIGHEST;
        !           839:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_HIGH);
        !           840:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           841:                     goto CWP_SET_PRIORITY;
        !           842: 
        !           843:                 case MM_TP_TIME_CRITICAL:
        !           844:                     if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           845:                         return 0L;
        !           846:                     }
        !           847: 
        !           848:                     iPriority = THREAD_PRIORITY_TIME_CRITICAL;
        !           849:                     bCheckMutexMenuItem(pInfo, hChildMenu, MM_TP_TIME_CRITICAL);
        !           850:                     DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           851: 
        !           852: CWP_SET_PRIORITY:
        !           853:                     {
        !           854:                        HANDLE       hThrd;
        !           855: 
        !           856:                        hThrd = pInfo->hThrd;
        !           857:                        pInfo->iPriority = iPriority;
        !           858: 
        !           859:                        if (hThrd && pInfo->bDrawing) {
        !           860:                            if (!SetThreadPriority(hThrd, iPriority))
        !           861:                                 MessageBox(ghwndMain, "Can't set Priority!",
        !           862:                                            "Error", MB_OK);
        !           863:                        }
        !           864: 
        !           865:                     }
        !           866:                     bReleaseInfoData(hwnd);
        !           867:                     return 0L;
        !           868: 
        !           869:             }
        !           870: 
1.1       root      871:             case MM_FLOAT: {
1.1.1.3 ! root      872:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           873:                     return 0L;
        !           874:                 }
        !           875:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_FLOAT);
1.1       root      876:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
                    877:                 gFloat = TRUE;
1.1.1.3 ! root      878:                 bReleaseInfoData(hwnd);
1.1       root      879:                 return 0L;
                    880:             }
                    881:             case MM_FIX: {
1.1.1.3 ! root      882:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !           883:                     return 0L;
        !           884:                 }
        !           885:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_FIX);
1.1       root      886:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
                    887:                 gFloat = FALSE;
1.1.1.3 ! root      888:                 bReleaseInfoData(hwnd);
1.1       root      889:                 return 0L;
                    890:             }
1.1.1.3 ! root      891:             case MM_ITERATION_100: {
1.1       root      892:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    893:                     return 0L;
                    894:                 }
1.1.1.3 ! root      895:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_100);
        !           896:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           897:                 gIteration = 100;
        !           898:                 pInfo->iIteration = 100;
        !           899:                 SetWindowText(pInfo->hTextWnd, "Iteration = 100");
1.1       root      900:                 bReleaseInfoData(hwnd);
                    901:                 return 0L;
                    902:             }
1.1.1.3 ! root      903:             case MM_ITERATION_500: {
1.1       root      904:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
                    905:                     return 0L;
                    906:                 }
1.1.1.3 ! root      907:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_500);
        !           908:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           909:                 gIteration = 500;
1.1       root      910: 
1.1.1.3 ! root      911:                 pInfo->iIteration = 500;
        !           912:                 SetWindowText(pInfo->hTextWnd, "Iteration = 500");
1.1       root      913:                 bReleaseInfoData(hwnd);
                    914:                 return 0L;
                    915:             }
1.1.1.3 ! root      916:             case MM_ITERATION_1000: {
1.1       root      917:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    918:                     return 0L;
                    919:                 }
1.1.1.3 ! root      920:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_1000);
        !           921:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           922:                 gIteration = 1000;
        !           923:                 pInfo->iIteration = 1000;
        !           924:                 SetWindowText(pInfo->hTextWnd, "Iteration = 1000");
1.1       root      925:                 bReleaseInfoData(hwnd);
                    926:                 return 0L;
                    927:             }
1.1.1.3 ! root      928:             case MM_ITERATION_5000: {
1.1       root      929:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    930:                     return 0L;
                    931:                 }
1.1.1.3 ! root      932:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_5000);
        !           933:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           934:                 gIteration = 5000;
        !           935:                 pInfo->iIteration = 5000;
        !           936:                 SetWindowText(pInfo->hTextWnd, "Iteration = 5000");
1.1       root      937:                 bReleaseInfoData(hwnd);
                    938:                 return 0L;
                    939:             }
                    940:             case MM_ITERATION_DOUBLE: {
                    941:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    942:                     return 0L;
                    943:                 }
1.1.1.3 ! root      944:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_ITERATION_DOUBLE);
        !           945:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           946:                 gIteration *= 2;
1.1       root      947:                 pInfo->iIteration = gIteration;
1.1.1.3 ! root      948:                 sprintf( gtext,"Iteration = %d", pInfo->iIteration);
        !           949:                 SetWindowText(pInfo->hTextWnd, gtext);
1.1       root      950:                 bReleaseInfoData(hwnd);
                    951:                 return 0L;
                    952:             }
                    953:             case MM_STEP_ONE: {
                    954:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    955:                     return 0L;
                    956:                 }
1.1.1.3 ! root      957:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_ONE);
        !           958:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           959:                 gStep = 1;
1.1       root      960:                 pInfo->iStep = 1;
                    961: 
                    962:                 bReleaseInfoData(hwnd);
                    963:                 return 0L;
                    964:             }
                    965:             case MM_STEP_TWO:  {
                    966:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
                    967:                     return 0L;
                    968:                 }
1.1.1.3 ! root      969:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_TWO);
        !           970:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           971:                 gStep = 2;
1.1       root      972:                 pInfo->iStep = 2;
                    973: 
                    974:                 bReleaseInfoData(hwnd);
                    975:                 return 0L;
                    976:             }
                    977:             case MM_STEP_THREE: {
                    978:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                    979:                     return 0L;
                    980:                 }
1.1.1.3 ! root      981:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_STEP_THREE);
        !           982:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !           983:                 gStep = 3;
1.1       root      984:                 pInfo->iStep = 3;
                    985: 
                    986:                 bReleaseInfoData(hwnd);
                    987:                 return 0L;
                    988:             }
                    989: 
                    990:             case MM_LOAD: {
                    991:                 HDC hDC;
                    992:                 OPENFILENAME ofn;
                    993:                 char szDirName[256];
                    994:                 char szFile[256], szFileTitle[256];
                    995:                 static char *szFilter;
                    996:                 RECT    rc;
                    997: 
1.1.1.3 ! root      998:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
        !           999:                     return 0L;
        !          1000:                 }
        !          1001: 
1.1       root     1002:                 szFilter =
                   1003:                   "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0";
                   1004: 
                   1005:                 GetSystemDirectory((LPSTR) szDirName, 256);
                   1006:                 strcpy(szFile, "*.bmp\0");
                   1007:                 ofn.lStructSize = sizeof(OPENFILENAME);
1.1.1.3 ! root     1008:                 ofn.hwndOwner = pInfo->hwnd;
1.1       root     1009:                 ofn.lpstrFilter = szFilter;
                   1010:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
                   1011:                 ofn.nMaxCustFilter = 0L;
                   1012:                 ofn.nFilterIndex = 1;
                   1013:                 ofn.lpstrFile = szFile;
                   1014:                 ofn.nMaxFile = sizeof(szFile);
                   1015:                 ofn.lpstrFileTitle = szFileTitle;
                   1016:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
                   1017:                 ofn.lpstrInitialDir = szDirName;
                   1018:                 ofn.lpstrTitle = (LPSTR) NULL;
                   1019:                 ofn.Flags = 0L;
                   1020:                 ofn.nFileOffset = 0;
                   1021:                 ofn.nFileExtension = 0;
                   1022:                 ofn.lpstrDefExt = "BMP";
                   1023: 
                   1024:                 if (!GetOpenFileName(&ofn))
                   1025:                     return 0L;
1.1.1.3 ! root     1026: 
1.1       root     1027:                 GetClientRect(pInfo->hwnd, &rc);
                   1028:                 hDC = GetDC(pInfo->hwnd);
                   1029:                 if (LoadBitmapFile(hDC, pInfo, szFile))
1.1.1.2   root     1030:                   bDrawDIB(hDC, pInfo, 0, 0, rc.right, rc.bottom);
1.1       root     1031:                 ReleaseDC(hwnd, hDC);
                   1032: 
                   1033:                 bReleaseInfoData(hwnd);
                   1034: 
                   1035:                 return 0L;
                   1036:             }
                   1037: 
                   1038:             case MM_SAVE: {
                   1039:                 HDC hDC;
                   1040:                 OPENFILENAME ofn;
                   1041:                 char szDirName[256];
                   1042:                 char szFile[256], szFileTitle[256];
                   1043:                 static char *szFilter;
                   1044:                 szFilter = "DIB files (*.bmp)\0\0";
                   1045: 
                   1046:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1047:                     return 0L;
                   1048:                 }
                   1049:                 hDC = GetDC(pInfo->hwnd);
1.1.1.3 ! root     1050: #if 0
        !          1051:                 {
        !          1052:                 HPALETTE hPalTmp;
1.1       root     1053: 
1.1.1.3 ! root     1054:                 hPalTmp = CopyPalette(pInfo->hPal);
        !          1055:                 DeleteObject(pInfo->hPal);
        !          1056:                 pInfo->hPal = hPalTmp;
        !          1057:                 }
        !          1058: #endif
1.1       root     1059:                 //
                   1060:                 // saving special effects user might have created in window
                   1061:                 //
                   1062:                 if (pInfo->hBmpSaved)
                   1063:                     DeleteObject(pInfo->hBmpSaved);
1.1.1.3 ! root     1064:                 pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd, pInfo->hPal);
        !          1065:                 pInfo->bUseDIB = FALSE;
1.1       root     1066: 
                   1067:                 GetSystemDirectory((LPSTR) szDirName, 256);
                   1068:                 strcpy(szFile, "*.bmp\0");
                   1069:                 ofn.lStructSize = sizeof(OPENFILENAME);
1.1.1.3 ! root     1070:                 ofn.hwndOwner = pInfo->hwnd;
1.1       root     1071:                 ofn.lpstrFilter = szFilter;
                   1072:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
                   1073:                 ofn.nMaxCustFilter = 0L;
                   1074:                 ofn.nFilterIndex = 0L;
                   1075:                 ofn.lpstrFile = szFile;
                   1076:                 ofn.nMaxFile = sizeof(szFile);
                   1077:                 ofn.lpstrFileTitle = szFileTitle;
                   1078:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
                   1079:                 ofn.lpstrInitialDir = szDirName;
                   1080:                 ofn.lpstrTitle = (LPSTR) NULL;
                   1081:                 ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
                   1082:                 ofn.nFileOffset = 0;
                   1083:                 ofn.nFileExtension = 0;
                   1084:                 ofn.lpstrDefExt = (LPSTR)NULL;
                   1085: 
                   1086:                 if (!GetSaveFileName(&ofn)) {
                   1087:                     ReleaseDC(pInfo->hwnd, hDC);
                   1088:                     bReleaseInfoData(hwnd);
                   1089:                     return 0L;
                   1090:                 }
                   1091: 
1.1.1.3 ! root     1092:                 SelectPalette(hDC,
        !          1093:                    ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
        !          1094:                    FALSE);
        !          1095:                 RealizePalette(hDC);
        !          1096:                 UpdateColors(hDC);
        !          1097: 
        !          1098:                 //
        !          1099:                 // test
        !          1100:                 //
        !          1101:                 ghPal = pInfo->hPal;
        !          1102: 
1.1       root     1103:                 SaveBitmapFile(hDC, pInfo->hBmpSaved, szFile);
1.1.1.3 ! root     1104: 
1.1       root     1105:                 ReleaseDC(pInfo->hwnd, hDC);
                   1106: 
                   1107:                 bReleaseInfoData(hwnd);
                   1108:                 return 0L;
                   1109:             }
                   1110:             case MM_SAVE_MONO: {
                   1111:                 HDC hDC;
                   1112:                 OPENFILENAME ofn;
                   1113:                 char szDirName[256];
                   1114:                 char szFile[256], szFileTitle[256];
                   1115:                 static char *szFilter;
1.1.1.3 ! root     1116: 
        !          1117:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
        !          1118:                     return 0L;
        !          1119:                 }
        !          1120: 
1.1       root     1121:                 szFilter = "DIB files (*.bmp)\0\0";
                   1122: 
                   1123:                 GetSystemDirectory((LPSTR) szDirName, 256);
                   1124:                 strcpy(szFile, "*.bmp\0");
                   1125:                 ofn.lStructSize = sizeof(OPENFILENAME);
1.1.1.3 ! root     1126:                 ofn.hwndOwner = pInfo->hwnd;
1.1       root     1127:                 ofn.lpstrFilter = szFilter;
                   1128:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
                   1129:                 ofn.nMaxCustFilter = 0L;
                   1130:                 ofn.nFilterIndex = 0L;
                   1131:                 ofn.lpstrFile = szFile;
                   1132:                 ofn.nMaxFile = sizeof(szFile);
                   1133:                 ofn.lpstrFileTitle = szFileTitle;
                   1134:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
                   1135:                 ofn.lpstrInitialDir = szDirName;
                   1136:                 ofn.lpstrTitle = "Saving Monochrome Bitmap";
                   1137:                 ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
                   1138:                 ofn.nFileOffset = 0;
                   1139:                 ofn.nFileExtension = 0;
                   1140:                 ofn.lpstrDefExt = (LPSTR)NULL;
                   1141: 
                   1142:                 if (!GetSaveFileName(&ofn))
                   1143:                     return 0L;
1.1.1.3 ! root     1144: 
1.1       root     1145:                 hDC = GetDC(pInfo->hwnd);
                   1146: 
                   1147:                 SaveBitmapFile(hDC, pInfo->hBmpMono, szFile);
                   1148:                 ReleaseDC(pInfo->hwnd, hDC);
                   1149: 
                   1150:                 bReleaseInfoData(hwnd);
                   1151:                 return 0L;
                   1152:             }
                   1153:             case MM_STRETCHBLT: {
                   1154:                 if ((pInfo = pGetInfoData(hwnd)) == NULL){
                   1155:                     return 0L;
                   1156:                 }
1.1.1.3 ! root     1157:                 gbStretch = TRUE;
        !          1158:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_STRETCHBLT);
        !          1159:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1       root     1160:                 pInfo->bStretch = gbStretch;
                   1161:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1162: 
                   1163:                 bReleaseInfoData(hwnd);
                   1164:                 return 0L;
                   1165: 
                   1166:             }
                   1167:             case MM_BITBLT: {
                   1168:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1169:                     return 0L;
                   1170:                 }
1.1.1.3 ! root     1171:                 gbStretch = FALSE;
        !          1172:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_BITBLT);
        !          1173:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1       root     1174:                 pInfo->bStretch = gbStretch;
                   1175:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1176: 
                   1177:                 bReleaseInfoData(hwnd);
                   1178:                 return 0L;
                   1179: 
                   1180:             }
                   1181:             case MM_BLACKONWHITE: {
                   1182:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1183:                     return 0L;
                   1184:                 }
1.1.1.3 ! root     1185:                 giStretchMode = BLACKONWHITE;
        !          1186:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_BLACKONWHITE);
        !          1187:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1       root     1188:                 pInfo->iStretchMode = giStretchMode;
                   1189:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1190: 
                   1191:                 bReleaseInfoData(hwnd);
                   1192:                 return 0L;
                   1193: 
                   1194:             }
                   1195:             case MM_COLORONCOLOR: {
                   1196:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1197:                     return 0L;
                   1198:                 }
1.1.1.3 ! root     1199:                 giStretchMode = COLORONCOLOR;
        !          1200:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_COLORONCOLOR);
        !          1201:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1       root     1202:                 pInfo->iStretchMode = giStretchMode;
                   1203:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1204: 
                   1205:                 bReleaseInfoData(hwnd);
                   1206:                 return 0L;
                   1207: 
                   1208:             }
                   1209:             case MM_WHITEONBLACK: {
                   1210:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1211:                     return 0L;
                   1212:                 }
1.1.1.3 ! root     1213:                 giStretchMode = WHITEONBLACK;
        !          1214:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_WHITEONBLACK);
        !          1215:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1       root     1216:                 pInfo->iStretchMode = giStretchMode;
                   1217:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1218: 
                   1219:                 bReleaseInfoData(hwnd);
                   1220:                 return 0L;
                   1221: 
                   1222:             }
                   1223:             case MM_HALFTONE: {
                   1224:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1225:                     return 0L;
                   1226:                 }
1.1.1.3 ! root     1227:                 giStretchMode = HALFTONE;
        !          1228:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_HALFTONE);
        !          1229:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1       root     1230:                 pInfo->iStretchMode = giStretchMode;
                   1231:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1232: 
                   1233:                 bReleaseInfoData(hwnd);
                   1234:                 return 0L;
                   1235:             }
                   1236:             case MM_SETDIB2DEVICE: {
                   1237:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1238:                     return 0L;
                   1239:                 }
                   1240:                 bDIB2Device = (bDIB2Device ? FALSE : TRUE);
                   1241:                 pInfo->bSetDIBsToDevice = bDIB2Device;
                   1242:                 CheckMenuItem(hChildMenu, MM_SETDIB2DEVICE, (bDIB2Device ? MF_CHECKED : MF_UNCHECKED));
                   1243:                 bReleaseInfoData(hwnd);
                   1244:                 return 0L;
                   1245:             }
                   1246:            case MM_BW: {
                   1247:                 HDC hDC;
                   1248: 
                   1249:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1250:                     return 0L;
                   1251:                 }
                   1252:                 hDC = GetDC(pInfo->hwnd);
                   1253:                 bChangeDIBColor(hDC, pInfo, MM_BW);
                   1254:                 ReleaseDC(hwnd, hDC);
                   1255:                 bReleaseInfoData(hwnd);
                   1256:                 return 0L;
                   1257:             }
                   1258:            case MM_SHIFT: {
                   1259:                 HDC hDC;
                   1260: 
                   1261:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1262:                     return 0L;
                   1263:                 }
                   1264:                 hDC = GetDC(pInfo->hwnd);
                   1265:                 bChangeDIBColor(hDC, pInfo, MM_SHIFT);
                   1266:                 ReleaseDC(hwnd, hDC);
                   1267:                 bReleaseInfoData(hwnd);
                   1268:                 return 0L;
                   1269:             }
                   1270:            case MM_CUSTOM: {
                   1271:                 static DWORD argbCust[16] = {
                   1272:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1273:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1274:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1275:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1276:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1277:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1278:                     RGB(255, 255, 255), RGB(255, 255, 255),
                   1279:                     RGB(255, 255, 255), RGB(255, 255, 255)
                   1280:                 };
                   1281:                 CHOOSECOLOR cc;
                   1282:                 BOOL bResult;
                   1283:                 DWORD rgbOld;
                   1284:                 HBRUSH hBrush;
                   1285:                 HDC hDC;
                   1286: 
                   1287:                 rgbOld = RGB(255, 255, 255);
                   1288:                 cc.lStructSize = sizeof(CHOOSECOLOR);
                   1289:                 cc.hwndOwner = ghwndMain;
                   1290:                 cc.hInstance = ghModule;
                   1291:                 cc.rgbResult = rgbOld;
                   1292:                 cc.lpCustColors = argbCust;
                   1293:                 cc.Flags = CC_RGBINIT | CC_SHOWHELP;
                   1294:                 cc.lCustData = 0;
                   1295:                 cc.lpfnHook = NULL;
                   1296:                 cc.lpTemplateName = NULL;
                   1297: 
                   1298:                 bResult = ChooseColor(&cc);
                   1299:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1300:                     return 0L;
                   1301:                 }
                   1302:                 if (bResult) {
                   1303:                     hDC = GetDC(pInfo->hwnd);
                   1304:                     hBrush = hBrCreateBrush(hDC, cc.rgbResult);
                   1305:                     ReleaseDC(pInfo->hwnd, hDC);
                   1306:                     if (pInfo->hBrush)
                   1307:                         DeleteObject(pInfo->hBrush);
                   1308:                     pInfo->hBrush = hBrush;
                   1309:                     pInfo->bFill = TRUE;
                   1310:                 }
                   1311:                 bReleaseInfoData(hwnd);
                   1312:                 return 0L;
                   1313:                 }
                   1314: 
                   1315: #ifndef CYCLETHRD
                   1316:             case MM_CYCLE: {
                   1317:                 HDC hDC;
                   1318: 
                   1319:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1320:                     return 0L;
                   1321:                 }
                   1322:                 hDC = GetDC(pInfo->hwnd);
                   1323: 
                   1324:                 if (pInfo->bClrCycle) {
                   1325:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
                   1326:                     pInfo->bClrCycle = FALSE;
                   1327:                 } else {
                   1328:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
                   1329:                     pInfo->bClrCycle = TRUE;
                   1330:                     bChangeDIBColor(hDC, pInfo, MM_CYCLE);
                   1331:                 }
                   1332: 
                   1333:                 ReleaseDC(hwnd, hDC);
                   1334:                 bReleaseInfoData(hwnd);
                   1335:                 return 0L;
                   1336:             }
                   1337: #else
                   1338: 
                   1339:             case MM_CYCLE: {
                   1340:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1341:                     return 0L;
                   1342:                 }
                   1343: 
                   1344:                 if (pInfo->bFirstTime) {
                   1345:                     if (!SetEvent(pInfo->hQuitEvent)) {
                   1346:                         MessageBox(ghwndMain, "Can't set Quit Event!",
                   1347:                                    "Error", MB_OK);
                   1348:                         return 0L;
                   1349:                     }
                   1350: 
1.1.1.3 ! root     1351:                     if (pInfo->hCycleThrd)
        !          1352:                         CloseHandle(pInfo->hCycleThrd);
        !          1353: 
1.1       root     1354:                     pInfo->hCycleThrd = CreateThread(NULL, 0,
                   1355:                                      (LPTHREAD_START_ROUTINE)bCycle,
1.1.1.3 ! root     1356:                                      (LPVOID)hwnd,
1.1       root     1357:                                      STANDARD_RIGHTS_REQUIRED,
                   1358:                                      &pInfo->dwCycleThrdID );
                   1359:                     pInfo->bClrCycle = TRUE;
                   1360:                     pInfo->bFirstTime = FALSE;
                   1361:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
                   1362:                 } else {
                   1363:                     if (pInfo->bClrCycle) {
                   1364:                         CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED);
                   1365:                         pInfo->bClrCycle = FALSE;
                   1366:                         pInfo->dwSuspend = SuspendThread(pInfo->hCycleThrd);
                   1367:                     } else {
                   1368:                         CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED);
                   1369:                         pInfo->bClrCycle = TRUE;
                   1370:                         pInfo->dwSuspend = ResumeThread(pInfo->hCycleThrd);
                   1371:                     }
                   1372:                     if (pInfo->dwSuspend == -1) {
                   1373:                         (pInfo->bClrCycle ?
                   1374:                          sprintf( gtext,"Error in resuming thread\n") :
                   1375:                          sprintf( gtext,"Error in suspending thread\n")  );
                   1376:                         OutputDebugString( gtext );
                   1377:                     }
                   1378:                 }
                   1379: 
                   1380:                 bReleaseInfoData(hwnd);
                   1381:                 return 0L;
                   1382:             }
                   1383: #endif
                   1384:             case MM_CLIP: {
                   1385:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1386:                     return 0L;
                   1387:                 }
                   1388: 
                   1389:                 hTextWnd = pInfo->hTextWnd;
                   1390:                 sprintf( gtext,"(%g, %g) <-> (%g, %g)", pInfo->xFrom, pInfo->yFrom, pInfo->xTo, pInfo->yTo);
                   1391:                 SetWindowText(hTextWnd, gtext);
                   1392:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n\n", pInfo->c1, pInfo->c2);
                   1393:                 OutputDebugString( gtext );
                   1394:                 if (!pInfo->bMandel) {
                   1395:                     MessageBox(ghwndMain, "Boundary Tracing and Setting clip region to the boundary points only works for Mandelbrot Set.", "Error", MB_OK);
                   1396:                     return 0L;
                   1397:                 }
1.1.1.3 ! root     1398: 
        !          1399:                 if (pInfo->hThrd)
        !          1400:                     CloseHandle(pInfo->hThrd);
        !          1401: 
1.1       root     1402:                 pInfo->hThrd = CreateThread(NULL, 0,
                   1403:                                  (gFloat ? (LPTHREAD_START_ROUTINE)bBoundaryScanFix : (LPTHREAD_START_ROUTINE)bBoundaryScanFix),
                   1404:                                  pInfo,
                   1405:                                  STANDARD_RIGHTS_REQUIRED,
                   1406:                                  &pInfo->dwThreadId );
                   1407: 
                   1408:                bReleaseInfoData(hwnd);
                   1409:                return 0L;
                   1410:            }
                   1411:             case MM_RM_CLIP: {
                   1412:                 HDC     hDC;
                   1413: 
                   1414:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1415:                     return 0L;
                   1416:                 }
                   1417: 
                   1418:                 hDC = GetDC(pInfo->hwnd);
                   1419:                 SelectClipRgn(hDC, (HRGN) NULL);
                   1420:                 ReleaseDC(pInfo->hwnd, hDC);
                   1421:                 bReleaseInfoData(hwnd);
                   1422:                 InvalidateRect(pInfo->hwnd, NULL, FALSE);
                   1423:                 return 0L;
                   1424: 
                   1425:             }
1.1.1.3 ! root     1426:             case MM_SELCLIPRGN: {
        !          1427:                 HDC     hDC;
        !          1428: 
        !          1429:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1430:                     return 0L;
        !          1431:                 }
        !          1432:                 hDC = GetDC(pInfo->hwnd);
        !          1433: 
        !          1434:                 if (pInfo->hRgnPath != (HRGN) NULL) {
        !          1435:                     SelectClipRgn(hDC, pInfo->hRgnPath);
        !          1436:                 }
        !          1437: 
        !          1438:                 ReleaseDC(pInfo->hwnd, hDC);
        !          1439:                 bReleaseInfoData(hwnd);
        !          1440:                 return 0L;
        !          1441:             }
1.1       root     1442:             case MM_ERASE: {
                   1443:                 HDC     hDC;
                   1444:                 RECT    rc;
                   1445: 
                   1446:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1447:                     return 0L;
                   1448:                 }
                   1449:                 hDC = GetDC(pInfo->hwnd);
                   1450:                 if (pInfo->hRgnPath != (HRGN) NULL) {
                   1451:                     SelectClipRgn(hDC, pInfo->hRgnPath);
                   1452:                 }
                   1453:                 SelectObject(hDC, GetStockObject(WHITE_BRUSH));
                   1454:                 GetClientRect(pInfo->hwnd, &rc);
                   1455:                 PatBlt(hDC, 0, 0, rc.right, rc.bottom, PATCOPY);
                   1456:                 ReleaseDC(pInfo->hwnd, hDC);
                   1457:                 bReleaseInfoData(hwnd);
                   1458:                 return 0L;
                   1459:             }
                   1460:             case MM_PORTRAIT: {
1.1.1.3 ! root     1461:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1462:                     return 0L;
        !          1463:                 }
        !          1464: 
1.1       root     1465:                 giDmOrient = DMORIENT_PORTRAIT;
1.1.1.3 ! root     1466:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_PORTRAIT);
1.1       root     1467:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1.1.3 ! root     1468:                 bReleaseInfoData(hwnd);
1.1       root     1469:                 return 0L;
                   1470:             }
                   1471:             case MM_LANDSCAPE: {
1.1.1.3 ! root     1472:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1473:                     return 0L;
        !          1474:                 }
        !          1475: 
1.1       root     1476:                 giDmOrient = DMORIENT_LANDSCAPE;
1.1.1.3 ! root     1477:                 bCheckMutexMenuItem(pInfo, hChildMenu, MM_LANDSCAPE);
1.1       root     1478:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
1.1.1.3 ! root     1479:                 bReleaseInfoData(hwnd);
1.1       root     1480:                 return 0L;
                   1481:             }
                   1482:             case MM_PRINTER:
                   1483:             case MM_PRINTER + 1:
                   1484:             case MM_PRINTER + 2:
                   1485:             case MM_PRINTER + 3:
                   1486:             case MM_PRINTER + 4:
                   1487:             case MM_PRINTER + 5:
                   1488:             case MM_PRINTER + 6:
                   1489:             case MM_PRINTER + 7:
                   1490:             case MM_PRINTER + 8:
                   1491: 
                   1492: #ifdef PRTTHRD
                   1493:             case MM_PRINTER + 9: {
                   1494:                 PINFO       pInfo;
                   1495:                 PRTDATA     PrtData, *pPrtData;
                   1496:                 ULONG       sizINFO;
                   1497:                 PBYTE       pjTmpInfo, pjTmp;
                   1498: 
                   1499:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1500:                     return 0L;
                   1501:                 }
                   1502: 
                   1503:                 if (pInfo->hBmpSaved == NULL) {
                   1504:                     MessageBox(ghwndMain, "No Saved bitmap to print", "Error", MB_OK);
                   1505:                     return 0L;
                   1506:                 }
                   1507: 
                   1508:                 //
                   1509:                 // Copy the info structure to PrtData
                   1510:                 //
                   1511:                 pPrtData = &PrtData;
                   1512:                 pjTmp    = (PBYTE)&(pPrtData->info);
                   1513:                 pjTmpInfo = (PBYTE)pInfo;
                   1514:                 sizINFO = sizeof(INFO);
                   1515: 
                   1516:                 while(sizINFO--)
                   1517:                 {
                   1518:                     *(((PBYTE)pjTmp)++) = *((pjTmpInfo)++);
                   1519:                 }
                   1520: 
                   1521:                 PrtData.index = LOWORD(wParam) - MM_PRINTER;
                   1522: 
                   1523:                 if (giDmOrient == DMORIENT_PORTRAIT) {
                   1524:                     PrtData.bUseDefault = TRUE;
                   1525:                 } else {
                   1526:                     PrtData.bUseDefault = FALSE;
                   1527:                     PrtData.DevMode.dmSize = sizeof(DEVMODE);
                   1528:                     PrtData.DevMode.dmDriverExtra = 0;
                   1529:                     PrtData.DevMode.dmOrientation = DMORIENT_LANDSCAPE;
                   1530:                     PrtData.DevMode.dmFields = DM_ORIENTATION;
                   1531:                 }
                   1532: 
1.1.1.3 ! root     1533:                 if (pInfo->hPrtThrd)
        !          1534:                     CloseHandle(pInfo->hPrtThrd);
        !          1535: 
1.1       root     1536:                 pInfo->hPrtThrd = CreateThread(NULL, 0,
                   1537:                                  (LPTHREAD_START_ROUTINE)bPrintBmp,
                   1538:                                  &PrtData,
                   1539:                                  STANDARD_RIGHTS_REQUIRED,
                   1540:                                  &pInfo->dwPrtThrdID );
                   1541: 
                   1542:                 bReleaseInfoData(hwnd);
                   1543:                 return 0L;
                   1544:             }
                   1545: 
                   1546: #else
                   1547:             case MM_PRINTER + 9: {
                   1548:                 HDC         hdcPrinter, hDC;
                   1549:                 int         index;
                   1550:                 DEVMODE     devmode;
                   1551:                 DEVMODE     *pdevmode;
                   1552:                 PINFO       pInfo;
                   1553:                 int         iWidth, iHeight;
                   1554: 
                   1555: 
                   1556:                 index = LOWORD(wParam) - MM_PRINTER;
                   1557: 
                   1558:                 if (giDmOrient == DMORIENT_PORTRAIT)
                   1559:                     pdevmode = NULL;
                   1560:                 else {
                   1561:                     pdevmode = &devmode;
                   1562:                     devmode.dmSize = sizeof(DEVMODE);
                   1563:                     devmode.dmDriverExtra = 0;
                   1564:                     devmode.dmOrientation = DMORIENT_LANDSCAPE;
                   1565:                     devmode.dmFields = DM_ORIENTATION;
                   1566:                 }
                   1567: 
                   1568:                 if (!(hdcPrinter = CreateDC( "", gpszPrinterNames[index],
                   1569:                                              "", pdevmode)))
                   1570:                 {
                   1571:                     return(0L);
                   1572:                 }
                   1573: 
                   1574:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1575:                     return 0L;
                   1576:                 }
                   1577: 
                   1578:                 iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
                   1579:                 iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
                   1580: 
1.1.1.3 ! root     1581: // !!! Why is it necessary to save the image over again?  May not want to
        !          1582: //     do this because user may want to print the nice HT bitmap. So,
        !          1583: //     use the DIB src.
        !          1584: #if 0
1.1       root     1585:                 if (pInfo->hBmpSaved)
                   1586:                     DeleteObject(pInfo->hBmpSaved);
                   1587: 
1.1.1.3 ! root     1588:                 pInfo->hBmpSaved = SaveBitmap(pInfo->hwnd, pInfo->hPal);
        !          1589: #endif
1.1       root     1590:                Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
1.1.1.2   root     1591:                 bDrawDIB(hdcPrinter, pInfo, 0, 0, iWidth, iHeight);
1.1.1.3 ! root     1592:                 Escape(hdcPrinter, NEWFRAME, 0, NULL, NULL);
        !          1593:                 Escape(hdcPrinter, ENDDOC, 0, NULL, NULL);
1.1       root     1594:                 ReleaseDC(pInfo->hwnd, hDC);
                   1595:                 bReleaseInfoData(hwnd);
                   1596:                 DeleteDC(hdcPrinter);
                   1597:                 return 0L;
                   1598:             }
                   1599: #endif
                   1600:             default:
                   1601:                return 0L;
                   1602: 
                   1603:          }
                   1604: 
                   1605:        }
                   1606:        case WM_SETFOCUS:
                   1607:            break;
                   1608: 
                   1609:        case WM_MDIACTIVATE: {
                   1610:             PINFO       pInfo;
                   1611: 
                   1612:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1613:                 return 0L;
                   1614:             }
                   1615: 
1.1.1.3 ! root     1616:            if ((HWND) lParam == hwnd) {                // being activated
1.1       root     1617:                SendMessage(GetParent(hwnd), WM_MDISETMENU,
                   1618:                            (DWORD)  hChildMenu,
                   1619:                            (LONG)   hSubMenuThree) ;
                   1620: 
                   1621:                 (pInfo->bClrCycle ?
                   1622:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_CHECKED) :
                   1623:                     CheckMenuItem(hChildMenu, MM_CYCLE, MF_UNCHECKED) );
                   1624: 
1.1.1.3 ! root     1625:                 vChkMenuItem(pInfo, hChildMenu, MF_CHECKED);
        !          1626:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          1627:                 goto MDI_ACT_EXIT;
        !          1628:             }
        !          1629: 
        !          1630:             if ((HWND) wParam == hwnd) {                // being deactivated
        !          1631: 
        !          1632:                 vChkMenuItem(pInfo, hChildMenu, MF_UNCHECKED);
        !          1633:                 DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          1634:             }
        !          1635: MDI_ACT_EXIT:
        !          1636:             bReleaseInfoData(hwnd);
        !          1637:            return 0L;
        !          1638:         }
        !          1639: 
        !          1640:         case WM_QUERYNEWPALETTE:
        !          1641:         case WM_PALETTECHANGED: {
        !          1642:             PINFO       pInfo;
        !          1643: 
        !          1644:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1645:                 return 0L;
        !          1646:             }
        !          1647: 
        !          1648:            SendMessage(pInfo->hwnd, message, wParam, lParam);
        !          1649:             bReleaseInfoData(hwnd);
        !          1650:            return 0L;
1.1       root     1651:         }
1.1.1.3 ! root     1652: 
1.1       root     1653: #if 0
                   1654:         case WM_WINDOWPOSCHANGING: {
                   1655:             PWINDOWPOS  pWndPos;
                   1656:             PINFO       pInfo;
                   1657:             HWND        hTextWnd;
                   1658:             int         iCyText, iCxBorder, iCyBorder, iCyCaption;
                   1659:             RECT        rect, rcl;
                   1660:             LONG        lcx, lcy;
                   1661: 
                   1662:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1663:                 break;
                   1664:             }
                   1665: 
                   1666:             hTextWnd = pInfo->hTextWnd;
                   1667: 
                   1668:             bReleaseInfoData(hwnd);
                   1669: 
                   1670:             iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
                   1671:             iCxBorder = GetSystemMetrics(SM_CXBORDER);
                   1672:             iCyBorder = GetSystemMetrics(SM_CYBORDER);
                   1673:             iCyCaption = GetSystemMetrics(SM_CYCAPTION) - iCyBorder;
                   1674:             GetClientRect(GetParent(hwnd), &rcl);
                   1675:             GetWindowRect(hwnd, &rect);
                   1676:             lcx = rect.right-rect.left;
                   1677:             lcy = rect.bottom-rect.top;
                   1678:             pWndPos = (PWINDOWPOS)lParam;
                   1679:             if ((pWndPos->cy > lcy) || (pWndPos->cx > lcx)) {
                   1680:                 pWndPos->cx =
                   1681:                    ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
                   1682:                 pWndPos->cy = pWndPos->cx + iCyText;
                   1683:             } else { if ((pWndPos->cy < lcy) || (pWndPos->cx < lcx)) {
                   1684:                      pWndPos->cx =
                   1685:                         ((pWndPos->cx > pWndPos->cy) ? pWndPos->cy-iCyText : pWndPos->cx);
                   1686:                      pWndPos->cy = pWndPos->cx + iCyText;
                   1687:                    }
                   1688:             }
                   1689:             break;
                   1690:         }
                   1691: #endif
                   1692:        case WM_SIZE: {
                   1693:             HANDLE      hThrd;
                   1694:             PINFO       pInfo;
                   1695:             HWND        hTextWnd, hJulia;
                   1696:             BOOL        bMandel;
                   1697:             WORD        wCx;
                   1698:             int         iCyText;
                   1699: 
                   1700:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1701:                 break;
                   1702:             }
                   1703: 
                   1704:             hTextWnd = pInfo->hTextWnd;
                   1705:             hJulia   = pInfo->hwnd;
                   1706:             hThrd    = pInfo->hThrd;
                   1707:             bMandel  = pInfo->bMandel;
                   1708:             bReleaseInfoData(hwnd);
                   1709:             iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
                   1710:             wCx = (WORD) (HIWORD(lParam) - iCyText);
                   1711: 
                   1712:             MoveWindow(hJulia, 0, 0,
                   1713:                           LOWORD(lParam),
                   1714:                            wCx,
                   1715:                           TRUE);
                   1716: 
                   1717:            MoveWindow(hTextWnd,
                   1718:                       0,
                   1719:                       wCx,
                   1720:                       LOWORD(lParam),
                   1721:                        iCyText,
                   1722:                       TRUE);
                   1723: 
                   1724:             if (hThrd) {
                   1725:                 TerminateThread(hThrd, (DWORD)0L);
                   1726:                 /*
                   1727:                 PostMessage(hwnd, WM_COMMAND,
                   1728:                     bMandel ? (DWORD)((WORD)MM_CREATE_MANDEL_THREAD) : (DWORD)((WORD)MM_CREATE_JULIA_THREAD),
                   1729:                     (LONG)0L);
                   1730:                   */
                   1731:             }
                   1732: 
                   1733:            break;
                   1734:         }
                   1735: 
                   1736:         //
                   1737:         // display info in the status window
                   1738:         //
                   1739:         case WM_USER+0xa: {
                   1740:             PINFO       pInfo;
                   1741:             static ULONG ulClick = 0;
                   1742:             HWND        hTextWnd;
                   1743: 
                   1744:             ulClick++;
                   1745:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1746:                 return 0L;
                   1747:             }
                   1748: 
                   1749:             hTextWnd = pInfo->hTextWnd;
                   1750:             switch (ulClick % 6) {
                   1751:                 case 0: sprintf( gtext,"%g <= x <= %g, %g <= y <= %g", pInfo->xFrom, pInfo->xTo, pInfo->yTo, pInfo->yFrom);
                   1752:                         break;
                   1753:                 case 1: sprintf( gtext,"c1 = %g, c2 = %g", pInfo->c1, pInfo->c2);
                   1754:                         break;
                   1755:                 case 2: sprintf( gtext,"Elapsed Time = %ld", (ULONG) pInfo->dwElapsed);
                   1756:                         break;
                   1757:                 case 3: sprintf( gtext,"Iteration = %d", pInfo->iIteration);
                   1758:                         break;
                   1759:                 case 4: sprintf( gtext,"Step = %d", pInfo->iStep);
                   1760:                         break;
                   1761:                 case 5: (gFloat ? sprintf( gtext,"Floating point math")
                   1762:                                        : sprintf( gtext,"Fix point math")) ;
                   1763:                         break;
                   1764: 
                   1765:                 default: break;
                   1766:             }
                   1767:             SetWindowText(hTextWnd, gtext);
                   1768:             bReleaseInfoData(hwnd);
                   1769:             return 0L;
                   1770:         }
                   1771: 
                   1772:         case WM_SYSCOMMAND: {
                   1773:             LONG        lResult;
                   1774: 
                   1775:             EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
                   1776: 
                   1777:             lResult = DefMDIChildProc(hwnd, message, wParam, lParam);
                   1778: 
                   1779:             EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
                   1780: 
                   1781:             return lResult;
                   1782:             break;
                   1783:         }
                   1784: 
                   1785:        case WM_CREATE: {
                   1786:             PINFO           pInfo;
                   1787:             HANDLE          hInfo;
                   1788:             HWND            hTextWnd, hJulia;
                   1789:            RECT            rcl;
                   1790: 
                   1791:             //
                   1792:             // CR! MakeProcInstance is noop!
                   1793:             //
                   1794:             lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
                   1795:             lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
                   1796: 
                   1797:             hTextWnd = CreateWindow("Text", NULL,
                   1798:                                     WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
                   1799:                                     0, 0, 0, 0,
                   1800:                                     hwnd,
                   1801:                                     (HMENU) 2,
                   1802:                                     ghModule,
                   1803:                                     NULL);
                   1804: 
                   1805:             GetClientRect(hwnd, &rcl);
                   1806:             hJulia = CreateWindow("Julia", (LPSTR) NULL,
                   1807:                           WS_CHILD      | WS_VISIBLE     |
                   1808:                           WS_BORDER,
                   1809:                           0,0, rcl.right-rcl.left,
                   1810:                           rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
                   1811:                           hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
                   1812: 
                   1813:             SetWindowText(hTextWnd, "Select the 'Draw Set' menu item to start drawing.");
                   1814:             hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
                   1815:             if (hInfo) {
                   1816:                 if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
                   1817:                     MessageBox(ghwndMain, "Failed in LocalLock, hNode", "Error", MB_OK);
                   1818:                     break;
                   1819:                 } else {
1.1.1.3 ! root     1820:                     HDC hDC;
        !          1821: 
1.1       root     1822:                     if (!GetClientRect(hwnd, &pInfo->rcClient))
                   1823:                         MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK);
                   1824: 
                   1825:                     pInfo->hTextWnd = hTextWnd;
                   1826:                     pInfo->hwnd = hJulia;
1.1.1.3 ! root     1827:                     hDC = GetDC(hJulia);
        !          1828:                     pInfo->hHTPal = CreateHalftonePalette(hDC);
        !          1829:                     ReleaseDC(hJulia, hDC);
1.1       root     1830: #ifdef CYCLETHRD
                   1831:                     //
                   1832:                     // Creating a signal quit color cycling event
                   1833:                     //
                   1834:                     if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
                   1835:                         MessageBox(ghwndMain, "Failed in creating Quit Event!", "Error", MB_OK);
                   1836: #endif
                   1837:                     SetWindowLong(hwnd, 0, (LONG) hInfo);
                   1838:                     LocalUnlock(hInfo);
                   1839:                 }
                   1840:            } else {
                   1841:                MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK);
                   1842:            }
                   1843: 
                   1844: #if 0
                   1845:             //
                   1846:             // Initialize printers here will detect printers availiability
                   1847:             // more often, but kind of overkill.
                   1848:             //
                   1849:             bInitPrinter(hwnd);
                   1850: #endif
                   1851:             break;
                   1852:        }
                   1853: 
                   1854:         case WM_CLOSE: {
                   1855:            SendMessage(GetParent(hwnd), WM_MDISETMENU,
                   1856:                            (DWORD) hMenu,
                   1857:                            (LONG)  hSubMenuOne) ;
                   1858:            DrawMenuBar(GetParent(GetParent(hwnd))) ;
                   1859:             break;
                   1860:         }
                   1861: 
                   1862:         case WM_DESTROY: {
                   1863:             PINFO            pInfo;
                   1864:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
                   1865:                 break;
                   1866:             }
                   1867: 
1.1.1.3 ! root     1868:             if (pInfo->hThrd) {
        !          1869:                 TerminateThread(pInfo->hThrd, (DWORD)0L);
        !          1870:                 CloseHandle(pInfo->hThrd);
        !          1871:             }
        !          1872:             if (pInfo->hPrtThrd) {
        !          1873:                 TerminateThread(pInfo->hPrtThrd, (DWORD)0L);
        !          1874:                 CloseHandle(pInfo->hPrtThrd);
        !          1875:             }
        !          1876:             if (pInfo->hCycleThrd) {
        !          1877:                 TerminateThread(pInfo->hCycleThrd, (DWORD)0L);
        !          1878:                 CloseHandle(pInfo->hCycleThrd);
        !          1879:             }
        !          1880: 
1.1       root     1881: 
                   1882: #ifdef CYCLETHRD
                   1883:             //
                   1884:             // Cleanup color cycling
                   1885:             //
                   1886:             if (!ResetEvent(pInfo->hQuitEvent))
                   1887:                 MessageBox(ghwndMain, "Failed in reseting quit event!", "Error", MB_OK);
                   1888: #endif
                   1889:             if (pInfo->hBmpMono)
                   1890:                 DeleteObject(pInfo->hBmpMono);
                   1891: 
                   1892:             if (pInfo->hBmpSaved)
                   1893:                 DeleteObject(pInfo->hBmpSaved);
                   1894: 
                   1895:             if (pInfo->hBrush)
                   1896:                 DeleteObject(pInfo->hBrush);
                   1897: 
                   1898:             bReleaseInfoData(hwnd);
                   1899:             LocalFree((HANDLE) GetWindowLong(hwnd, 0));
                   1900:             break;
                   1901:        }
                   1902: 
                   1903:        default:
                   1904:            return DefMDIChildProc(hwnd, message, wParam, lParam);
                   1905: 
                   1906:     } //switch
                   1907:     return DefMDIChildProc(hwnd, message, wParam, lParam);
                   1908: }
                   1909: 
1.1.1.3 ! root     1910: /******************************Public*Routine******************************\
1.1       root     1911: *
1.1.1.3 ! root     1912: * ViewerWndProc
        !          1913: *
        !          1914: * Effects:
        !          1915: *
        !          1916: * Warnings:
1.1       root     1917: *
                   1918: * History:
1.1.1.3 ! root     1919: *  11-Dec-1992 -by- Petrus Wong
        !          1920: * Wrote it.
        !          1921: \**************************************************************************/
1.1       root     1922: 
1.1.1.3 ! root     1923: LONG APIENTRY ViewerWndProc(
        !          1924:     HWND hwnd,
1.1       root     1925:     UINT message,
                   1926:     DWORD wParam,
                   1927:     LONG lParam)
                   1928: {
1.1.1.3 ! root     1929:     static FARPROC     lpfnSuspendThrd, lpfnResumeThrd;
        !          1930: 
1.1       root     1931:     switch (message) {
1.1.1.3 ! root     1932:        case WM_COMMAND: {
        !          1933:           PINFO       pInfo;
        !          1934:           HWND        hTextWnd;
1.1       root     1935: 
1.1.1.3 ! root     1936:          switch (LOWORD(wParam)) {
        !          1937:             case MM_RLELOAD_DEMO: {
        !          1938:                 HDC             hDC;
        !          1939:                 char            szDirName[256];
        !          1940:                 char            szFile[400];
        !          1941:                 HWND            hViewSurf;
1.1       root     1942: 
1.1.1.3 ! root     1943:                 GetCurrentDirectory(256, (LPTSTR) szDirName);
1.1       root     1944: 
1.1.1.3 ! root     1945:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          1946:                     return 0L;
        !          1947:                 }
1.1       root     1948: 
1.1.1.3 ! root     1949:                 if ((hViewSurf = pInfo->hwnd) == NULL)
        !          1950:                     return 0L;
1.1       root     1951: 
1.1.1.3 ! root     1952:                 hTextWnd = pInfo->hTextWnd;
        !          1953:                 sprintf( gtext,"Loading bitmap(s) into memory");
        !          1954:                 SetWindowText(hTextWnd, gtext);
1.1       root     1955: 
1.1.1.3 ! root     1956:                 hDC = GetDC(hViewSurf);
        !          1957:                 strcpy(szFile, szDirName);
        !          1958:                 strcat(szFile, "\\rsc\\julia.rle");
1.1       root     1959: 
1.1.1.3 ! root     1960:                 if (bStoreRleFile(hDC, pInfo, szFile)) {
        !          1961:                     pInfo->RleData.ulFiles++;
        !          1962:                     PostMessage(ghwndMain, WM_COMMAND, MM_RLEPLAYCONT, 0L);
        !          1963:                 }
1.1       root     1964: 
1.1.1.3 ! root     1965:                 ReleaseDC(hViewSurf, hDC);
1.1       root     1966: 
1.1.1.3 ! root     1967:                 bReleaseInfoData(hwnd);
        !          1968:                 return 0L;
1.1       root     1969: 
1.1.1.3 ! root     1970:             }
1.1       root     1971: 
                   1972: 
1.1.1.3 ! root     1973:             case MM_RLELOAD: {
        !          1974:                 HDC             hDC;
        !          1975:                 OPENFILENAME    ofn;
        !          1976:                 char            szDirName[256];
        !          1977:                 char            szFile[256], szFileTitle[256];
        !          1978:                 static char     *szFilter;
        !          1979:                 RECT            rc;
        !          1980:                 HWND            hViewSurf;
1.1       root     1981: 
1.1.1.3 ! root     1982:                 szFilter =
        !          1983:                   "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0";
1.1       root     1984: 
1.1.1.3 ! root     1985:                 GetSystemDirectory((LPSTR) szDirName, 256);
        !          1986:                 strcpy(szFile, "*.bmp\0");
        !          1987:                 ofn.lStructSize = sizeof(OPENFILENAME);
        !          1988:                 ofn.hwndOwner = hwnd;
        !          1989:                 ofn.lpstrFilter = szFilter;
        !          1990:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
        !          1991:                 ofn.nMaxCustFilter = 0L;
        !          1992:                 ofn.nFilterIndex = 1;
        !          1993:                 ofn.lpstrFile = szFile;
        !          1994:                 ofn.nMaxFile = sizeof(szFile);
        !          1995:                 ofn.lpstrFileTitle = szFileTitle;
        !          1996:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
        !          1997:                 ofn.lpstrInitialDir = szDirName;
        !          1998:                 ofn.lpstrTitle = (LPSTR) NULL;
        !          1999:                 ofn.Flags = 0L;
        !          2000:                 ofn.nFileOffset = 0;
        !          2001:                 ofn.nFileExtension = 0;
        !          2002:                 ofn.lpstrDefExt = "BMP";
1.1       root     2003: 
1.1.1.3 ! root     2004:                 if (!GetOpenFileName(&ofn))
        !          2005:                     return 0L;
1.1       root     2006: 
1.1.1.3 ! root     2007:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2008:                     return 0L;
        !          2009:                 }
1.1       root     2010: 
1.1.1.3 ! root     2011:                 if ((hViewSurf = pInfo->hwnd) == NULL)
        !          2012:                     return 0L;
1.1       root     2013: 
1.1.1.3 ! root     2014:                 hTextWnd = pInfo->hTextWnd;
        !          2015:                 sprintf( gtext,"Loading bitmap(s) into memory");
        !          2016:                 SetWindowText(hTextWnd, gtext);
1.1       root     2017: 
1.1.1.3 ! root     2018:                 GetClientRect(hwnd, &rc);
        !          2019:                 hDC = GetDC(hViewSurf);
        !          2020:                 if (bStoreRleFile(hDC, pInfo, szFile))
        !          2021:                     pInfo->RleData.ulFiles++;
        !          2022:                 ReleaseDC(hViewSurf, hDC);
1.1       root     2023: 
1.1.1.3 ! root     2024:                 bReleaseInfoData(hwnd);
        !          2025:                 return 0L;
1.1       root     2026: 
1.1.1.3 ! root     2027:             }
1.1       root     2028: 
1.1.1.3 ! root     2029:             case MM_RLESAVE: {
        !          2030:                 HDC             hDC;
        !          2031:                 OPENFILENAME    ofn;
        !          2032:                 char            szDirName[256];
        !          2033:                 char            szFile[256], szFileTitle[256];
        !          2034:                 static char     *szFilter;
        !          2035:                 HWND            hViewSurf;
1.1       root     2036: 
1.1.1.3 ! root     2037:                 szFilter = "DIB files (*.rle)\0\0";
1.1       root     2038: 
1.1.1.3 ! root     2039:                 GetSystemDirectory((LPSTR) szDirName, 256);
        !          2040:                 strcpy(szFile, "*.rle\0");
        !          2041:                 ofn.lStructSize = sizeof(OPENFILENAME);
        !          2042:                 ofn.hwndOwner = hwnd;
        !          2043:                 ofn.lpstrFilter = szFilter;
        !          2044:                 ofn.lpstrCustomFilter = (LPSTR) NULL;
        !          2045:                 ofn.nMaxCustFilter = 0L;
        !          2046:                 ofn.nFilterIndex = 0L;
        !          2047:                 ofn.lpstrFile = szFile;
        !          2048:                 ofn.nMaxFile = sizeof(szFile);
        !          2049:                 ofn.lpstrFileTitle = szFileTitle;
        !          2050:                 ofn.nMaxFileTitle = sizeof(szFileTitle);
        !          2051:                 ofn.lpstrInitialDir = szDirName;
        !          2052:                 ofn.lpstrTitle = "Saving Memory RLE Bitmap in File";
        !          2053:                 ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
        !          2054:                 ofn.nFileOffset = 0;
        !          2055:                 ofn.nFileExtension = 0;
        !          2056:                 ofn.lpstrDefExt = (LPSTR)NULL;
1.1       root     2057: 
1.1.1.3 ! root     2058:                 if (!GetSaveFileName(&ofn))
        !          2059:                     return 0L;
1.1       root     2060: 
1.1.1.3 ! root     2061:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2062:                     return 0L;
        !          2063:                 }
1.1       root     2064: 
1.1.1.3 ! root     2065:                 if ((hViewSurf = pInfo->hwnd) == NULL)
        !          2066:                     return 0L;
1.1       root     2067: 
1.1.1.3 ! root     2068:                 hTextWnd = pInfo->hTextWnd;
        !          2069:                 sprintf( gtext,"Saving loaded bitmap(s) into one RLE file");
        !          2070:                 SetWindowText(hTextWnd, gtext);
1.1       root     2071: 
1.1.1.3 ! root     2072:                 hDC = GetDC(hViewSurf);
        !          2073:                 bSaveRleFile(hDC, pInfo, szFile);
        !          2074:                 ReleaseDC(hViewSurf, hDC);
1.1       root     2075: 
1.1.1.3 ! root     2076:                 bReleaseInfoData(hwnd);
        !          2077:                 return 0L;
        !          2078:             }
1.1       root     2079: 
1.1.1.3 ! root     2080:             case MM_CLEAR: {
        !          2081:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2082:                     return 0L;
        !          2083:                 }
1.1       root     2084: 
1.1.1.3 ! root     2085:                 hTextWnd = pInfo->hTextWnd;
        !          2086:                 sprintf( gtext,"Discard loaded bitmap(s) from memory");
        !          2087:                 SetWindowText(hTextWnd, gtext);
1.1       root     2088: 
1.1.1.3 ! root     2089:                 bFreeRleFile(pInfo);
1.1       root     2090: 
1.1.1.3 ! root     2091:                 bReleaseInfoData(hwnd);
        !          2092:                 return 0L;
        !          2093:             }
1.1       root     2094: 
1.1.1.3 ! root     2095:             case MM_RLEPLAY: {
        !          2096:                 HDC     hDC;
        !          2097:                 HWND    hViewSurf;
1.1       root     2098: 
1.1.1.3 ! root     2099:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2100:                     return 0L;
        !          2101:                 }
1.1       root     2102: 
1.1.1.3 ! root     2103:                 if ((hViewSurf = pInfo->hwnd) == NULL)
        !          2104:                     return 0L;
1.1       root     2105: 
1.1.1.3 ! root     2106:                 hTextWnd = pInfo->hTextWnd;
        !          2107:                 sprintf( gtext,"Play loaded bitmap(s)");
        !          2108:                 SetWindowText(hTextWnd, gtext);
1.1       root     2109: 
1.1.1.3 ! root     2110:                 hDC = GetDC(hViewSurf);
        !          2111:                 EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED);
1.1       root     2112: 
1.1.1.3 ! root     2113:                 if (pInfo->hThrd0)
        !          2114:                     CloseHandle(pInfo->hThrd0);
1.1       root     2115: 
1.1.1.3 ! root     2116:                 pInfo->hThrd0 = CreateThread(NULL, 0,
        !          2117:                              (LPTHREAD_START_ROUTINE)bPlayRle,
        !          2118:                              pInfo,
        !          2119:                              STANDARD_RIGHTS_REQUIRED,
        !          2120:                              &pInfo->dwThreadId );
        !          2121: 
        !          2122:                 if (pInfo->hThrd0) {
        !          2123:                     if (!SetThreadPriority(pInfo->hThrd0, THREAD_PRIORITY_BELOW_NORMAL))
        !          2124:                          MessageBox(ghwndMain, "Can't set Priority!",
        !          2125:                                     "Error", MB_OK);
        !          2126:                 }
        !          2127: 
        !          2128:                 //bPlayRle(hDC, pInfo);
        !          2129:                 EnableMenuItem(hViewSubOne, MM_CLEAR, MF_ENABLED);
        !          2130:                 ReleaseDC(hViewSurf, hDC);
1.1       root     2131: 
1.1.1.3 ! root     2132:                 bReleaseInfoData(hwnd);
        !          2133:                 return 0L;
        !          2134:             }
1.1       root     2135: 
1.1.1.3 ! root     2136:             case MM_RLEPLAYCONT: {
        !          2137:                 HWND    hViewSurf;
1.1       root     2138: 
1.1.1.3 ! root     2139:                 if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2140:                     return 0L;
        !          2141:                 }
1.1       root     2142: 
1.1.1.3 ! root     2143:                 if ((hViewSurf = pInfo->hwnd) == NULL)
        !          2144:                     return 0L;
1.1       root     2145: 
1.1.1.3 ! root     2146:                 hTextWnd = pInfo->hTextWnd;
        !          2147:                 sprintf( gtext,"Play loaded bitmap(s) continuously");
        !          2148:                 SetWindowText(hTextWnd, gtext);
1.1       root     2149: 
1.1.1.3 ! root     2150:                 if (pInfo->bFirstTime) {
        !          2151:                     if (!SetEvent(pInfo->hQuitEvent)) {
        !          2152:                         MessageBox(ghwndMain, "Can't set Quit Event!",
        !          2153:                                    "Error", MB_OK);
        !          2154:                         return 0L;
        !          2155:                     }
1.1       root     2156: 
1.1.1.3 ! root     2157:                     EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED);
1.1       root     2158: 
1.1.1.3 ! root     2159:                     if (pInfo->hThrd)
        !          2160:                         CloseHandle(pInfo->hThrd);
1.1       root     2161: 
1.1.1.3 ! root     2162:                     pInfo->hThrd = CreateThread(NULL, 0,
        !          2163:                                  (LPTHREAD_START_ROUTINE)bPlayRleCont2,
        !          2164:                                  pInfo,
        !          2165:                                  STANDARD_RIGHTS_REQUIRED,
        !          2166:                                  &pInfo->dwThreadId );
1.1       root     2167: 
1.1.1.3 ! root     2168:                     if (pInfo->hThrd) {
        !          2169:                         if (!SetThreadPriority(pInfo->hThrd, THREAD_PRIORITY_BELOW_NORMAL))
        !          2170:                              MessageBox(ghwndMain, "Can't set Priority!",
        !          2171:                                         "Error", MB_OK);
        !          2172:                     }
1.1       root     2173: 
1.1.1.3 ! root     2174:                     pInfo->bPlayRleCont = TRUE;
        !          2175:                     pInfo->bFirstTime = FALSE;
        !          2176:                     CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_CHECKED);
        !          2177:                 } else {
        !          2178:                     if (pInfo->bPlayRleCont) {
        !          2179:                         EnableMenuItem(hViewSubOne, MM_CLEAR, MF_ENABLED);
        !          2180:                         CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_UNCHECKED);
        !          2181:                         pInfo->bPlayRleCont = FALSE;
        !          2182:                         pInfo->dwSuspend = SuspendThread(pInfo->hThrd);
        !          2183:                     } else {
        !          2184:                         EnableMenuItem(hViewSubOne, MM_CLEAR, MF_GRAYED);
        !          2185:                         CheckMenuItem(hViewMenu, MM_RLEPLAYCONT, MF_CHECKED);
        !          2186:                         pInfo->bPlayRleCont = TRUE;
        !          2187:                         pInfo->dwSuspend = ResumeThread(pInfo->hThrd);
        !          2188:                     }
        !          2189:                     if (pInfo->dwSuspend == -1) {
        !          2190:                         (pInfo->bPlayRleCont ?
        !          2191:                          sprintf( gtext,"Error in resuming thread\n") :
        !          2192:                          sprintf( gtext,"Error in suspending thread\n")  );
        !          2193:                         OutputDebugString( gtext );
        !          2194:                     }
        !          2195:                 }
1.1       root     2196: 
1.1.1.3 ! root     2197:                 bReleaseInfoData(hwnd);
        !          2198:                 return 0L;
        !          2199:             }
1.1       root     2200: 
1.1.1.3 ! root     2201:             default:
        !          2202:                return 0L;
1.1       root     2203: 
1.1.1.3 ! root     2204:          } //switch
1.1       root     2205: 
1.1.1.3 ! root     2206:        } // WM_COMMAND
        !          2207:        case WM_SETFOCUS:
        !          2208:            break;
1.1       root     2209: 
1.1.1.3 ! root     2210:        case WM_MDIACTIVATE: {
        !          2211:             PINFO       pInfo;
1.1       root     2212: 
1.1.1.3 ! root     2213:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2214:                 return 0L;
        !          2215:             }
1.1       root     2216: 
1.1.1.3 ! root     2217:            if ((HWND) lParam == hwnd) {
        !          2218:                SendMessage(GetParent(hwnd), WM_MDISETMENU,
        !          2219:                            (WPARAM)  hViewMenu,
        !          2220:                            (LPARAM)  NULL) ;
        !          2221:                DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          2222:            }
1.1       root     2223: 
1.1.1.3 ! root     2224:             bReleaseInfoData(hwnd);
        !          2225:            return 0L;
        !          2226:         }
        !          2227:         case WM_QUERYNEWPALETTE:
        !          2228:         case WM_PALETTECHANGED: {
        !          2229:             PINFO       pInfo;
1.1       root     2230: 
1.1.1.3 ! root     2231:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2232:                 return 0L;
        !          2233:             }
1.1       root     2234: 
1.1.1.3 ! root     2235:            SendMessage(pInfo->hwnd, message, wParam, lParam);
        !          2236:             bReleaseInfoData(hwnd);
        !          2237:            return 0L;
        !          2238:         }
1.1       root     2239: 
1.1.1.3 ! root     2240:        case WM_SIZE: {
        !          2241:             PINFO       pInfo;
        !          2242:             HWND        hTextWnd, hView;
        !          2243:             WORD        wCx;
        !          2244:             int         iCyText;
1.1       root     2245: 
1.1.1.3 ! root     2246:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2247:                 break;
        !          2248:             }
        !          2249: 
        !          2250:             hTextWnd = pInfo->hTextWnd;
        !          2251:             hView    = pInfo->hwnd;
        !          2252:             bReleaseInfoData(hwnd);
        !          2253:             iCyText = GetWindowLong(hTextWnd, GWL_USERDATA);
        !          2254:             wCx = (WORD) (HIWORD(lParam) - iCyText);
        !          2255: 
        !          2256:             MoveWindow(hView, 0, 0,
        !          2257:                           LOWORD(lParam),
        !          2258:                            wCx,
        !          2259:                           TRUE);
        !          2260: 
        !          2261:            MoveWindow(hTextWnd,
        !          2262:                       0,
        !          2263:                       wCx,
        !          2264:                       LOWORD(lParam),
        !          2265:                        iCyText,
        !          2266:                       TRUE);
        !          2267: 
        !          2268:            break;
        !          2269:         }
        !          2270: 
        !          2271:         //
        !          2272:         // display info in the status window
        !          2273:         //
        !          2274:         case WM_USER+0xa: {
        !          2275:             PINFO       pInfo;
        !          2276:             static ULONG ulClick = 0;
        !          2277:             HWND        hTextWnd;
        !          2278: 
        !          2279:             ulClick++;
        !          2280:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2281:                 return 0L;
        !          2282:             }
        !          2283: 
        !          2284:             hTextWnd = pInfo->hTextWnd;
        !          2285:             switch (ulClick % 4) {
        !          2286:                 case 0: sprintf( gtext,"%d Frames", pInfo->RleData.ulFrames);
        !          2287:                         break;
        !          2288:                 case 1: sprintf( gtext,"%d Files", pInfo->RleData.ulFiles);
        !          2289:                         break;
        !          2290:                 case 2: sprintf( gtext,
        !          2291:                         (pInfo->bPlayRleCont ? "Continuous Play"
        !          2292:                                              : "Single Play"));
        !          2293:                         break;
        !          2294:                 case 3: sprintf( gtext,"");
        !          2295:                         break;
        !          2296:                 default: break;
        !          2297:             }
        !          2298:             SetWindowText(hTextWnd, gtext);
        !          2299:             bReleaseInfoData(hwnd);
        !          2300:             return 0L;
        !          2301:         }
        !          2302: 
        !          2303:         case WM_SYSCOMMAND: {
        !          2304:             LONG        lResult;
        !          2305: 
        !          2306:             EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnSuspendThrd, lParam);
        !          2307: 
        !          2308:             lResult = DefMDIChildProc(hwnd, message, wParam, lParam);
        !          2309: 
        !          2310:             EnumChildWindows(ghwndClient, (WNDENUMPROC)lpfnResumeThrd, lParam);
        !          2311: 
        !          2312:             return lResult;
1.1       root     2313:             break;
1.1.1.3 ! root     2314:         }
1.1       root     2315: 
1.1.1.3 ! root     2316:        case WM_CREATE: {
        !          2317:             PINFO           pInfo;
        !          2318:             HANDLE          hInfo;
        !          2319:             HWND            hTextWnd, hView;
        !          2320:            RECT            rcl;
1.1       root     2321: 
1.1.1.3 ! root     2322:             //
        !          2323:             // CR! MakeProcInstance is noop!
        !          2324:             //
        !          2325:             lpfnSuspendThrd = (FARPROC)MakeProcInstance (SuspendDrawThrd, ghModule);
        !          2326:             lpfnResumeThrd  = (FARPROC)MakeProcInstance (ResumeDrawThrd, ghModule);
1.1       root     2327: 
1.1.1.3 ! root     2328:             hTextWnd = CreateWindow("Text", NULL,
        !          2329:                                     WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
        !          2330:                                     0, 0, 0, 0,
        !          2331:                                     hwnd,
        !          2332:                                     (HMENU) 2,
        !          2333:                                     ghModule,
        !          2334:                                     NULL);
1.1       root     2335: 
1.1.1.3 ! root     2336:             GetClientRect(hwnd, &rcl);
        !          2337:             hView = CreateWindow("View", (LPSTR) NULL,
        !          2338:                           WS_CHILD      | WS_VISIBLE     |
        !          2339:                           WS_BORDER,
        !          2340:                           0,0, rcl.right-rcl.left,
        !          2341:                           rcl.bottom-rcl.top-GetWindowLong(hTextWnd, GWL_USERDATA),
        !          2342:                           hwnd, (HMENU)1, ghModule, (LPVOID)NULL);
        !          2343: 
        !          2344:             SetWindowText(hTextWnd, "Select the 'Draw Set' menu item to start drawing.");
        !          2345:             hInfo = (HANDLE) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam ;
        !          2346:             if (hInfo) {
        !          2347:                 if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
        !          2348:                     MessageBox(ghwndMain, "Failed in LocalLock, hNode", "Error", MB_OK);
        !          2349:                     break;
        !          2350:                 } else {
        !          2351:                     HDC hDC;
        !          2352: 
        !          2353:                     if (!GetClientRect(hwnd, &pInfo->rcClient))
        !          2354:                         MessageBox(ghwndMain, "Failed in GetClientRect!", "Error", MB_OK);
        !          2355: 
        !          2356:                     pInfo->hTextWnd = hTextWnd;
        !          2357:                     pInfo->hwnd = hView;
        !          2358: 
        !          2359:                     hDC = GetDC(hView);
        !          2360:                     pInfo->hHTPal = CreateHalftonePalette(hDC);
        !          2361:                     ReleaseDC(hView, hDC);
        !          2362: 
        !          2363:                     //
        !          2364:                     // Creating a signal quit play continuous event
        !          2365:                     //
        !          2366:                     if ((pInfo->hQuitEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
        !          2367:                         MessageBox(ghwndMain, "Failed in creating Quit Event!", "Error", MB_OK);
        !          2368: 
        !          2369:                     SetWindowLong(hwnd, 0, (LONG) hInfo);
        !          2370:                     LocalUnlock(hInfo);
        !          2371:                 }
        !          2372:            } else {
        !          2373:                MessageBox(ghwndMain, "Can't allocate hInfo!", "Error", MB_OK);
        !          2374:            }
        !          2375: 
        !          2376:             break;
        !          2377:        }
        !          2378: 
        !          2379:         case WM_CLOSE: {
        !          2380:            SendMessage(GetParent(hwnd), WM_MDISETMENU,
        !          2381:                            (DWORD) hMenu,
        !          2382:                            (LONG)  hSubMenuOne) ;
        !          2383:            DrawMenuBar(GetParent(GetParent(hwnd))) ;
        !          2384:             break;
        !          2385:         }
        !          2386: 
        !          2387:         case WM_DESTROY: {
        !          2388:             PINFO            pInfo;
        !          2389:             if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          2390:                 break;
        !          2391:             }
        !          2392: 
        !          2393:             TerminateThread(pInfo->hThrd, (DWORD)0L);
        !          2394:             CloseHandle(pInfo->hThrd);
        !          2395: 
        !          2396:             //
        !          2397:             // Cleanup continuous play
        !          2398:             //
        !          2399:             if (!ResetEvent(pInfo->hQuitEvent))
        !          2400:                 MessageBox(ghwndMain, "Failed in reseting quit event!", "Error", MB_OK);
        !          2401: 
        !          2402:             bFreeRleFile(pInfo);
        !          2403:             bReleaseInfoData(hwnd);
        !          2404:             LocalFree((HANDLE) GetWindowLong(hwnd, 0));
        !          2405:             break;
        !          2406:        }
        !          2407: 
        !          2408:        default:
        !          2409:            return DefMDIChildProc(hwnd, message, wParam, lParam);
        !          2410: 
        !          2411:     } //switch
        !          2412:     return DefMDIChildProc(hwnd, message, wParam, lParam);
        !          2413: }
        !          2414: 
        !          2415: /******************************Public*Routine******************************\
        !          2416: *
        !          2417: * ViewSurfWndProc
        !          2418: *
        !          2419: * Effects:
        !          2420: *
        !          2421: * Warnings:
        !          2422: *
        !          2423: * History:
        !          2424: *  13-Dec-1992 -by- Petrus Wong
        !          2425: * Wrote it.
        !          2426: \**************************************************************************/
        !          2427: 
        !          2428: LONG APIENTRY ViewSurfWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
        !          2429: {
        !          2430:     switch (message)
        !          2431:     {
        !          2432:        case WM_CREATE: {
        !          2433:            break;
        !          2434:        }
        !          2435: 
        !          2436:        case WM_DESTROY: {
        !          2437:             break;
        !          2438:        }
        !          2439: 
        !          2440:        case WM_QUERYNEWPALETTE: {
        !          2441:              HWND        hParent;
        !          2442:              PINFO       pInfo;
        !          2443:              HDC         hDC;
        !          2444:              UINT        i;
        !          2445:              HPALETTE    hOldPal;
        !          2446: 
        !          2447:              if ((hParent=GetParent(hwnd)) == NULL) {
        !          2448:                  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2449:                  return 0L;
        !          2450:              }
        !          2451:              if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2452:                   return 0L;
        !          2453:              }
        !          2454: 
        !          2455:              // If palette realization causes a palette change,
        !          2456:              // we need to do a full redraw.
        !          2457: 
        !          2458:              hDC = GetDC (hwnd);
        !          2459: 
        !          2460:              hOldPal = SelectPalette (hDC,
        !          2461:                        pInfo->RleData.hPal,
        !          2462:                        0);
        !          2463: 
        !          2464:              i = RealizePalette(hDC);
        !          2465: 
        !          2466:              SelectPalette (hDC, hOldPal, 0);
        !          2467:              ReleaseDC (hwnd, hDC);
        !          2468:              bReleaseInfoData(hParent);
        !          2469: 
        !          2470:              if (i) {
        !          2471:                  InvalidateRect (hwnd, (LPRECT) (NULL), TRUE);
        !          2472:                  return TRUE;
        !          2473:              } else
        !          2474:                  return FALSE;
        !          2475: 
        !          2476:        }
        !          2477:        case WM_PALETTECHANGED: {
        !          2478:              HWND        hParent;
        !          2479:              PINFO       pInfo;
        !          2480:              HDC         hDC;
        !          2481:              UINT        i;
        !          2482:              HPALETTE    hOldPal;
        !          2483: 
        !          2484:              if ((hParent=GetParent(hwnd)) == NULL) {
        !          2485:                  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2486:                  return 0L;
        !          2487:              }
        !          2488:              if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2489:                   return 0L;
        !          2490:              }
        !          2491: 
        !          2492:              // if we were not responsible for palette change and if
        !          2493:              // palette realization causes a palette change, do a redraw.
        !          2494: 
        !          2495:              if ((HWND)wParam != hwnd){
        !          2496:                 hDC = GetDC (hwnd);
        !          2497: 
        !          2498:                 hOldPal = SelectPalette (hDC,
        !          2499:                         pInfo->RleData.hPal,
        !          2500:                         0);
        !          2501: 
        !          2502:                 i = RealizePalette (hDC);
        !          2503: 
        !          2504:                 if (i){
        !          2505:                     UpdateColors (hDC);
        !          2506:                 }
        !          2507:                 SelectPalette (hDC, hOldPal, 0);
        !          2508:                 ReleaseDC (hwnd, hDC);
1.1       root     2509:             }
1.1.1.3 ! root     2510:             bReleaseInfoData(hParent);
        !          2511:             break;
        !          2512:        }
        !          2513: 
        !          2514:        case WM_PAINT:
        !          2515:          {
        !          2516:              PAINTSTRUCT ps;
        !          2517:              HDC         hDC;
        !          2518:              RECT        rc;
        !          2519: 
        !          2520:              GetClientRect(hwnd,&rc);
        !          2521:              hDC = BeginPaint(hwnd, &ps);
        !          2522:              EndPaint(hwnd, &ps);
        !          2523:              return 0L;
        !          2524:          }
        !          2525: 
        !          2526:     } // switch
        !          2527:     return DefWindowProc(hwnd, message, wParam, lParam);
        !          2528: }
        !          2529: 
        !          2530: /***************************************************************************\
        !          2531: * About
        !          2532: *
        !          2533: * About dialog proc.
        !          2534: *
        !          2535: * History:
        !          2536: * 04-13-91 ????         Created.
        !          2537: * 09-09-91 Petrus Wong Rewrote.
        !          2538: \***************************************************************************/
        !          2539: 
        !          2540: BOOL CALLBACK About(
        !          2541:     HWND hDlg,
        !          2542:     UINT message,
        !          2543:     DWORD wParam,
        !          2544:     LONG lParam)
        !          2545: {
        !          2546:     switch (message) {
        !          2547:     case WM_INITDIALOG:
        !          2548:         return TRUE;
        !          2549: 
        !          2550:     case WM_COMMAND:
        !          2551:         if (wParam == IDOK)
        !          2552:             EndDialog(hDlg, wParam);
        !          2553:         break;
        !          2554:     }
        !          2555: 
        !          2556:     return FALSE;
        !          2557: 
        !          2558:     UNREFERENCED_PARAMETER(lParam);
        !          2559:     UNREFERENCED_PARAMETER(hDlg);
        !          2560: }
        !          2561: 
        !          2562: /*************************************************************************
        !          2563: *
        !          2564: * TextWndProc
        !          2565: *
        !          2566: * Text Window proc.
        !          2567: *
        !          2568: * History:
        !          2569: * 10-07-91  Petrus Wong        Created.
        !          2570: *
        !          2571: \***************************************************************************/
        !          2572: 
        !          2573: LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
        !          2574: {
        !          2575:     static HFONT hFont = (HFONT) NULL;
        !          2576: 
        !          2577:     switch (message)
        !          2578:     {
        !          2579:     case WM_CREATE:
        !          2580:         {
        !          2581:            LOGFONT    lf;
        !          2582:            HDC        hDC;
        !          2583:            HFONT      hOldFont;
        !          2584:             TEXTMETRIC tm;
        !          2585:            RECT       rect;
        !          2586:            LONG       lHeight;
        !          2587: 
        !          2588:             SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, FALSE);
        !          2589: 
        !          2590:            hDC = GetDC(hwnd);
        !          2591:            // this is the height for 8 point size font in pixels
        !          2592:            lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
        !          2593: 
        !          2594:            hFont = CreateFontIndirect(&lf);
        !          2595:            hOldFont = SelectObject(hDC, hFont);
        !          2596:            GetTextMetrics(hDC, &tm);
        !          2597:            GetClientRect(GetParent(hwnd), &rect);
        !          2598: 
        !          2599:            // base the height of the window on size of text
        !          2600:            lHeight = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
        !          2601:            // saved the height for later reference
        !          2602:            SetWindowLong(hwnd, GWL_USERDATA, lHeight);
        !          2603:            SetWindowPos(hwnd, NULL,
        !          2604:                    0,
        !          2605:                    rect.bottom-lHeight,
        !          2606:                    rect.right-rect.left,
        !          2607:                    lHeight,
        !          2608:                    SWP_NOZORDER | SWP_NOMOVE);
        !          2609: 
        !          2610:             ReleaseDC(hwnd, hDC);
        !          2611:             break;
        !          2612:         }
        !          2613: 
        !          2614:     case WM_LBUTTONDOWN: {
        !          2615:         PostMessage(GetParent(hwnd), WM_USER+0xa, (DWORD)0L, (LONG)0L);
        !          2616:         break;
        !          2617:     }
        !          2618: 
        !          2619:     case WM_DESTROY:
        !          2620:            if (hFont)
        !          2621:                DeleteObject(hFont);
        !          2622:            break;
        !          2623: 
        !          2624:     case WM_SETTEXT:
        !          2625:             DefWindowProc(hwnd, message, wParam, lParam);
        !          2626:             InvalidateRect(hwnd,NULL,TRUE);
        !          2627:             UpdateWindow(hwnd);
        !          2628:             return 0L;
        !          2629: 
        !          2630:     case WM_PAINT:
        !          2631:         {
        !          2632:             PAINTSTRUCT ps;
        !          2633:             RECT   rc;
        !          2634:             char   ach[128];
        !          2635:             int    len, nxBorder, nyBorder;
        !          2636:             HFONT  hOldFont = NULL;
        !          2637: 
        !          2638:             BeginPaint(hwnd, &ps);
        !          2639: 
        !          2640:             GetClientRect(hwnd,&rc);
        !          2641: 
        !          2642:             nxBorder = GetSystemMetrics(SM_CXBORDER);
        !          2643:            rc.left  += 9*nxBorder;
        !          2644:             rc.right -= 9*nxBorder;
        !          2645: 
        !          2646:             nyBorder = GetSystemMetrics(SM_CYBORDER);
        !          2647:            rc.top    += 3*nyBorder;
        !          2648:            rc.bottom -= 3*nyBorder;
        !          2649: 
        !          2650:            // 3D Text
        !          2651:             len = GetWindowText(hwnd, ach, sizeof(ach));
        !          2652:            SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
        !          2653: 
        !          2654:            SetBkMode(ps.hdc, TRANSPARENT);
        !          2655:            SetTextColor(ps.hdc, RGB(64,96,96));
        !          2656:            if (hFont)
        !          2657:                hOldFont = SelectObject(ps.hdc, hFont);
        !          2658:            ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
        !          2659:                        &rc, ach, len, NULL);
        !          2660: 
        !          2661:            SetTextColor(ps.hdc, RGB(128,128,128));
        !          2662:            if (hFont)
        !          2663:                hOldFont = SelectObject(ps.hdc, hFont);
        !          2664:            ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
        !          2665:                        &rc, ach, len, NULL);
        !          2666: 
        !          2667:            SetTextColor(ps.hdc, RGB(255,255,255));
        !          2668:            if (hFont)
        !          2669:                hOldFont = SelectObject(ps.hdc, hFont);
        !          2670:            ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
        !          2671:                        &rc, ach, len, NULL);
        !          2672: 
        !          2673:            SetBkMode(ps.hdc, OPAQUE);
        !          2674: 
        !          2675:            if (hOldFont)
        !          2676:                SelectObject(ps.hdc, hOldFont);
        !          2677: 
        !          2678:             EndPaint(hwnd, &ps);
        !          2679:             return 0L;
        !          2680:         }
        !          2681:     }
        !          2682:     return DefWindowProc(hwnd, message, wParam, lParam);
        !          2683: }
        !          2684: 
        !          2685: 
        !          2686: /**************************************************************************\
        !          2687: *
        !          2688: * JuliaWndProc
        !          2689: *
        !          2690: * History:
        !          2691: *  14-Jun-1992 -by- Petrus Wong     removed pens except red & black
        !          2692: *  22-Nov-1991 -by- Petrus Wong
        !          2693: * Wrote it.
        !          2694: \**************************************************************************/
        !          2695: 
        !          2696: LONG APIENTRY JuliaWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
        !          2697: {
        !          2698:     //
        !          2699:     // These statics are shared by all the Julia windows.  But, this is
        !          2700:     // fine because only one Julia window is tracking at any one time.
        !          2701:     // Ideally, we should place this in the per-window INFO data structure.
        !          2702:     // But, this is not necessary.
        !          2703:     //
        !          2704:     static BOOL    bTrack = FALSE;
        !          2705:     static int     OrgX, OrgY;
        !          2706:     static int     PrevX, PrevY;
        !          2707:     static HDC     hDC;
        !          2708:     static HCURSOR hCurArrow, hCurPaintCan;
        !          2709: 
        !          2710:     switch (message)
        !          2711:     {
        !          2712:        case WM_CREATE: {
        !          2713: 
        !          2714:             hpnRed     = CreatePen(PS_SOLID, 0, RGB(0xFF, 0,    0));
        !          2715:             hpnGreen   = CreatePen(PS_SOLID, 0, RGB(0,    0xFF, 0));
        !          2716:             hpnBlack   = CreatePen(PS_SOLID, 0, RGB(0,    0,    0));
        !          2717: 
        !          2718:             hCurPaintCan = LoadCursor(ghModule, MAKEINTRESOURCE(PAINTCURSOR));
        !          2719:             hCurArrow = LoadCursor(NULL, IDC_ARROW);
        !          2720:            break;
        !          2721:        }
        !          2722: 
        !          2723:        case WM_DESTROY: {
        !          2724:             HWND        hParent;
        !          2725:             PINFO       pInfo;
        !          2726: 
        !          2727:             DeleteObject(hpnRed);
        !          2728:             DeleteObject(hpnGreen);
        !          2729:             DeleteObject(hpnBlack);
        !          2730: 
        !          2731:             if ((hParent=GetParent(hwnd)) == NULL) {
        !          2732:                 MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2733:                 break;
        !          2734:             }
        !          2735:             if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2736:                 break;
        !          2737:             }
        !          2738: 
        !          2739:             // we might have open resource if we ever load bitmap in this wnd.
        !          2740:             bFreeRleFile(pInfo);
        !          2741:             bReleaseInfoData(hParent);
        !          2742:             break;
        !          2743:        }
        !          2744: 
        !          2745:        case WM_QUERYNEWPALETTE: {
        !          2746:              HWND        hParent;
        !          2747:              PINFO       pInfo;
        !          2748:              HDC         hDC;
        !          2749:              UINT        i;
        !          2750:              HPALETTE    hOldPal;
        !          2751: 
        !          2752:              if ((hParent=GetParent(hwnd)) == NULL) {
        !          2753:                  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2754:                  return 0L;
        !          2755:              }
        !          2756:              if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2757:                   return 0L;
        !          2758:              }
        !          2759: 
        !          2760:              // If palette realization causes a palette change,
        !          2761:              // we need to do a full redraw.
        !          2762: 
        !          2763:              hDC = GetDC (hwnd);
        !          2764: 
        !          2765:              hOldPal = SelectPalette (hDC,
        !          2766:                        ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
        !          2767:                        0);
        !          2768: 
        !          2769:              i = RealizePalette(hDC);
        !          2770:              SelectPalette (hDC, hOldPal, 0);
        !          2771:              ReleaseDC (hwnd, hDC);
        !          2772:              bReleaseInfoData(hParent);
        !          2773: 
        !          2774:              if (i) {
        !          2775:                  InvalidateRect (hwnd, (LPRECT) (NULL), TRUE);
        !          2776:                  return TRUE;
        !          2777:              } else
        !          2778:                  return FALSE;
        !          2779: 
        !          2780:        }
        !          2781:        case WM_PALETTECHANGED: {
        !          2782:              HWND        hParent;
        !          2783:              PINFO       pInfo;
        !          2784:              HDC         hDC;
        !          2785:              UINT        i;
        !          2786:              HPALETTE    hOldPal;
        !          2787: 
        !          2788:              if ((hParent=GetParent(hwnd)) == NULL) {
        !          2789:                  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2790:                  return 0L;
        !          2791:              }
        !          2792:              if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2793:                   return 0L;
        !          2794:              }
        !          2795: 
        !          2796:              // if we were not responsible for palette change and if
        !          2797:              // palette realization causes a palette change, do a redraw.
        !          2798: 
        !          2799:              if ((HWND)wParam != hwnd){
        !          2800:                 hDC = GetDC (hwnd);
        !          2801: 
        !          2802:                 hOldPal = SelectPalette (hDC,
        !          2803:                        ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
        !          2804:                         0);
        !          2805: 
        !          2806:                 i = RealizePalette (hDC);
        !          2807: 
        !          2808:                 if (i){
        !          2809:                     UpdateColors (hDC);
        !          2810:                 }
        !          2811:                 SelectPalette (hDC, hOldPal, 0);
        !          2812:                 ReleaseDC (hwnd, hDC);
        !          2813:             }
        !          2814:             bReleaseInfoData(hParent);
        !          2815:             break;
        !          2816:        }
        !          2817: 
        !          2818:        case WM_PAINT:
        !          2819:          {
        !          2820:              PAINTSTRUCT ps;
        !          2821:              HWND        hParent;
        !          2822:              PINFO       pInfo;
        !          2823:              HDC         hDC;
        !          2824:              RECT        rc;
        !          2825: 
        !          2826:              GetClientRect(hwnd,&rc);
        !          2827:              hDC = BeginPaint(hwnd, &ps);
        !          2828:              EndPaint(hwnd, &ps);
        !          2829:              if ((hParent=GetParent(hwnd)) == NULL) {
        !          2830:                  MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2831:                  return 0L;
        !          2832:              }
        !          2833:              if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2834:                   return 0L;
        !          2835:                 }
        !          2836: 
        !          2837:              if (pInfo->hBmpSaved) {
        !          2838:                 hDC = GetDC(hwnd);
        !          2839:                 bDrawDIB(hDC, pInfo, 0, 0, rc.right, rc.bottom);
        !          2840:                 ReleaseDC(hwnd, hDC);
        !          2841:              }
        !          2842:              bReleaseInfoData(hParent);
        !          2843: 
        !          2844:              //EndPaint(hwnd, &ps);
        !          2845:              return 0L;
        !          2846:          }
        !          2847: 
        !          2848:        case WM_RBUTTONDOWN: {
        !          2849:          RECT   rc;
        !          2850:         HANDLE hParent;
        !          2851:         PINFO  pInfo;
        !          2852:          int    x, y;
        !          2853:          HWND   hJulia;
        !          2854:          HANDLE hTextWnd;
        !          2855: 
        !          2856:          x = (int) LOWORD(lParam);
        !          2857:          y = (int) HIWORD(lParam);
        !          2858:          if ((hParent=GetParent(hwnd)) == NULL) {
        !          2859:              MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2860:              break;
        !          2861:          }
        !          2862: 
        !          2863:          if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2864:              break;
        !          2865:          }
        !          2866: 
        !          2867:          hTextWnd = pInfo->hTextWnd;
        !          2868: 
        !          2869:          if (GetWindowLong(GetParent(hwnd), GWL_STYLE) & WS_MAXIMIZE) {
        !          2870:              GetClientRect(ghwndMain, &rc);
        !          2871:              rc.bottom -= GetWindowLong(hTextWnd,GWL_USERDATA);
        !          2872:          } else {
        !          2873:              GetClientRect(hwnd, &rc);
        !          2874:          }
        !          2875: 
        !          2876:          if (pInfo->bMandel) {
        !          2877: 
        !          2878:              hJulia = (HWND) SendMessage(ghwndMain, WM_COMMAND,
        !          2879:                                          (DWORD)((WORD)MM_JULIA), 0L);
        !          2880:              if (hJulia) {
        !          2881:                  //GetClientRect(hwnd, &rc);
        !          2882:                  //
        !          2883:                  // calculate the c value corresponding to the point
        !          2884:                  //
        !          2885:                  c1 = Xform((double) x, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          2886:                  c2 = Xform((double) y, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          2887:                  lc1 = XformFix(x, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          2888:                  lc2 = XformFix(y, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          2889: 
        !          2890:                 sprintf( gtext,"(c1 = %g, c2 = %g)\n", c1, c2);
        !          2891:                 OutputDebugString( gtext );
        !          2892: 
        !          2893:                  //
        !          2894:                  // Reset globals to default values for creating Julia set
        !          2895:                  // (Entire set, not zoom in)
        !          2896:                  //
        !          2897:                  bResetGlobal();
        !          2898:                  PostMessage(hJulia, WM_COMMAND, (DWORD)((WORD) MM_SET_XFORM_ATTR), 0L);
        !          2899:              } else {
        !          2900:                  MessageBox(ghwndMain, "Can't create hJulia!", "Error", MB_OK);
        !          2901:              }
        !          2902:          }
        !          2903:          bReleaseInfoData(hParent);
        !          2904:          break;
        !          2905:        }
        !          2906:        case WM_LBUTTONDOWN: {
        !          2907:         HANDLE hParent;
        !          2908:         PINFO  pInfo;
        !          2909:          int    x, y;
        !          2910:          DWORD  dwRGB;
        !          2911:          HBRUSH hBrOld;
        !          2912: 
        !          2913:          x = (int) LOWORD(lParam);
        !          2914:          y = (int) HIWORD(lParam);
        !          2915:          if ((hParent=GetParent(hwnd)) == NULL) {
        !          2916:              MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2917:              break;
        !          2918:          }
        !          2919: 
        !          2920:          if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2921:              break;
        !          2922:          }
        !          2923: 
        !          2924:          if (pInfo->bFill) {
        !          2925:             hDC = GetDC(hwnd);
        !          2926:             hBrOld = SelectObject(hDC, pInfo->hBrush);
        !          2927: 
        !          2928:             dwRGB = GetPixel(hDC, x, y);
        !          2929: 
        !          2930:             ExtFloodFill(hDC, x, y, (COLORREF)dwRGB, FLOODFILLSURFACE);
        !          2931:             SelectObject(hDC, hBrOld);
        !          2932:             ReleaseDC(hwnd, hDC);
        !          2933:             pInfo->bFill = FALSE;
        !          2934: 
        !          2935:             if (pInfo->hBmpSaved)
        !          2936:                 DeleteObject(pInfo->hBmpSaved);
        !          2937: 
        !          2938:             pInfo->hBmpSaved = SaveBitmap(hwnd, pInfo->hPal);
        !          2939:             pInfo->bUseDIB = FALSE;
        !          2940: 
        !          2941: 
        !          2942:             SetCursor(hCurArrow);
        !          2943:          } else {
        !          2944:             bTrack = TRUE;
        !          2945:             OrgX = PrevX = x = LOWORD(lParam);
        !          2946:             OrgY = PrevY = y = HIWORD(lParam);
        !          2947: 
        !          2948:             hDC = GetDC(hwnd);
        !          2949:             SetCapture(hwnd);
        !          2950:          }
        !          2951:          bReleaseInfoData(hParent);
        !          2952:          break;
        !          2953:        }
        !          2954:        case WM_MOUSEMOVE: {
        !          2955:          RECT rectClient;
        !          2956:          int NextX;
        !          2957:          int NextY;
        !          2958:         HANDLE hParent;
        !          2959:         PINFO  pInfo;
        !          2960: 
        !          2961:          if ((hParent=GetParent(hwnd)) == NULL) {
        !          2962:              MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          2963:              break;
        !          2964:          }
        !          2965: 
        !          2966:          if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          2967:              break;
        !          2968:          }
        !          2969: 
        !          2970:          if (pInfo->bFill) {
        !          2971:                  SetCursor(hCurPaintCan);
        !          2972:          } else {
        !          2973:                  SetCursor(hCurArrow);
        !          2974:          }
        !          2975: 
        !          2976:          bReleaseInfoData(hParent);
        !          2977: 
        !          2978:          // Update the selection region
        !          2979:          if (bTrack) {
        !          2980:              NextX = (SHORT) LOWORD(lParam);
        !          2981:              NextY = (SHORT) HIWORD(lParam);
        !          2982: 
        !          2983:              // Do not draw outside the window's client area
        !          2984: 
        !          2985:              GetClientRect (hwnd, &rectClient);
        !          2986:              if (NextX < rectClient.left) {
        !          2987:                  NextX = rectClient.left;
        !          2988:              } else if (NextX >= rectClient.right) {
        !          2989:                  NextX = rectClient.right - 1;
        !          2990:              }
        !          2991:              if (NextY < rectClient.top) {
        !          2992:                  NextY = rectClient.top;
        !          2993:              } else if (NextY >= rectClient.bottom) {
        !          2994:                  NextY = rectClient.bottom - 1;
        !          2995:              }
        !          2996:              if ((NextX != PrevX) || (NextY != PrevY)) {
        !          2997:                 SetROP2(hDC, R2_NOT);           // Erases the previous box
        !          2998: 
        !          2999:                 MoveToEx(hDC, OrgX, OrgY, NULL);
        !          3000:                 LineTo(hDC, OrgX, PrevY);
        !          3001:                 LineTo(hDC, PrevX, PrevY);
        !          3002:                 LineTo(hDC, PrevX, OrgY);
        !          3003:                 LineTo(hDC, OrgX, OrgY);
        !          3004:              // Get the current mouse position
        !          3005: 
        !          3006:                 PrevX = NextX;
        !          3007:                 PrevY = NextY;
        !          3008:                 MoveToEx(hDC, OrgX, OrgY, NULL);   // Draws the new box
        !          3009:                 LineTo(hDC, OrgX, PrevY);
        !          3010:                 LineTo(hDC, PrevX, PrevY);
        !          3011:                 LineTo(hDC, PrevX, OrgY);
        !          3012:                 LineTo(hDC, OrgX, OrgY);
        !          3013:              }
        !          3014:          }
        !          3015:          break;
        !          3016: 
        !          3017:        }
        !          3018: 
        !          3019:        case WM_LBUTTONUP: {
        !          3020:         RECT rc;
        !          3021:         HANDLE hParent;
        !          3022:         PINFO  pInfo;
        !          3023:          int NextX;
        !          3024:          int NextY;
        !          3025:          int iDistX, iDistY, iAbsDstX, iAbsDstY;
        !          3026:          HWND hZoom;
        !          3027:          HANDLE hTextWnd;
        !          3028: 
        !          3029:          if (!bTrack)
        !          3030:             break;
        !          3031: 
        !          3032:          // End the selection
        !          3033:             ReleaseCapture();
        !          3034:             bTrack = FALSE;
        !          3035: 
        !          3036:             MoveToEx(hDC, OrgX, OrgY, NULL);   // Erases the box
        !          3037:             LineTo(hDC, OrgX, PrevY);
        !          3038:             LineTo(hDC, PrevX, PrevY);
        !          3039:             LineTo(hDC, PrevX, OrgY);
        !          3040:             LineTo(hDC, OrgX, OrgY);
        !          3041: 
        !          3042:             NextX = LOWORD(lParam);
        !          3043:             NextY = HIWORD(lParam);
        !          3044: 
        !          3045:             iDistX = NextX - OrgX;
        !          3046:             iDistY = NextY - OrgY;
        !          3047:             iAbsDstX = (iDistX > 0 ? iDistX : -iDistX);
        !          3048:             iAbsDstY = (iDistY > 0 ? iDistY : -iDistY);
        !          3049:             if (iAbsDstX > iAbsDstY) {
        !          3050:                 NextY = OrgY + (iDistY > 0 ? iAbsDstX : -iAbsDstX);
        !          3051:             } else if (iAbsDstX < iAbsDstY) {
        !          3052:                         NextX = OrgX + (iDistX > 0 ? iAbsDstY : -iAbsDstY);
        !          3053:             }
        !          3054: 
        !          3055:             MoveToEx(hDC, OrgX, OrgY, NULL);   // Draws the new box
        !          3056:             LineTo(hDC, OrgX, NextY);
        !          3057:             LineTo(hDC, NextX, NextY);
        !          3058:             LineTo(hDC, NextX, OrgY);
        !          3059:             LineTo(hDC, OrgX, OrgY);
        !          3060: 
        !          3061:             SetROP2(hDC, R2_COPYPEN);
        !          3062: 
        !          3063:             ReleaseDC(hwnd, hDC);
        !          3064:             if ((hParent=GetParent(hwnd)) == NULL) {
        !          3065:                 MessageBox(ghwndMain, "Can't get hParent!", "Error", MB_OK);
        !          3066:                 break;
        !          3067:             }
        !          3068: 
        !          3069:             if ((pInfo = pGetInfoData(hParent)) == NULL) {
        !          3070:                 break;
        !          3071:             }
        !          3072: 
        !          3073:             hTextWnd = pInfo->hTextWnd;
        !          3074:             sprintf(gtext, "Mouse (%d, %d), (%d, %d)\n", OrgX, OrgY, NextX, NextY);
        !          3075:             //SetWindowText(hTextWnd, gtext);
        !          3076:             OutputDebugString(gtext);
        !          3077: 
        !          3078: 
        !          3079:             if (GetWindowLong(GetParent(hwnd), GWL_STYLE) & WS_MAXIMIZE) {
        !          3080: 
        !          3081:                 GetClientRect(ghwndMain, &rc);
        !          3082:                 rc.bottom -= GetWindowLong(hTextWnd,GWL_USERDATA);
        !          3083:                 sprintf(gtext, "(%d, %d), (%d, %d)\n", rc.left, rc.top, rc.right, rc.bottom);
        !          3084:                 //SetWindowText(hTextWnd, gtext);
        !          3085:                 OutputDebugString(gtext);
        !          3086: 
        !          3087:             } else {
        !          3088:                 GetClientRect(hwnd, &rc);
        !          3089:             }
        !          3090: 
        !          3091:             if ((OrgX == NextX) && (OrgY == NextY)) {
        !          3092:                 bReleaseInfoData(hParent);
        !          3093:                 break;
        !          3094:             }
        !          3095: 
        !          3096:             hZoom = (HWND) SendMessage(ghwndMain, WM_COMMAND,
        !          3097:                        pInfo->bMandel ? (DWORD)((WORD)MM_MANDEL) : (DWORD)((WORD)MM_JULIA),
        !          3098:                        0L);
        !          3099:             if (hZoom) {
        !          3100:                 //GetClientRect(hwnd, &rc);
        !          3101:                 xFrom = Xform((double) OrgX, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          3102:                 xTo   = Xform((double) NextX, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          3103:                 yFrom = Xform((double) OrgY, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          3104:                 yTo   = Xform((double) NextY, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          3105:                 lxFrom = XformFix(OrgX, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          3106:                 lxTo   = XformFix(NextX, 0, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          3107:                 lyFrom = XformFix(OrgY, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          3108:                 lyTo   = XformFix(NextY, 0, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          3109:                 if (!pInfo->bMandel) {
        !          3110:                     c1 = pInfo->c1;
        !          3111:                     c2 = pInfo->c2;
        !          3112:                     lc1 = pInfo->lc1;
        !          3113:                     lc2 = pInfo->lc2;
        !          3114:                 }
        !          3115:                 PostMessage(hZoom, WM_COMMAND, (DWORD)((WORD) MM_SET_XFORM_ATTR), 0L);
        !          3116:             } else {
        !          3117:                 MessageBox(ghwndMain, "Can't create hZoom!", "Error", MB_OK);
        !          3118:             }
        !          3119:          bReleaseInfoData(hParent);
        !          3120:          break;
        !          3121:        } // case WM_LBUTTONUP
        !          3122:     } // switch
        !          3123:     return DefWindowProc(hwnd, message, wParam, lParam);
        !          3124: }
        !          3125: 
        !          3126: 
        !          3127: /******************************Public*Routine******************************\
        !          3128: *
        !          3129: * SuspendDrawThrd
        !          3130: *
        !          3131: * Effects: Enumerates all the MDI children.  Suspending the drawing thread
        !          3132: *          in those windows, if any.
        !          3133: *
        !          3134: * Warnings: assumes the MDI children has class name "ChildClass."
        !          3135: *
        !          3136: * History:
        !          3137: *  09-Dec-1991 -by- Petrus Wong
        !          3138: * Wrote it.
        !          3139: \**************************************************************************/
        !          3140: 
        !          3141: 
        !          3142: BOOL APIENTRY SuspendDrawThrd (HWND hwnd, LONG lParam) {
        !          3143:    HANDLE      hThrd;
        !          3144:    PINFO       pInfo;
        !          3145:    DWORD       dwSuspend;
        !          3146:    BOOL        bDrawing;
        !          3147:    char        sz[30];
        !          3148: 
        !          3149:    GetClassName(hwnd, sz, 15);
        !          3150:    if (strcmp(sz, "ChildClass") != 0)
        !          3151:         return 1L;
        !          3152:        if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          3153:            return 1L;
        !          3154:        }
        !          3155: 
        !          3156:        bDrawing = pInfo->bDrawing;
        !          3157:        hThrd    = pInfo->hThrd;
        !          3158:        bReleaseInfoData(hwnd);
        !          3159: 
        !          3160:        if (hThrd && bDrawing) {
        !          3161:            dwSuspend = SuspendThread(hThrd);
        !          3162:            sprintf( gtext,"\nSuspend: dwSuspend = %d, dwSuspend = %g\n", dwSuspend, dwSuspend);
        !          3163:            OutputDebugString( gtext );
        !          3164: 
        !          3165:            if (dwSuspend == -1) {
        !          3166:                sprintf( gtext,"Error in suspending thread\n");
        !          3167:                OutputDebugString( gtext );
        !          3168:            }
        !          3169:        }
        !          3170:    return 1L;
        !          3171:    UNREFERENCED_PARAMETER(lParam);
        !          3172: }
        !          3173: 
        !          3174: 
        !          3175: /******************************Public*Routine******************************\
        !          3176: *
        !          3177: * ResumeDrawThrd
        !          3178: *
        !          3179: * Effects: Enumerates all the MDI children.  Resuming the drawing thread
        !          3180: *          in those windows, if any.
        !          3181: *
        !          3182: * Warnings: Assumes the MDI children has class name "ChildClass." Also,
        !          3183: *           assumes the drawing has been suspended by SuspendDrawThrd.
        !          3184: *
        !          3185: * History:
        !          3186: *  09-Dec-1991 -by- Petrus Wong
        !          3187: * Wrote it.
        !          3188: \**************************************************************************/
        !          3189: 
        !          3190: 
        !          3191: BOOL APIENTRY ResumeDrawThrd  (HWND hwnd, LONG lParam) {
        !          3192:    HANDLE      hThrd;
        !          3193:    PINFO       pInfo;
        !          3194:    DWORD       dwSuspend;
        !          3195:    BOOL        bDrawing;
        !          3196:    char        sz[30];
        !          3197: 
        !          3198:    GetClassName(hwnd, sz, 15);
        !          3199:    if (strcmp(sz, "ChildClass") != 0)
        !          3200:         return 1L;
        !          3201:       if ((pInfo = pGetInfoData(hwnd)) == NULL) {
        !          3202:           return 1L;
        !          3203:       }
        !          3204: 
        !          3205:       bDrawing = pInfo->bDrawing;
        !          3206:       hThrd    = pInfo->hThrd;
        !          3207:       bReleaseInfoData(hwnd);
        !          3208: 
        !          3209:       if (hThrd && bDrawing) {
        !          3210:           dwSuspend = ResumeThread(hThrd);
        !          3211:           sprintf( gtext,"Resume: dwSuspend = %d, dwSuspend = %g\n", dwSuspend, dwSuspend);
        !          3212:           OutputDebugString( gtext );
        !          3213: 
        !          3214:           if (dwSuspend == -1) {
        !          3215:               sprintf( gtext,"Error in resuming thread\n");
        !          3216:               OutputDebugString( gtext );
        !          3217:           }
        !          3218:       }
        !          3219:    return 1L;
        !          3220:    UNREFERENCED_PARAMETER(lParam);
        !          3221: }
        !          3222: 
        !          3223: 
        !          3224: /******************************Public*Routine******************************\
        !          3225: *
        !          3226: * lMul
        !          3227: *
        !          3228: * Effects: Fix point multiplication
        !          3229: *
        !          3230: * Warnings: 9.23 fix point representation used. This is only good for
        !          3231: *           multiplication in a limited range.  Will overflow.
        !          3232: *           CR! Will be implemented as macros in the future
        !          3233: *
        !          3234: * History:
        !          3235: *  16-Feb-1993      Petrus Wong     9.23 fix i LARGE_INTEGER support
        !          3236: *  20-Nov-1991 -by- Petrus Wong
        !          3237: * Wrote it.
        !          3238: \**************************************************************************/
        !          3239: 
        !          3240: LONG lMul(LONG l1, LONG l2)
        !          3241: {
        !          3242:     LARGE_INTEGER   liTmp;
        !          3243: 
        !          3244:     liTmp = EnlargedIntegerMultiply(l1, l2);
        !          3245:     liTmp = LargeIntegerShiftRight(liTmp, 23);
        !          3246:     return(liTmp.LowPart);
        !          3247: }
        !          3248: 
        !          3249: /******************************Public*Routine******************************\
        !          3250: *
        !          3251: * lDiv
        !          3252: *
        !          3253: * Effects: fix point division
        !          3254: *
        !          3255: * Warnings: 9.23 fix point representation used. This is only good for
        !          3256: *           division in a limited range.  Will overflow.
        !          3257: *           CR! Will be implemented as macros in the future
        !          3258: *
        !          3259: * History:
        !          3260: *  16-Feb-1993      Petrus Wong     9.23 fix i LARGE_INTEGER support
        !          3261: *  20-Nov-1991 -by- Petrus Wong
        !          3262: * Wrote it.
        !          3263: \**************************************************************************/
        !          3264: 
        !          3265: LONG lDiv(long l1, long l2)
        !          3266: {
        !          3267:     LARGE_INTEGER   liTmp, liTmp2;
        !          3268: 
        !          3269: 
        !          3270:     liTmp  = ConvertLongToLargeInteger(l1);
        !          3271:     liTmp2 = ConvertLongToLargeInteger(l2);
        !          3272:     liTmp  = LargeIntegerShiftLeft(liTmp, 23);
        !          3273:     liTmp  = LargeIntegerDivide(liTmp, liTmp2, NULL);
        !          3274:     return (liTmp.LowPart);
        !          3275: }
        !          3276: 
        !          3277: 
        !          3278: /**************************************************************************\
        !          3279: *
        !          3280: * StartDrawFix
        !          3281: *                                           2
        !          3282: * Effects: Draw'g the Julia Set for Q (z) = z  + c, where z, c are complex
        !          3283: *                                   c
        !          3284: *         Fact:   |Q (0)| = |c| > 2, the orbit of 0 escapes immediately
        !          3285: *                   c
        !          3286: *         claim:  |z| >= |c| = 2 + l, l > 0 escapes under Q
        !          3287: *                                                          c
        !          3288: *         The Julia Set: Basin Boundaries algorithm.
        !          3289: *
        !          3290: * Warnings:
        !          3291: *
        !          3292: * History:
        !          3293: *  16-Feb-1993      Petrus Wong     9.23 fix
        !          3294: *  11-Feb-1993      Petrus Wong     Minimize device access
        !          3295: *  14-Dec-1992 -by- Petrus Wong     Enable shadow bitmap
        !          3296: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array
        !          3297: *  20-Nov-1991 -by- Petrus Wong
        !          3298: * Wrote it.
        !          3299: \**************************************************************************/
        !          3300: BOOL StartDrawFix(PINFO pInfo)
        !          3301: {
        !          3302:    DWORD       dwTick1;
        !          3303:    HDC         hDC;
        !          3304:    RECT        rc;
        !          3305: 
        !          3306:    int m, n, i, iPrev;
        !          3307:    int xCurr, yCurr;
        !          3308:    int iPen;
        !          3309: 
        !          3310:    LONG c1, c2;
        !          3311:    LONG x0, y0, x1, y1, x, y, z;
        !          3312: 
        !          3313:    int  iBand=1;
        !          3314:    int  iScan=0;
        !          3315:    int  iDiff=0;
        !          3316: 
        !          3317: #ifndef THRDONE
        !          3318:    INT      iNumClr;
        !          3319: #endif
        !          3320: 
        !          3321:    HDC          hDCMem;
        !          3322:    HBITMAP      hBitmap, hOldBitmap;
        !          3323: 
        !          3324:    iPen = pInfo->iPen + 1;
        !          3325:    iPrev = FIRST_PIXEL;           // a big value to signal the first pixel
        !          3326:    //iPrev = pInfo->iIteration + FIRST_PIXEL;
        !          3327:    c1 = pInfo->lc1;
        !          3328:    c2 = pInfo->lc2;
        !          3329: 
        !          3330:    pInfo->bMandel = FALSE;
        !          3331:    pInfo->bDrawing = TRUE;
        !          3332:    hDC = GetDC(pInfo->hwnd);
        !          3333: 
        !          3334: #ifndef THRDONE
        !          3335:     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) {
        !          3336:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
        !          3337:         OutputDebugString( gtext);
        !          3338: 
        !          3339:         if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !          3340:             MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
        !          3341:         } else {
        !          3342:             if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &(pInfo->hPal))) == 0)
        !          3343:                 MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
        !          3344:         }
        !          3345:     }
        !          3346: 
        !          3347:    hDCMem = CreateCompatibleDC(hDC);
        !          3348: 
        !          3349:    SelectPalette(hDCMem, pInfo->hPal, FALSE);
        !          3350:    SelectPalette(hDC,    pInfo->hPal, FALSE);
        !          3351:    RealizePalette(hDC);
        !          3352:    iPen = pInfo->iPen + 1;
        !          3353: #endif
        !          3354: 
        !          3355:    GetClientRect(pInfo->hwnd, &rc);
        !          3356:    hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom);
        !          3357:    hOldBitmap = SelectObject(hDCMem, hBitmap);
        !          3358:    yCurr = rc.top;
        !          3359: 
        !          3360:    dwTick1 = GetTickCount();
        !          3361:    iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan);
        !          3362: 
        !          3363:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          3364:        xCurr = rc.left;                      // since LineTo excludes last point
        !          3365:        MoveToEx(hDCMem, 0, yCurr, NULL);
        !          3366:        y0 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          3367: 
        !          3368:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          3369:           x0 = XformFix(m, rc.left, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          3370:            x = x0;
        !          3371:            y = y0;
        !          3372: 
        !          3373:            for (i=1; i<=pInfo->iIteration; i++) {
        !          3374:                x1 = lMul(x - y, x + y) + c1;    // Z = x1 + i x2
        !          3375: 
        !          3376:               y1 = (lMul(x, y) * 2) + c2;
        !          3377:                x = x1;
        !          3378:               y = y1;                          //    2       2     2 1/2     2
        !          3379:               z = lMul(x, x) + lMul(y, y);     // |Z|  = ((x1  + x2 )   ) > 2
        !          3380: 
        !          3381:               if (z > 33554432)
        !          3382:                    break;
        !          3383:            }
        !          3384: 
        !          3385:           if (i != iPrev)
        !          3386:           {
        !          3387:              if (iPrev != FIRST_PIXEL)
        !          3388:              {
        !          3389:                switch(iPrev)
        !          3390:                {
        !          3391:                    case 1:
        !          3392:                            SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          3393:                            break;
        !          3394:                    default:
        !          3395: 
        !          3396:                        if (iPrev >= pInfo->iIteration) {
        !          3397:                           SelectObject(hDCMem, hpnBlack);
        !          3398:                           break;
        !          3399:                        }
        !          3400:                        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
        !          3401:                        break;
        !          3402:                }
        !          3403:                iPrev = i;
        !          3404:                 LineTo(hDCMem,xCurr,yCurr);
        !          3405:              }
        !          3406:              else
        !          3407:                 iPrev = i;     // remember the color for the first pixel
        !          3408:           }
        !          3409:        }
        !          3410:        switch(i) {
        !          3411:           case 1:
        !          3412:                   SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          3413:                   break;
        !          3414:           default:
        !          3415:               if (iPrev >= pInfo->iIteration) {
        !          3416:                  SelectObject(hDCMem, hpnBlack);
        !          3417:                  break;
        !          3418:               }
        !          3419:               SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]);
        !          3420:               break;
        !          3421:        }
        !          3422: 
        !          3423:        LineTo(hDCMem,xCurr,yCurr);
        !          3424: 
        !          3425:        sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100);
        !          3426:        SetWindowText(pInfo->hTextWnd, gtext);
        !          3427: 
        !          3428:        if (n >= iScan * iBand) {
        !          3429:             BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          3430:             iBand++;
        !          3431:        }
        !          3432:    }
        !          3433: 
        !          3434:    if ((iDiff = iScan * iBand - rc.bottom) != 0) {
        !          3435:         BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          3436:    }
        !          3437: 
        !          3438:    sprintf(gtext, "Drawing: DONE");
        !          3439:    SetWindowText(pInfo->hTextWnd, gtext);
        !          3440: 
        !          3441:    ReleaseDC(pInfo->hwnd, hDC);
        !          3442: 
        !          3443:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !          3444: 
        !          3445:    if (pInfo->hBmpSaved)
        !          3446:        DeleteObject(pInfo->hBmpSaved);
        !          3447: 
        !          3448:    pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap);
        !          3449:    pInfo->bDrawing = FALSE;
        !          3450: #ifndef THRDONE
        !          3451:    if (pInfo->prghPen != NULL) {
        !          3452:        for (i = 0; i <= pInfo->iPen; i++) {
        !          3453:            DeleteObject((HPEN) (pInfo->prghPen)[i]);
        !          3454:        }
        !          3455:        GlobalFree(pInfo->prghPen);
        !          3456:    }
        !          3457: #endif
        !          3458:    DeleteDC(hDCMem);
        !          3459:    ExitThread(0);
        !          3460:    return TRUE;
        !          3461: }
        !          3462: 
        !          3463: /**************************************************************************\
        !          3464: *
        !          3465: * StartDraw
        !          3466: *                                           2
        !          3467: * Effects: Draw'g the Julia Set for Q (z) = z  + c, where z, c are complex
        !          3468: *                                   c
        !          3469: *         Fact:   |Q (0)| = |c| > 2, the orbit of 0 escapes immediately
        !          3470: *                   c
        !          3471: *         claim:  |z| >= |c| = 2 + l, l > 0 escapes under Q
        !          3472: *                                                          c
        !          3473: *         The Julia Set: Basin Boundaries algorithm.
        !          3474: *
        !          3475: * Warnings:
        !          3476: *
        !          3477: * History:
        !          3478: *  11-Feb-1993      Petrus Wong     Minimize device access
        !          3479: *  14-Dec-1992 -by- Petrus Wong     Enable shadow bitmap
        !          3480: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array and LineTo
        !          3481: *  20-Nov-1991 -by- Petrus Wong
        !          3482: * Wrote it.
        !          3483: \**************************************************************************/
        !          3484: BOOL StartDraw(PINFO pInfo)
        !          3485: {
        !          3486:    DWORD       dwTick1;
        !          3487:    HDC         hDC;
        !          3488:    RECT        rc;
        !          3489: 
        !          3490:    int m, n, i, iPrev;
        !          3491:    int xCurr, yCurr;
        !          3492:    int iPen;
        !          3493: 
        !          3494:    double c1, c2;
        !          3495:    double x0, y0, x1, y1, x, y, z;
        !          3496: 
        !          3497:    int  iBand=1;
        !          3498:    int  iScan=0;
        !          3499:    int  iDiff=0;
        !          3500: 
        !          3501: 
        !          3502:    HDC          hDCMem;
        !          3503:    HBITMAP      hBitmap, hOldBitmap;
        !          3504: 
        !          3505: #ifndef THRDONE
        !          3506:    INT      iNumClr;
        !          3507: #endif
        !          3508: 
        !          3509:    iPen = pInfo->iPen + 1;
        !          3510:    iPrev = FIRST_PIXEL;           // a big value to signal the first pixel
        !          3511:    //iPrev = pInfo->iIteration + FIRST_PIXEL;
        !          3512:    c1 = pInfo->c1;
        !          3513:    c2 = pInfo->c2;
        !          3514: 
        !          3515:    pInfo->bMandel = FALSE;
        !          3516:    pInfo->bDrawing = TRUE;
        !          3517:    hDC = GetDC(pInfo->hwnd);
        !          3518: 
        !          3519: #ifndef THRDONE
        !          3520:     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) {
        !          3521:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
        !          3522:         OutputDebugString( gtext);
        !          3523: 
        !          3524:         if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !          3525:             MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
        !          3526:         } else {
        !          3527:             if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &(pInfo->hPal))) == 0)
        !          3528:                 MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
        !          3529:         }
        !          3530:     }
        !          3531: 
        !          3532:    hDCMem = CreateCompatibleDC(hDC);
        !          3533: 
        !          3534:    SelectPalette(hDCMem, pInfo->hPal, FALSE);
        !          3535:    SelectPalette(hDC,    pInfo->hPal, FALSE);
        !          3536:    RealizePalette(hDC);
        !          3537:    iPen = pInfo->iPen + 1;
        !          3538: #endif
        !          3539: 
        !          3540:    GetClientRect(pInfo->hwnd, &rc);
        !          3541:    hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom);
        !          3542:    hOldBitmap = SelectObject(hDCMem, hBitmap);
        !          3543:    yCurr = rc.top;
        !          3544: 
        !          3545:    dwTick1 = GetTickCount();
        !          3546: 
        !          3547:    iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan);
        !          3548: 
        !          3549:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          3550:        xCurr = rc.left;                      // since LineTo excludes last point
        !          3551:        MoveToEx(hDCMem, 0, yCurr, NULL);
        !          3552:        y0 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          3553: 
        !          3554:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          3555:            x0 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          3556:            x = x0;
        !          3557:            y = y0;
        !          3558: 
        !          3559:            for (i=1; i<=pInfo->iIteration; i++) {
        !          3560:                x1 = (x - y) * (x + y) + c1;     // Z = x1 + i x2
        !          3561: 
        !          3562:                y1 = 2 * x * y + c2;
        !          3563:                x = x1;
        !          3564:               y = y1;                          //    2       2     2 1/2     2
        !          3565:               z = x * x + y * y;               // |Z|  = ((x1  + x2 )   ) > 2
        !          3566: 
        !          3567:               if (z > 4.0)
        !          3568:                    break;
        !          3569:            }
        !          3570: 
        !          3571:           if (i != iPrev)
        !          3572:           {
        !          3573:              if (iPrev != FIRST_PIXEL)
        !          3574:              {
        !          3575:                switch(iPrev)
        !          3576:                {
        !          3577:                    case 1:
        !          3578:                            SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          3579:                            break;
        !          3580:                    default:
        !          3581: 
        !          3582:                        if (iPrev >= pInfo->iIteration) {
        !          3583:                           SelectObject(hDCMem, hpnBlack);
        !          3584:                           break;
        !          3585:                        }
        !          3586:                        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
        !          3587:                        break;
        !          3588:                }
        !          3589:                iPrev = i;
        !          3590:                 LineTo(hDCMem,xCurr,yCurr);
        !          3591:              }
        !          3592:              else
        !          3593:                 iPrev = i;     // remember the color for the first pixel
        !          3594:           }
        !          3595:        }
        !          3596:        switch(i) {
        !          3597:           case 1:
        !          3598:                   SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          3599:                   break;
        !          3600:           default:
        !          3601:               if (iPrev >= pInfo->iIteration) {
        !          3602:                  SelectObject(hDCMem, hpnBlack);
        !          3603:                  break;
        !          3604:               }
        !          3605:               SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]);
        !          3606:               break;
        !          3607:        }
        !          3608: 
        !          3609:        LineTo(hDCMem,xCurr,yCurr);
        !          3610: 
        !          3611:        sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100);
        !          3612:        SetWindowText(pInfo->hTextWnd, gtext);
        !          3613: 
        !          3614:        if (n >= iScan * iBand) {
        !          3615:             BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          3616:             iBand++;
        !          3617:        }
        !          3618:    }
        !          3619: 
        !          3620:    if ((iDiff = iScan * iBand - rc.bottom) != 0) {
        !          3621:         BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          3622:    }
        !          3623: 
        !          3624:    sprintf(gtext, "Drawing: DONE");
        !          3625:    SetWindowText(pInfo->hTextWnd, gtext);
        !          3626: 
        !          3627:    ReleaseDC(pInfo->hwnd, hDC);
        !          3628: 
        !          3629:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !          3630: 
        !          3631:    if (pInfo->hBmpSaved)
        !          3632:        DeleteObject(pInfo->hBmpSaved);
        !          3633: 
        !          3634:    pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap);
        !          3635:    pInfo->bDrawing = FALSE;
        !          3636: #ifndef THRDONE
        !          3637:    if (pInfo->prghPen != NULL) {
        !          3638:        for (i = 0; i <= pInfo->iPen; i++) {
        !          3639:            DeleteObject((HPEN) (pInfo->prghPen)[i]);
        !          3640:        }
        !          3641:        GlobalFree(pInfo->prghPen);
        !          3642:    }
        !          3643: #endif
        !          3644:    DeleteDC(hDCMem);
        !          3645: 
        !          3646:    ExitThread(0);
        !          3647:    return TRUE;
        !          3648: }
        !          3649: 
        !          3650: /**************************************************************************\
        !          3651: *
        !          3652: * StartDraw2
        !          3653: *                                           2
        !          3654: * Effects: Draw'g the Julia Set for Q (z) = z  + c, where z, c are complex
        !          3655: *
        !          3656: *         The Julia Set: Backward iteration algorithm.
        !          3657: *
        !          3658: * Warnings:
        !          3659: *
        !          3660: * History:
        !          3661: *  20-Nov-1991 -by- Petrus Wong
        !          3662: * Wrote it.
        !          3663: \**************************************************************************/
        !          3664: 
        !          3665: BOOL StartDraw2(PINFO pInfo)
        !          3666: {
        !          3667:    HDC         hDC;
        !          3668:    RECT        rc;
        !          3669:    int        m, n, i;
        !          3670:    double      c1, c2;
        !          3671:    double      x0, y0, w0, w1, pi, theta, r;
        !          3672: 
        !          3673:    pi = 22.0/7.0;
        !          3674:    c1 = 0.360284;
        !          3675:    c2 = 0.100376;
        !          3676:    x0 = 1.5;
        !          3677:    y0 = 1.5;
        !          3678: 
        !          3679:    hDC = GetDC(pInfo->hwnd);
        !          3680: 
        !          3681:    GetClientRect(pInfo->hwnd, &rc);
        !          3682:    for (i=0; i<=15000; i++) {
        !          3683:     w0 = x0 - c1;
        !          3684:     w1 = y0 - c2;
        !          3685:     sprintf( gtext,"w(%g, %g) xy(%g, %g)\n", w0, w1, x0, y0);
        !          3686:     OutputDebugString( gtext );
        !          3687: 
        !          3688:     if (w0 == 0.0) {
        !          3689:        theta = pi/2;
        !          3690:         sprintf( gtext,"(w0 == 0.0) theta = %g\n\n", theta);
        !          3691:         OutputDebugString( gtext );
        !          3692: 
        !          3693:     } else {
        !          3694:        if (w0 > 0.0) {
        !          3695:            theta = atan(w1/w0);
        !          3696:             sprintf( gtext,"(w0 > 0.0) theta = %g\n\n", theta);
        !          3697:             OutputDebugString( gtext );
        !          3698: 
        !          3699:        } else { // w0 < 0.0
        !          3700:            theta = pi + atan(w1/w0);
        !          3701:             sprintf( gtext,"(w0 < 0.0) theta = %g\n\n", theta);
        !          3702:             OutputDebugString( gtext );
        !          3703:        }
        !          3704:     }
        !          3705:     r = sqrt(w0 * w0 + w1 + w1);
        !          3706:     //theta = theta/2.0 + ((int) ((2.0*rand()/(RAND_MAX+1.0)))*pi);
        !          3707:     //theta = theta/2.0 + ((2.0*rand()/((double)RAND_MAX+1.0))*pi);
        !          3708:     r = sqrt(r);
        !          3709:     x0 = r*cos(theta);
        !          3710:     y0 = r*sin(theta);
        !          3711:     if (i > 50) {
        !          3712:        m = Xform2(x0, pInfo->xFrom, pInfo->xTo, 0.0, (double) rc.right);
        !          3713:        n = Xform2(y0, pInfo->yFrom, pInfo->yTo, 0.0, (double) rc.bottom);
        !          3714:        SetPixel(hDC, m, n, 0x000000ff);
        !          3715:     }
        !          3716:    }
        !          3717: 
        !          3718:    ReleaseDC(pInfo->hwnd, hDC);
        !          3719: 
        !          3720:    ExitThread(0);
        !          3721:    return TRUE;
        !          3722: }
        !          3723: 
        !          3724: /**************************************************************************\
        !          3725: *
        !          3726: * StartMandelbrotFix
        !          3727: *                                           2
        !          3728: * Effects: Draw'g the Mandelbrot Set for Q (z) = z  + c, where z, c complex
        !          3729: *
        !          3730: * Warnings:
        !          3731: *
        !          3732: * History:
        !          3733: *  16-Feb-1993      Petrus Wong     9.23 fix
        !          3734: *  11-Feb-1993      Petrus Wong     Minimize device access
        !          3735: *  14-Dec-1992 -by- Petrus Wong     Enable shadow bitmap
        !          3736: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array
        !          3737: *  20-Nov-1991 -by- Petrus Wong
        !          3738: * Wrote it.
        !          3739: \**************************************************************************/
        !          3740: BOOL StartMandelbrotFix(PINFO pInfo)
        !          3741: {
        !          3742:    DWORD       dwTick1;
        !          3743:    HDC         hDC;
        !          3744:    RECT        rc;
        !          3745:    int        m, n, i, iPrev;
        !          3746:    int         xCurr, yCurr;
        !          3747:    int         iPen;
        !          3748: 
        !          3749:    LONG c1, c2;
        !          3750:    LONG x1, y1, x, y, r;
        !          3751: #ifndef THRDONE
        !          3752:    INT      iNumClr;
        !          3753: #endif
        !          3754: 
        !          3755:    HDC          hDCMem;
        !          3756:    HBITMAP      hBitmap, hOldBitmap;
        !          3757: 
        !          3758:    int  iBand=1;
        !          3759:    int  iScan=0;
        !          3760:    int  iDiff=0;
        !          3761: 
        !          3762:    iPen = pInfo->iPen + 1;
        !          3763:    pInfo->bMandel = TRUE;
        !          3764:    pInfo->bDrawing = TRUE;
        !          3765:    hDC = GetDC(pInfo->hwnd);
        !          3766: 
        !          3767: #ifndef THRDONE
        !          3768:     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) {
        !          3769:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
        !          3770:         OutputDebugString( gtext);
        !          3771: 
        !          3772:         if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !          3773:             MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
        !          3774:         } else {
        !          3775:             if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 0, &(pInfo->hPal))) == 0)
        !          3776:                 MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
        !          3777:         }
        !          3778:     }
        !          3779: 
        !          3780:    hDCMem = CreateCompatibleDC(hDC);
        !          3781: 
        !          3782:    SelectPalette(hDCMem, pInfo->hPal, FALSE);
        !          3783:    SelectPalette(hDC,    pInfo->hPal, FALSE);
        !          3784:    RealizePalette(hDC);
        !          3785:    iPen = pInfo->iPen + 1;
        !          3786: #endif
        !          3787: 
        !          3788:    GetClientRect(pInfo->hwnd, &rc);
        !          3789: 
        !          3790:    hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom);
        !          3791:    hOldBitmap = SelectObject(hDCMem, hBitmap);
        !          3792: 
        !          3793:    dwTick1 = GetTickCount();
        !          3794:    yCurr = rc.top;
        !          3795: 
        !          3796:    iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan);
        !          3797: 
        !          3798:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          3799:        xCurr = rc.left;                   // since LineTo excludes last point
        !          3800:        MoveToEx(hDCMem, 0, yCurr, NULL);
        !          3801:        c2 = XformFix(n, rc.top, rc.bottom, pInfo->lyFrom, pInfo->lyTo);
        !          3802: 
        !          3803:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          3804:            c1 = XformFix(m, rc.left, rc.right, pInfo->lxFrom, pInfo->lxTo);
        !          3805:           x = c1;
        !          3806:           y = c2;
        !          3807: 
        !          3808:           for (i=1; i<=pInfo->iIteration; i++) {
        !          3809:                x1 = lMul(x - y, x + y) + c1;
        !          3810:                y1 = (lMul(x, y) * 2) + c2;
        !          3811:               r = lMul(x1, x1) + lMul(y1, y1);
        !          3812:               x = x1;
        !          3813:               y = y1;
        !          3814:               if (r > 33554432) {
        !          3815:                    break;
        !          3816:                }
        !          3817:            }
        !          3818: 
        !          3819:            if (i != iPrev) {
        !          3820:                if (iPrev != FIRST_PIXEL) {
        !          3821:                  switch(iPrev) {
        !          3822:                    case 1:
        !          3823:                            SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]); break;
        !          3824:                    default:
        !          3825:                        if (iPrev >= pInfo->iIteration) {
        !          3826:                             SelectObject(hDCMem, hpnBlack);
        !          3827:                             break;
        !          3828:                        }
        !          3829:                        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
        !          3830:                        break;
        !          3831:                  }
        !          3832:                  iPrev = i;
        !          3833:                  LineTo(hDCMem, xCurr, yCurr);
        !          3834:                }
        !          3835:                else
        !          3836:                  iPrev = i;    // remember the color for the first pixel
        !          3837:            }
        !          3838:        }
        !          3839: 
        !          3840:        switch(i) {
        !          3841:            case 1:
        !          3842:                SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          3843:                break;
        !          3844:            default:
        !          3845:                if (i >= pInfo->iIteration) {
        !          3846:                     SelectObject(hDCMem, hpnBlack);
        !          3847:                     break;
        !          3848:                }
        !          3849:                SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]);
        !          3850:                break;
        !          3851:        }
        !          3852:        LineTo(hDCMem,xCurr,yCurr);
1.1       root     3853: 
1.1.1.3 ! root     3854:        sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100);
        !          3855:        SetWindowText(pInfo->hTextWnd, gtext);
1.1       root     3856: 
1.1.1.3 ! root     3857:        if (n >= iScan * iBand) {
        !          3858:             BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          3859:             iBand++;
        !          3860:        }
1.1       root     3861: 
1.1.1.3 ! root     3862:    }
1.1       root     3863: 
1.1.1.3 ! root     3864:    if ((iDiff = iScan * iBand - rc.bottom) != 0) {
        !          3865:         BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          3866:    }
1.1       root     3867: 
1.1.1.3 ! root     3868:    sprintf(gtext, "Drawing: DONE");
        !          3869:    SetWindowText(pInfo->hTextWnd, gtext);
1.1       root     3870: 
1.1.1.3 ! root     3871:    ReleaseDC(pInfo->hwnd, hDC);
1.1       root     3872: 
1.1.1.3 ! root     3873:    pInfo->dwElapsed = GetTickCount() - dwTick1;
1.1       root     3874: 
1.1.1.3 ! root     3875:    if (pInfo->hBmpSaved)
        !          3876:        DeleteObject(pInfo->hBmpSaved);
1.1       root     3877: 
1.1.1.3 ! root     3878:    pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap);
        !          3879:    pInfo->bDrawing = FALSE;
1.1       root     3880: 
1.1.1.3 ! root     3881: #ifndef THRDONE
        !          3882:    if (pInfo->prghPen != NULL) {
        !          3883:        for (i = 0; i <= pInfo->iPen; i++) {
        !          3884:            DeleteObject((HPEN) (pInfo->prghPen)[i]);
        !          3885:        }
        !          3886:        GlobalFree(pInfo->prghPen);
        !          3887:    }
        !          3888: #endif
1.1       root     3889: 
1.1.1.3 ! root     3890:    DeleteDC(hDCMem);
1.1       root     3891: 
1.1.1.3 ! root     3892:    ExitThread(0);
        !          3893:    return TRUE;
        !          3894: }
1.1       root     3895: 
1.1.1.3 ! root     3896: /**************************************************************************\
1.1       root     3897: *
1.1.1.3 ! root     3898: * StartMandelbrot
        !          3899: *                                           2
        !          3900: * Effects: Draw'g the Mandelbrot Set for Q (z) = z  + c, where z, c complex
1.1       root     3901: *
1.1.1.3 ! root     3902: * Warnings:
1.1       root     3903: *
                   3904: * History:
1.1.1.3 ! root     3905: *  11-Feb-1993      Petrus Wong     Minimize device access
        !          3906: *  14-Dec-1992 -by- Petrus Wong     Enable shadow bitmap
        !          3907: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array and LineTo
        !          3908: *  20-Nov-1991 -by- Petrus Wong
1.1       root     3909: * Wrote it.
                   3910: \**************************************************************************/
1.1.1.3 ! root     3911: BOOL StartMandelbrot(PINFO pInfo)
        !          3912: {
        !          3913:    DWORD       dwTick1;
        !          3914:    HDC         hDC;
        !          3915:    RECT        rc;
        !          3916:    int        m, n, i, iPrev;
        !          3917:    int         xCurr, yCurr;
        !          3918:    int         iPen;
1.1       root     3919: 
1.1.1.3 ! root     3920: #ifndef THRDONE
        !          3921:    INT      iNumClr;
        !          3922:    char     text[256];
        !          3923: #endif
1.1       root     3924: 
1.1.1.3 ! root     3925:    double c1, c2;
        !          3926:    double x1, y1, x, y, r;
1.1       root     3927: 
1.1.1.3 ! root     3928:    HDC          hDCMem;
        !          3929:    HBITMAP      hBitmap, hOldBitmap;
1.1.1.2   root     3930: 
1.1.1.3 ! root     3931:    int  iBand=1;
        !          3932:    int  iScan=0;
        !          3933:    int  iDiff=0;
        !          3934: 
        !          3935:    iPen = pInfo->iPen + 1;
        !          3936:    pInfo->bMandel = TRUE;
        !          3937:    pInfo->bDrawing = TRUE;
        !          3938:    hDC = GetDC(pInfo->hwnd);
        !          3939: 
        !          3940: #ifndef THRDONE
        !          3941:     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) {
        !          3942:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
        !          3943:         OutputDebugString( gtext);
        !          3944: 
        !          3945:         if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !          3946:             MessageBox(ghwndMain, "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
        !          3947:         } else {
        !          3948:             if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 1, &(pInfo->hPal))) == 0)
        !          3949:                 MessageBox(ghwndMain, "Failed in creating pen!", "Error", MB_OK);
        !          3950:         }
        !          3951:     }
        !          3952: 
        !          3953:    hDCMem = CreateCompatibleDC(hDC);
        !          3954: 
        !          3955:    SelectPalette(hDCMem, pInfo->hPal, FALSE);
        !          3956:    SelectPalette(hDC,    pInfo->hPal, FALSE);
        !          3957:    RealizePalette(hDC);
        !          3958:    iPen = pInfo->iPen + 1;
        !          3959:    wsprintf(text, "iPen = %d\n", iPen);
        !          3960:    //MessageBox(ghwndMain, text, "Error", MB_OK);
        !          3961: #endif
        !          3962: 
        !          3963:    GetClientRect(pInfo->hwnd, &rc);
        !          3964: 
        !          3965:    hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom);
        !          3966:    hOldBitmap = SelectObject(hDCMem, hBitmap);
        !          3967: 
        !          3968: #if 0
        !          3969:  {
        !          3970:    int iWidth, i, j;
        !          3971: 
        !          3972:    iWidth = rc.right/iNumClr;
        !          3973: 
        !          3974:    for (i = 0; i < iNumClr; i++) {
        !          3975:        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iNumClr]);
        !          3976:        for (j = 0; j < iWidth; j++) {
        !          3977:             MoveToEx(hDCMem, i*iWidth+j, 0, NULL);
        !          3978:             LineTo(hDCMem, i*iWidth+j, rc.bottom);
1.1       root     3979:        }
                   3980: 
1.1.1.3 ! root     3981:    }
        !          3982:  }
        !          3983: #endif
1.1       root     3984: 
1.1.1.3 ! root     3985:    dwTick1 = GetTickCount();
1.1       root     3986: 
1.1.1.3 ! root     3987:    iScan = (((iScan = BATCH / rc.right) == 0) ? 1 : iScan);
        !          3988: 
        !          3989:    yCurr = rc.top;
        !          3990:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !          3991:        xCurr = rc.left;                   // since LineTo excludes last point
        !          3992:        MoveToEx(hDCMem, 0, yCurr, NULL);
        !          3993:        c2 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !          3994: 
        !          3995:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !          3996:            c1 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !          3997:           x = c1;
        !          3998:           y = c2;
        !          3999: 
        !          4000:           for (i=1; i<=pInfo->iIteration; i++) {
        !          4001:                x1 = (x - y) * (x + y) + c1;
        !          4002:                y1 = 2 * x * y + c2;
        !          4003:               r = x1 * x1 + y1 * y1;
        !          4004:               x = x1;
        !          4005:               y = y1;
        !          4006:               if (r > 4.0) {
        !          4007:                    break;
        !          4008:                }
        !          4009:            }
        !          4010: 
        !          4011:            if (i != iPrev) {
        !          4012:                if (iPrev != FIRST_PIXEL) {
        !          4013:                  switch(iPrev) {
        !          4014:                    case 1:
        !          4015:                            SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          4016:                     break;
        !          4017:                    default:
        !          4018:                        if (iPrev >= pInfo->iIteration) {
        !          4019:                             SelectObject(hDCMem, hpnBlack);
        !          4020:                             break;
        !          4021:                        }
        !          4022:                        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
        !          4023:                        break;
        !          4024:                  }
        !          4025:                  iPrev = i;
        !          4026:                  LineTo(hDCMem, xCurr, yCurr);
        !          4027:                }
        !          4028:                else
        !          4029:                  iPrev = i;    // remember the color for the first pixel
1.1       root     4030:            }
                   4031:        }
                   4032: 
1.1.1.3 ! root     4033:        switch(i) {
        !          4034:               case 1:
        !          4035:                       SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !          4036:                break;
        !          4037:               default:
        !          4038:                   if (i >= pInfo->iIteration) {
        !          4039:                        SelectObject(hDCMem, hpnBlack);
        !          4040:                        break;
        !          4041:                   }
        !          4042:                   SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]);
        !          4043:                   break;
        !          4044:        }
1.1       root     4045: 
1.1.1.3 ! root     4046:        LineTo(hDCMem,xCurr,yCurr);
1.1       root     4047: 
1.1.1.3 ! root     4048:        sprintf(gtext, "Drawing: %3.2f %%", ((FLOAT)n/(FLOAT)rc.bottom)*100);
        !          4049:        SetWindowText(pInfo->hTextWnd, gtext);
1.1       root     4050: 
1.1.1.3 ! root     4051:        if (n >= iScan * iBand) {
        !          4052:             BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          4053:             iBand++;
        !          4054:        }
        !          4055:    }
1.1       root     4056: 
1.1.1.3 ! root     4057:    if ((iDiff = iScan * iBand - rc.bottom) != 0) {
        !          4058:         BitBlt(hDC, 0, iScan * (iBand-1), rc.right, iScan-iDiff, hDCMem, 0, iScan * (iBand-1), SRCCOPY);
        !          4059:    }
1.1.1.2   root     4060: 
1.1.1.3 ! root     4061:    sprintf(gtext, "Drawing: DONE");
        !          4062:    SetWindowText(pInfo->hTextWnd, gtext);
1.1       root     4063: 
1.1.1.3 ! root     4064:    ReleaseDC(pInfo->hwnd, hDC);
1.1       root     4065: 
1.1.1.3 ! root     4066:    pInfo->dwElapsed = GetTickCount() - dwTick1;
1.1       root     4067: 
1.1.1.3 ! root     4068:    if (pInfo->hBmpSaved)
        !          4069:        DeleteObject(pInfo->hBmpSaved);
        !          4070: 
        !          4071:    pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap);
        !          4072:    pInfo->bDrawing = FALSE;
        !          4073: #ifndef THRDONE
        !          4074:    if (pInfo->prghPen != NULL) {
        !          4075:        for (i = 0; i <= pInfo->iPen; i++) {
        !          4076:            DeleteObject((HPEN) (pInfo->prghPen)[i]);
        !          4077:        }
        !          4078:        GlobalFree(pInfo->prghPen);
        !          4079:    }
        !          4080: #endif
        !          4081: 
        !          4082:    DeleteDC(hDCMem);
        !          4083: 
        !          4084:    ExitThread(0);
        !          4085:    return TRUE;
1.1       root     4086: }
                   4087: 
                   4088: 
                   4089: /******************************Public*Routine******************************\
                   4090: *
1.1.1.3 ! root     4091: * Xform
1.1       root     4092: *
1.1.1.3 ! root     4093: * Effects: Given m, find x.
1.1       root     4094: *
1.1.1.3 ! root     4095: *          Xform(Pt) : Src |--> Dest
        !          4096: * eg.
        !          4097: *          Src |----|--------|      |-->   Dest |----|--------|
        !          4098: *              -2   x        2                  0    m       320
        !          4099: *
        !          4100: *          x = (m - 0)/(320 - 0) * (2 - -2) + -2
        !          4101: *
        !          4102: * Warnings: 1. This will become a macro in the future for speed.  For now,
        !          4103: *             it is here for debugging purposes.
1.1       root     4104: *
                   4105: * History:
1.1.1.3 ! root     4106: *  25-Nov-1991 -by- Petrus Wong
1.1       root     4107: * Wrote it.
                   4108: \**************************************************************************/
1.1.1.3 ! root     4109: #if 0
        !          4110: double Xform(
        !          4111:    double Pt,
        !          4112:    double SrcFrom,
        !          4113:    double SrcTo,
        !          4114:    double DestFrom,
        !          4115:    double DestTo)
1.1       root     4116: {
1.1.1.3 ! root     4117:  //sprintf( gtext,"%g = Xform(%g, %g, %g, %g, %g)\n", ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom, Pt, SrcFrom, SrcTo, DestFrom, DestTo);
        !          4118:  //OutputDebugString( gtext );
        !          4119:  return(((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom);
1.1       root     4120: }
1.1.1.3 ! root     4121: #endif
1.1       root     4122: 
                   4123: /******************************Public*Routine******************************\
                   4124: *
1.1.1.3 ! root     4125: * Xform2
1.1       root     4126: *
1.1.1.3 ! root     4127: * Effects: Given x, find m.
1.1       root     4128: *
1.1.1.3 ! root     4129: *          Xform(Pt) : Src |--> Dest
        !          4130: * eg.
        !          4131: *          Src |----|--------|      |-->   Dest |----|--------|
        !          4132: *             -2   x        2                  0    m       320
        !          4133: *
        !          4134: *         m = (x - -2)/(2 - -2) * 320
        !          4135: *
        !          4136: * Warnings: 1. This will become a macro in the future for speed.  For now,
        !          4137: *             it is here for debugging purposes.
1.1       root     4138: *
                   4139: * History:
1.1.1.3 ! root     4140: *  25-Nov-1991 -by- Petrus Wong
1.1       root     4141: * Wrote it.
                   4142: \**************************************************************************/
1.1.1.3 ! root     4143: #if 0
        !          4144: int Xform2(
        !          4145:    double Pt,
        !          4146:    double SrcFrom,
        !          4147:    double SrcTo,
        !          4148:    double DestFrom,
        !          4149:    double DestTo)
1.1       root     4150: {
1.1.1.3 ! root     4151:  //sprintf( gtext,"%g = Xform(%g, %g, %g, %g, %g)\n", ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom))+DestFrom, Pt, SrcFrom, SrcTo, DestFrom, DestTo);
        !          4152:  //OutputDebugString( gtext );
        !          4153:  return((int) ((Pt-SrcFrom)/(SrcTo-SrcFrom)*(DestTo-DestFrom)+DestFrom));
1.1       root     4154: }
1.1.1.3 ! root     4155: #endif
1.1       root     4156: 
1.1.1.3 ! root     4157: /******************************Public*Routine******************************\
1.1       root     4158: *
1.1.1.3 ! root     4159: * SaveBitmap
        !          4160: *
        !          4161: * Effects:  Returns the handle of a bitmap corresponding to the window.
        !          4162: *           using utilizing BitBlt.
1.1       root     4163: *
                   4164: * Warnings:
1.1.1.3 ! root     4165: *   // should we set the dirty flag here?
        !          4166: *
1.1       root     4167: *
                   4168: * History:
1.1.1.3 ! root     4169: *  03-Dec-1991 -by- Petrus Wong
1.1       root     4170: * Wrote it.
                   4171: \**************************************************************************/
                   4172: 
1.1.1.3 ! root     4173: HBITMAP SaveBitmap(HWND hWnd, HPALETTE hPal) {
        !          4174:     HDC     hdcMem, hDC;
        !          4175:     HBITMAP hBitmap, hOldBitmap;
        !          4176:     RECT    rc;
        !          4177:     HPALETTE hPalOld, hPalMemOld;
        !          4178:     int     ii;
1.1       root     4179: 
1.1.1.3 ! root     4180:     hDC = GetDC(hWnd);
        !          4181:     GetClientRect(hWnd, &rc);
1.1       root     4182: 
1.1.1.3 ! root     4183:     if (hPal) {
1.1       root     4184: 
1.1.1.3 ! root     4185:         hPalOld = SelectPalette(hDC, hPal, FALSE);
        !          4186:         ii=RealizePalette(hDC);
        !          4187:         if (ii){
        !          4188:             UpdateColors (hDC);
        !          4189:         }
1.1       root     4190: 
1.1.1.3 ! root     4191:     }
1.1       root     4192: 
1.1.1.3 ! root     4193:     hdcMem = CreateCompatibleDC(hDC);
1.1       root     4194: 
1.1.1.3 ! root     4195:     if (hPal) {
1.1       root     4196: 
1.1.1.3 ! root     4197:         hPalMemOld = SelectPalette(hdcMem, hPal, FALSE);
        !          4198:         RealizePalette(hdcMem);
        !          4199:     }
1.1       root     4200: 
1.1.1.3 ! root     4201:     hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right-rc.left, (int)rc.bottom-rc.top);
1.1       root     4202: 
1.1.1.3 ! root     4203:     hOldBitmap = SelectObject(hdcMem, hBitmap);
1.1       root     4204: 
                   4205: 
1.1.1.3 ! root     4206:     BitBlt(hdcMem, 0, 0, (int)rc.right-rc.left, (int)rc.bottom-rc.top, hDC, 0, 0, SRCCOPY);
        !          4207:     hBitmap = SelectObject(hdcMem, hOldBitmap);
1.1       root     4208: 
1.1.1.3 ! root     4209:     DeleteDC(hdcMem);
        !          4210:     ReleaseDC(hWnd, hDC);
1.1       root     4211: 
1.1.1.3 ! root     4212:     return(hBitmap);
1.1       root     4213: 
                   4214: }
                   4215: 
1.1.1.3 ! root     4216: /******************************Public*Routine******************************\
1.1       root     4217: *
1.1.1.3 ! root     4218: * DrawBitmap
        !          4219: *
        !          4220: * Effects:
1.1       root     4221: *
                   4222: * Warnings:
                   4223: *
                   4224: * History:
1.1.1.3 ! root     4225: *  03-Dec-1991 -by- Petrus Wong
1.1       root     4226: * Wrote it.
                   4227: \**************************************************************************/
                   4228: 
1.1.1.3 ! root     4229: void DrawBitmap(HDC hdc, PINFO pInfo, int xStart, int yStart, int cx, int cy) {
        !          4230:     BITMAP bm;
        !          4231:     HDC    hdcMem;
        !          4232:     POINT  ptSize, ptOrg;
        !          4233:     HPALETTE hPalOld, hPalMemOld;
        !          4234:     char    text[128];
1.1       root     4235: 
1.1.1.3 ! root     4236:     if ((pInfo->hPal) && !(pInfo->bUseMono)) {
1.1       root     4237: 
1.1.1.3 ! root     4238:         hPalOld = SelectPalette(hdc,
        !          4239:              ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
        !          4240:              FALSE);
        !          4241:         //RealizePalette(hdc);
        !          4242:         wsprintf(text, "Realized Palette = %d", RealizePalette(hdc));
        !          4243:         MessageBox(ghwndMain, text, "", MB_OK);
1.1       root     4244: 
1.1.1.3 ! root     4245:         UpdateColors (hdc);
        !          4246:     }
1.1       root     4247: 
1.1.1.3 ! root     4248:     hdcMem = CreateCompatibleDC(hdc);
1.1       root     4249: 
1.1.1.3 ! root     4250:     if ((pInfo->hPal) && !(pInfo->bUseMono)) {
1.1       root     4251: 
1.1.1.3 ! root     4252:         hPalMemOld = SelectPalette(hdcMem,
        !          4253:              ((pInfo->iStretchMode == HALFTONE) ? pInfo->hHTPal : pInfo->hPal),
        !          4254:               FALSE);
        !          4255:         //RealizePalette(hdcMem);
        !          4256:         wsprintf(text, "Realized Palette = %d", RealizePalette(hdcMem));
        !          4257:         MessageBox(ghwndMain, text, "", MB_OK);
1.1       root     4258: 
                   4259: 
1.1.1.3 ! root     4260:         UpdateColors (hdcMem);
1.1       root     4261: 
                   4262: 
                   4263: 
1.1.1.3 ! root     4264:     }
1.1       root     4265: 
1.1.1.3 ! root     4266:     SelectObject(hdcMem, (pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved));
        !          4267:     SetMapMode(hdcMem, GetMapMode(hdc));
1.1       root     4268: 
1.1.1.3 ! root     4269:     GetObject((pInfo->bUseMono ? pInfo->hBmpMono : pInfo->hBmpSaved), sizeof(BITMAP), (LPSTR)&bm);
        !          4270:     ptSize.x = bm.bmWidth;
        !          4271:     ptSize.y = bm.bmHeight;
        !          4272:     DPtoLP(hdc, &ptSize, 1);
1.1       root     4273: 
1.1.1.3 ! root     4274:     ptOrg.x = 0;
        !          4275:     ptOrg.y = 0;
        !          4276:     DPtoLP(hdcMem, &ptOrg, 1);
1.1       root     4277: 
1.1.1.3 ! root     4278:     if (pInfo->bStretch) {
        !          4279:         SetStretchBltMode(hdc, pInfo->iStretchMode);
        !          4280:         // cx+1 and cy+1: temporary work around for a bug!
        !          4281:         StretchBlt(hdc, xStart, yStart, cx+1, cy+1,
        !          4282:                hdcMem, ptOrg.x, ptOrg.y, ptSize.x, ptSize.y,SRCCOPY);
        !          4283:     } else {
        !          4284:         BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y,
        !          4285:                hdcMem, xStart, yStart, SRCCOPY);
        !          4286:     }
1.1       root     4287: 
1.1.1.3 ! root     4288:     if (pInfo->bUseMono)
        !          4289:         pInfo->bUseMono = FALSE;
1.1       root     4290: 
1.1.1.3 ! root     4291:     DeleteDC(hdcMem);
        !          4292:     UNREFERENCED_PARAMETER(cx);
        !          4293:     UNREFERENCED_PARAMETER(cy);
1.1       root     4294: }
                   4295: 
1.1.1.3 ! root     4296: /******************************Public*Routine******************************\
1.1       root     4297: *
1.1.1.3 ! root     4298: * bDrawDIB
1.1       root     4299: *
1.1.1.3 ! root     4300: * Effects:
1.1       root     4301: *
                   4302: * Warnings:
                   4303: *
                   4304: * History:
1.1.1.3 ! root     4305: *  17-Jun-1993      Petrus Wong     updated for latest HT changes
        !          4306: *  06-Feb-1993      Petrus Wong     rewritten for HT support
        !          4307: *  14-Dec-1992 -by- Petrus Wong
1.1       root     4308: * Wrote it.
                   4309: \**************************************************************************/
                   4310: 
1.1.1.3 ! root     4311: BOOL bDrawDIB(HDC hDC, PINFO pInfo, int xStart, int yStart, int cx, int cy)
1.1       root     4312: {
1.1.1.3 ! root     4313:     HBITMAP     hBmpOld, hBmp;
        !          4314:     BOOL        bSuccess;
        !          4315:     PBITMAPINFO pbmi;
        !          4316:     HDC         hdcMem;
        !          4317:     BITMAP      bm;
1.1       root     4318: 
1.1.1.3 ! root     4319:     bSuccess = TRUE;
        !          4320:     if (pInfo->bUseMono) {
        !          4321:         DrawBitmap(hDC, pInfo, xStart, yStart, cx, cy);
        !          4322:         return bSuccess;
        !          4323:     }
1.1       root     4324: 
1.1.1.3 ! root     4325:     if ((hBmp = pInfo->hBmpSaved) == NULL) {
        !          4326:         MessageBox(ghwndMain, "There's no Bitmap to draw!", "Error", MB_OK);
        !          4327:         return FALSE;
        !          4328:     }
1.1       root     4329: 
1.1.1.3 ! root     4330:     if (pInfo->bStretch) {
        !          4331:         SetStretchBltMode(hDC, pInfo->iStretchMode);
1.1       root     4332: 
1.1.1.3 ! root     4333:         if (pInfo->bUseDIB) { // this'll give a src for halftone...
        !          4334:             pbmi = (PBITMAPINFO) (pInfo->RleData.rgpbmi[0]);
1.1       root     4335: 
1.1.1.3 ! root     4336:             // Select and realize the appropriate palette to destination DC
        !          4337:             if ((pInfo->iStretchMode == HALFTONE) && (pInfo->hHTPal)) {
        !          4338:                 SelectPalette(hDC, pInfo->hHTPal, FALSE);
        !          4339:                 RealizePalette(hDC);
        !          4340:             } else {
        !          4341:                 if ((pInfo->iStretchMode != HALFTONE) && (pInfo->hPal)) {
        !          4342:                     SelectPalette(hDC, pInfo->hPal, FALSE);
        !          4343:                     RealizePalette(hDC);
        !          4344:                 }
        !          4345:             }
        !          4346:             if (pInfo->bCoreHdr) {
        !          4347:                 StretchDIBits(hDC, xStart, yStart, cx, cy,
        !          4348:                           0, 0, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcWidth,
        !          4349:                                 ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight,
        !          4350:                           (LPSTR)pInfo->RleData.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY);
        !          4351:             } else {
        !          4352:                 StretchDIBits(hDC, xStart, yStart, cx, cy,
        !          4353:                           0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight,
        !          4354:                           (LPSTR)pInfo->RleData.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY);
        !          4355:             }
        !          4356:         } else { // image is dirty or created on this device
1.1       root     4357: 
1.1.1.3 ! root     4358:             HBITMAP     hDIB;
        !          4359: 
        !          4360:             //
        !          4361:             // Get the source DIB info from the DDB for halftoning
        !          4362:             //
        !          4363:             hDIB = DIBfromDDB(hDC, hBmp, pInfo);
        !          4364: 
        !          4365:             hdcMem = CreateCompatibleDC(hDC);
        !          4366:             hBmpOld = SelectObject(hdcMem, hDIB);
        !          4367: 
        !          4368:             if ((pInfo->iStretchMode == HALFTONE) && (pInfo->hHTPal)) {
        !          4369:                 SelectPalette(hDC, pInfo->hHTPal, FALSE);
        !          4370:                 RealizePalette(hDC);
        !          4371:             } else {
        !          4372:                 if ((pInfo->iStretchMode != HALFTONE) && (pInfo->hPal)) {
        !          4373:                     SelectPalette(hDC, pInfo->hPal, FALSE);
        !          4374:                     RealizePalette(hDC);
        !          4375:                 }
        !          4376:             }
        !          4377: 
        !          4378:             //
        !          4379:             // Use StretchBlt here instead of StretchDIBits just for
        !          4380:             // demonstrating using the API with halftone
        !          4381:             //
        !          4382:             GetObject(hDIB, sizeof(BITMAP), (LPSTR)&bm);
        !          4383:             StretchBlt(hDC, xStart, yStart, cx, cy, hdcMem,
        !          4384:                           0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
        !          4385: 
        !          4386:             DeleteDC(hdcMem);
        !          4387: 
        !          4388:         }
        !          4389:         return bSuccess;
1.1       root     4390:     }
1.1.1.3 ! root     4391: 
        !          4392:     //
        !          4393:     // Not stretching...No halftone
        !          4394:     //
        !          4395: 
        !          4396:     GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bm);
        !          4397: 
        !          4398:     // Select and realize the appropriate palette to destination DC
        !          4399:     if (pInfo->hPal) {
        !          4400:         SelectPalette(hDC, pInfo->hPal, FALSE);
        !          4401:         RealizePalette(hDC);
1.1       root     4402:     }
                   4403: 
1.1.1.3 ! root     4404:     if (pInfo->bUseDIB) { // this'll give a src
        !          4405:         pbmi = (PBITMAPINFO) (pInfo->RleData.rgpbmi[0]);
1.1       root     4406: 
1.1.1.3 ! root     4407:         // default to use SetDIBitsToDevice
        !          4408:         SetDIBitsToDevice(hDC, xStart, yStart, bm.bmWidth, bm.bmHeight,
        !          4409:                       0, 0, 0, bm.bmHeight, pInfo->RleData.rgpjFrame[0],
        !          4410:                       pbmi, DIB_RGB_COLORS);
        !          4411:     } else { // image is dirty or created on this device
1.1       root     4412: 
1.1.1.3 ! root     4413:         hdcMem = CreateCompatibleDC(hDC);
        !          4414:         hBmpOld = SelectObject(hdcMem, hBmp);
        !          4415: 
        !          4416:         BitBlt(hDC, xStart, yStart, bm.bmWidth, bm.bmHeight,
        !          4417:                hdcMem, 0, 0, SRCCOPY);
        !          4418: 
        !          4419:         DeleteDC(hdcMem);
        !          4420:     }
        !          4421: 
        !          4422:     return bSuccess;
1.1       root     4423: }
                   4424: 
1.1.1.3 ! root     4425: /******************************Public*Routine******************************\
1.1       root     4426: *
1.1.1.3 ! root     4427: * pGetInfoData(HWND hwnd)
        !          4428: *
        !          4429: * Effects:  calls LocalLock, returning pointer to Info structure.
        !          4430: *           assumes hwnd contains handle to Info structure at index 0.
        !          4431: *           should call bReleaseInfoData when done.
        !          4432: *           Global alert: ghwndMain used.
1.1       root     4433: *
                   4434: * Warnings:
                   4435: *
                   4436: * History:
1.1.1.3 ! root     4437: *  27-Jan-1992 -by- Petrus Wong
1.1       root     4438: * Wrote it.
                   4439: \**************************************************************************/
                   4440: 
1.1.1.3 ! root     4441: PINFO pGetInfoData(HWND hwnd)
        !          4442: {
        !          4443:     HANDLE hInfo;
        !          4444:     PINFO  pInfo;
1.1       root     4445: 
1.1.1.3 ! root     4446:     hInfo = (HANDLE) GetWindowLong(hwnd, 0);
        !          4447:     if (hInfo == NULL) {
        !          4448:         MessageBox(ghwndMain, "Null Info handle retrieved - GetInfo", "Error", MB_OK);
        !          4449:         return NULL;
        !          4450:     }
1.1       root     4451: 
1.1.1.3 ! root     4452:     if ((pInfo = (PINFO)LocalLock(hInfo)) == NULL) {
        !          4453:         return NULL;
        !          4454:     }
1.1       root     4455: 
1.1.1.3 ! root     4456:     return pInfo;
        !          4457: }
1.1       root     4458: 
1.1.1.3 ! root     4459: /******************************Public*Routine******************************\
        !          4460: *
        !          4461: * bReleaseInfoData(HWND hwnd)
        !          4462: *
        !          4463: * Effects: calls LocalUnlock.  Returns whatever LocalUnlock returns.
        !          4464: *
        !          4465: * Warnings: assumes LocalLock was called previously.
        !          4466: *           assumes hwnd contains handle to Info structure at index 0.
        !          4467: *           Global alert: ghwndMain used.
        !          4468: *
        !          4469: * History:
        !          4470: *  27-Jan-1992 -by- Petrus Wong
        !          4471: * Wrote it.
        !          4472: \**************************************************************************/
1.1       root     4473: 
1.1.1.3 ! root     4474: BOOL bReleaseInfoData(HWND hwnd)
        !          4475: {
        !          4476:     HANDLE hInfo;
1.1       root     4477: 
1.1.1.3 ! root     4478:     hInfo = (HANDLE) GetWindowLong(hwnd, 0);
        !          4479:     if (hInfo == NULL) {
        !          4480:         MessageBox(ghwndMain, "Null Info handle retrieved - ReleaseInfo", "Error", MB_OK);
        !          4481:         return FALSE;
        !          4482:     }
1.1       root     4483: 
1.1.1.3 ! root     4484:     return (LocalUnlock(hInfo));
        !          4485: }
1.1       root     4486: 
                   4487: 
1.1.1.3 ! root     4488: /******************************Public*Routine******************************\
        !          4489: *
        !          4490: * bCheckMutexMenuItem
        !          4491: *
        !          4492: * Effects: Put a check mark on uiCheckItem in the hMenu.  Remove previous
        !          4493: *          check mark, if any, on items in the same group.  Returns TRUE
        !          4494: *          if successful, FALSE otherwise (item not exists).
        !          4495: *
        !          4496: * Warnings:
        !          4497: *
        !          4498: * History:
        !          4499: *  12-Jan-1993      Petrus Wong             rewritten
        !          4500: *  28-Jan-1992 -by- Petrus Wong
        !          4501: * Wrote it.
        !          4502: \**************************************************************************/
1.1       root     4503: 
1.1.1.3 ! root     4504: BOOL bCheckMutexMenuItem(PINFO pInfo, HMENU hMenu, UINT uiCheckItem)
        !          4505: {
1.1       root     4506: 
1.1.1.3 ! root     4507:     switch(uiCheckItem) {
        !          4508:         case MM_TP_IDLE:
        !          4509:         case MM_TP_LOW:
        !          4510:         case MM_TP_BELOW_NORMAL:
        !          4511:         case MM_TP_NORMAL:
        !          4512:         case MM_TP_ABOVE_NORMAL:
        !          4513:         case MM_TP_HIGH:
        !          4514:         case MM_TP_TIME_CRITICAL:
        !          4515:             switch (pInfo->iPriority) {
        !          4516:                 case THREAD_PRIORITY_IDLE:
        !          4517:                     CheckMenuItem(hMenu, MM_TP_IDLE, MF_UNCHECKED);
        !          4518:                     break;
        !          4519:                 case THREAD_PRIORITY_LOWEST:
        !          4520:                     CheckMenuItem(hMenu, MM_TP_LOW, MF_UNCHECKED);
        !          4521:                     break;
        !          4522:                 case THREAD_PRIORITY_BELOW_NORMAL:
        !          4523:                     CheckMenuItem(hMenu, MM_TP_BELOW_NORMAL, MF_UNCHECKED);
        !          4524:                     break;
        !          4525:                 case THREAD_PRIORITY_NORMAL:
        !          4526:                     CheckMenuItem(hMenu, MM_TP_NORMAL, MF_UNCHECKED);
        !          4527:                     break;
        !          4528:                 case THREAD_PRIORITY_ABOVE_NORMAL:
        !          4529:                     CheckMenuItem(hMenu, MM_TP_ABOVE_NORMAL, MF_UNCHECKED);
        !          4530:                     break;
        !          4531:                 case THREAD_PRIORITY_HIGHEST:
        !          4532:                     CheckMenuItem(hMenu, MM_TP_HIGH, MF_UNCHECKED);
        !          4533:                     break;
        !          4534:                 case THREAD_PRIORITY_TIME_CRITICAL:
        !          4535:                     CheckMenuItem(hMenu, MM_TP_TIME_CRITICAL, MF_UNCHECKED);
        !          4536:                     break;
        !          4537:                 default:
        !          4538:                     break;
        !          4539:             }
        !          4540:             break;
        !          4541:         case MM_FLOAT:
        !          4542:         case MM_FIX:
        !          4543:             CheckMenuItem(hMenu, MM_FLOAT, MF_UNCHECKED);
        !          4544:             CheckMenuItem(hMenu, MM_FIX,   MF_UNCHECKED);
        !          4545:             break;
        !          4546:         case MM_ITERATION_100:
        !          4547:         case MM_ITERATION_500:
        !          4548:         case MM_ITERATION_1000:
        !          4549:         case MM_ITERATION_5000:
        !          4550:         case MM_ITERATION_DOUBLE:
        !          4551:             switch (pInfo->iIteration) {
        !          4552:                 case 100:
        !          4553:                     CheckMenuItem(hMenu, MM_ITERATION_100, MF_UNCHECKED);
        !          4554:                     break;
        !          4555:                 case 500:
        !          4556:                     CheckMenuItem(hMenu, MM_ITERATION_500, MF_UNCHECKED);
        !          4557:                     break;
        !          4558:                 case 1000:
        !          4559:                     CheckMenuItem(hMenu, MM_ITERATION_1000, MF_UNCHECKED);
        !          4560:                     break;
        !          4561:                 case 5000:
        !          4562:                     CheckMenuItem(hMenu, MM_ITERATION_5000, MF_UNCHECKED);
        !          4563:                     break;
        !          4564:                 default:
        !          4565:                     CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, MF_UNCHECKED);
        !          4566:                     break;
        !          4567:             }
        !          4568:             break;
        !          4569:         case MM_STEP_ONE:
        !          4570:         case MM_STEP_TWO:
        !          4571:         case MM_STEP_THREE:
        !          4572:             switch (pInfo->iStep) {
        !          4573:                 case 1:
        !          4574:                     CheckMenuItem(hMenu, MM_STEP_ONE, MF_UNCHECKED);
        !          4575:                     break;
        !          4576:                 case 2:
        !          4577:                     CheckMenuItem(hMenu, MM_STEP_TWO, MF_UNCHECKED);
        !          4578:                     break;
        !          4579:                 default:
        !          4580:                     CheckMenuItem(hMenu, MM_STEP_THREE, MF_UNCHECKED);
        !          4581:                     break;
        !          4582:             }
        !          4583:             break;
        !          4584:         case MM_STRETCHBLT:
        !          4585:         case MM_BITBLT:
        !          4586:                 CheckMenuItem(hMenu, MM_STRETCHBLT,   MF_UNCHECKED);
        !          4587:                 CheckMenuItem(hMenu, MM_BITBLT,       MF_UNCHECKED);
        !          4588:             break;
        !          4589:         case MM_BLACKONWHITE:
        !          4590:         case MM_COLORONCOLOR:
        !          4591:         case MM_WHITEONBLACK:
        !          4592:         case MM_HALFTONE:
        !          4593:             switch (pInfo->iStretchMode) {
        !          4594:                 case BLACKONWHITE:
        !          4595:                     CheckMenuItem(hMenu, MM_BLACKONWHITE, MF_UNCHECKED);
        !          4596:                     break;
        !          4597:                 case COLORONCOLOR:
        !          4598:                     CheckMenuItem(hMenu, MM_COLORONCOLOR, MF_UNCHECKED);
        !          4599:                     break;
        !          4600:                 case WHITEONBLACK:
        !          4601:                     CheckMenuItem(hMenu, MM_WHITEONBLACK, MF_UNCHECKED);
        !          4602:                     break;
        !          4603:                 case HALFTONE:
        !          4604:                     CheckMenuItem(hMenu, MM_HALFTONE, MF_UNCHECKED);
        !          4605:                     break;
        !          4606:                 default:
        !          4607:                     break;
        !          4608:             }
        !          4609:             break;
        !          4610:         case MM_PORTRAIT:
        !          4611:         case MM_LANDSCAPE:
        !          4612:                 CheckMenuItem(hMenu, MM_PORTRAIT,   MF_UNCHECKED);
        !          4613:                 CheckMenuItem(hMenu, MM_LANDSCAPE,  MF_UNCHECKED);
        !          4614:             break;
        !          4615:         default:
        !          4616:             return FALSE;
        !          4617:     }
        !          4618:     CheckMenuItem(hMenu, uiCheckItem, MF_CHECKED);
        !          4619:     return TRUE;
1.1       root     4620: }
                   4621: 
1.1.1.3 ! root     4622: 
        !          4623: /******************************Public*Routine******************************\
1.1       root     4624: *
1.1.1.3 ! root     4625: * vChkMenuItem
        !          4626: *
        !          4627: * Effects:  Helper function for checking or unchecking menu items based on
        !          4628: *           values set in the pInfo.  Gets called when processing
        !          4629: *           WM_MDIACTIVATE
1.1       root     4630: *
                   4631: * Warnings:
                   4632: *
                   4633: * History:
1.1.1.3 ! root     4634: *  12-Jan-1993 -by- Petrus Wong
1.1       root     4635: * Wrote it.
                   4636: \**************************************************************************/
                   4637: 
1.1.1.3 ! root     4638: VOID vChkMenuItem(PINFO pInfo, HMENU hMenu, UINT uiFlag)
        !          4639: {
        !          4640:     (pInfo->bStretch ?
        !          4641:         CheckMenuItem(hMenu, MM_STRETCHBLT, uiFlag) :
        !          4642:         CheckMenuItem(hMenu, MM_BITBLT, uiFlag) );
        !          4643: 
        !          4644:     switch (pInfo->iPriority) {
        !          4645:         case THREAD_PRIORITY_IDLE:
        !          4646:             CheckMenuItem(hMenu, MM_TP_IDLE, uiFlag);
        !          4647:             break;
        !          4648:         case THREAD_PRIORITY_LOWEST:
        !          4649:             CheckMenuItem(hMenu, MM_TP_LOW, uiFlag);
        !          4650:             break;
        !          4651:         case THREAD_PRIORITY_BELOW_NORMAL:
        !          4652:             CheckMenuItem(hMenu, MM_TP_BELOW_NORMAL, uiFlag);
        !          4653:             break;
        !          4654:         case THREAD_PRIORITY_NORMAL:
        !          4655:             CheckMenuItem(hMenu, MM_TP_NORMAL, uiFlag);
        !          4656:             break;
        !          4657:         case THREAD_PRIORITY_ABOVE_NORMAL:
        !          4658:             CheckMenuItem(hMenu, MM_TP_ABOVE_NORMAL, uiFlag);
        !          4659:             break;
        !          4660:         case THREAD_PRIORITY_HIGHEST:
        !          4661:             CheckMenuItem(hMenu, MM_TP_HIGH, uiFlag);
        !          4662:             break;
        !          4663:         case THREAD_PRIORITY_TIME_CRITICAL:
        !          4664:             CheckMenuItem(hMenu, MM_TP_TIME_CRITICAL, uiFlag);
        !          4665:             break;
        !          4666:         default:
        !          4667:             break;
        !          4668:     }
1.1       root     4669: 
1.1.1.3 ! root     4670:     switch (pInfo->iStretchMode) {
        !          4671:         case BLACKONWHITE:
        !          4672:             CheckMenuItem(hMenu, MM_BLACKONWHITE, uiFlag);
        !          4673:             break;
        !          4674:         case COLORONCOLOR:
        !          4675:             CheckMenuItem(hMenu, MM_COLORONCOLOR, uiFlag);
        !          4676:             break;
        !          4677:         case WHITEONBLACK:
        !          4678:             CheckMenuItem(hMenu, MM_WHITEONBLACK, uiFlag);
        !          4679:             break;
        !          4680:         case HALFTONE:
        !          4681:             CheckMenuItem(hMenu, MM_HALFTONE, uiFlag);
        !          4682:             break;
        !          4683:         default:
        !          4684:             break;
        !          4685:     }
1.1       root     4686: 
1.1.1.3 ! root     4687:     switch (pInfo->iStep) {
        !          4688:         case 1:
        !          4689:             CheckMenuItem(hMenu, MM_STEP_ONE, uiFlag);
        !          4690:             break;
        !          4691:         case 2:
        !          4692:             CheckMenuItem(hMenu, MM_STEP_TWO, uiFlag);
        !          4693:             break;
        !          4694:         default:
        !          4695:             CheckMenuItem(hMenu, MM_STEP_THREE, uiFlag);
        !          4696:             break;
        !          4697:     }
1.1       root     4698: 
1.1.1.3 ! root     4699:     switch (pInfo->iIteration) {
        !          4700:         case 100:
        !          4701:             CheckMenuItem(hMenu, MM_ITERATION_100, uiFlag);
        !          4702:             break;
        !          4703:         case 500:
        !          4704:             CheckMenuItem(hMenu, MM_ITERATION_500, uiFlag);
        !          4705:             break;
        !          4706:         case 1000:
        !          4707:             CheckMenuItem(hMenu, MM_ITERATION_1000, uiFlag);
        !          4708:             break;
        !          4709:         case 5000:
        !          4710:             CheckMenuItem(hMenu, MM_ITERATION_5000, uiFlag);
        !          4711:             break;
        !          4712:         default:
        !          4713:             CheckMenuItem(hMenu, MM_ITERATION_DOUBLE, uiFlag);
        !          4714:             break;
        !          4715:     }
        !          4716:     return;
1.1       root     4717: }
                   4718: 
                   4719: /******************************Public*Routine******************************\
                   4720: *
1.1.1.3 ! root     4721: * bInitInfo
1.1       root     4722: *
1.1.1.3 ! root     4723: * Effects: Initialize the Info data structure
1.1       root     4724: *
1.1.1.3 ! root     4725: * Warnings:
1.1       root     4726: *
                   4727: * History:
1.1.1.3 ! root     4728: *  16-Feb-1993      Petrus Wong         changed to 9.23 fix value
        !          4729: *  08-Feb-1993      Petrus Wong         Added bUseDIB flag
        !          4730: *  14-Dec-1992 -by- Petrus Wong         Added Rle and pens stuff
        !          4731: *  28-Jan-1992 -by- Petrus Wong
1.1       root     4732: * Wrote it.
                   4733: \**************************************************************************/
1.1.1.3 ! root     4734: 
        !          4735: BOOL bInitInfo(PINFO pInfo)
1.1       root     4736: {
1.1.1.3 ! root     4737:     pInfo->hParent      = ghwndClient;
        !          4738:     pInfo->xFrom        = -2.0;
        !          4739:     pInfo->xTo          = 1.0;
        !          4740:     pInfo->yFrom        = 1.5;
        !          4741:     pInfo->yTo          = -1.5;
        !          4742:     pInfo->lxFrom       = -16777216;                 // 9.23 fix point
        !          4743:     pInfo->lxTo         =  8388608;                  // representation of
        !          4744:     pInfo->lyFrom       =  12582912;                 // -2, 1.0, 1.5, and -1.5
        !          4745:     pInfo->lyTo         = -12582912;                 //
        !          4746:     pInfo->iIteration   = gIteration;
        !          4747:     pInfo->iStep        = gStep;
        !          4748:     pInfo->bStretch     = gbStretch;
        !          4749:     pInfo->iStretchMode = giStretchMode;
        !          4750:     wsprintf((LPSTR) &(pInfo->CaptionBarText), "");
        !          4751:     pInfo->hwnd         = NULL;
        !          4752:     pInfo->hTextWnd     = NULL;
        !          4753:     pInfo->rcClient.top    = 0;
        !          4754:     pInfo->rcClient.left   = 0;
        !          4755:     pInfo->rcClient.bottom = 0;
        !          4756:     pInfo->rcClient.right  = 0;
        !          4757:     pInfo->hdcClient    = NULL;
        !          4758:     pInfo->hRgnPath     = NULL;
        !          4759:     pInfo->hThrd0       = NULL;
        !          4760:     pInfo->hThrd        = NULL;
        !          4761:     pInfo->bDrawing     = FALSE;
        !          4762:     pInfo->dwThreadId   = 0;
        !          4763:     pInfo->dwElapsed    = 0L;
        !          4764:     pInfo->c1           = 0.0;
        !          4765:     pInfo->c2           = 0.0;
        !          4766:     pInfo->lc1          = 0L;
        !          4767:     pInfo->lc2          = 0L;
        !          4768:     pInfo->hBmpSaved    = NULL;
        !          4769:     pInfo->bSizeChng    = FALSE;
        !          4770:     pInfo->bMandel      = TRUE;
        !          4771:     pInfo->bSetDIBsToDevice = FALSE;
        !          4772:     pInfo->bFill        = FALSE;
        !          4773:     pInfo->hBrush       = NULL;
        !          4774:     pInfo->hQuitEvent   = NULL;
        !          4775:     pInfo->hCycleThrd   = NULL;
        !          4776:     pInfo->dwCycleThrdID = 0;
        !          4777:     pInfo->bClrCycle    = FALSE;
        !          4778:     pInfo->bFirstTime   = TRUE;
        !          4779:     pInfo->dwSuspend    = 0;
        !          4780:     pInfo->hBmpMono     = NULL;
        !          4781:     pInfo->bUseMono     = FALSE;
        !          4782:     pInfo->hPrtThrd     = NULL;
        !          4783:     pInfo->dwPrtThrdID  = 0;
        !          4784:     pInfo->hPal         = NULL;
        !          4785:     pInfo->hCyclePal    = NULL;
        !          4786:     pInfo->RleData.ulFiles  = 0;
        !          4787:     pInfo->RleData.ulFrames = 0;
        !          4788:     pInfo->bPlayRleCont = FALSE;
        !          4789:     pInfo->prghPen      = NULL;
        !          4790:     pInfo->iPen         = 0;
        !          4791:     pInfo->iPriority    = THREAD_PRIORITY_NORMAL;
        !          4792:     pInfo->bUseDIB      = FALSE;
        !          4793:     pInfo->bCoreHdr     = FALSE;
        !          4794: 
        !          4795:     return TRUE;
1.1       root     4796: }
                   4797: 
                   4798: /******************************Public*Routine******************************\
                   4799: *
1.1.1.3 ! root     4800: * bResetGlobal
1.1       root     4801: *
1.1.1.3 ! root     4802: * Effects: Set (l) x/y From/To to their default values
        !          4803: *          Used for Julia set
1.1       root     4804: *
1.1.1.3 ! root     4805: * Warnings:
1.1       root     4806: *
                   4807: * History:
1.1.1.3 ! root     4808: *  16-Feb-1993      Petrus Wong     changed to 9.23 fix value
        !          4809: *  28-Jan-1992 -by- Petrus Wong
1.1       root     4810: * Wrote it.
                   4811: \**************************************************************************/
1.1.1.3 ! root     4812: 
        !          4813: BOOL bResetGlobal(VOID)
1.1       root     4814: {
1.1.1.3 ! root     4815:     xFrom  =  -2.0;
        !          4816:     xTo    =   2.0;
        !          4817:     yFrom  =   2.0;
        !          4818:     yTo    =  -2.0;
        !          4819:     lxFrom =  -16777216;
        !          4820:     lxTo   =   16777216;
        !          4821:     lyFrom =   16777216;
        !          4822:     lyTo   =  -16777216;
        !          4823:     return TRUE;
1.1       root     4824: }
                   4825: 
                   4826: /******************************Public*Routine******************************\
                   4827: *
1.1.1.3 ! root     4828: * hBrCreateBrush
1.1       root     4829: *
1.1.1.3 ! root     4830: * Effects: Creates a brush with the specified RGB
1.1       root     4831: *
                   4832: * Warnings:
                   4833: *
                   4834: * History:
1.1.1.3 ! root     4835: *  04-Mar-1992 -by- Petrus Wong
1.1       root     4836: * Wrote it.
                   4837: \**************************************************************************/
                   4838: 
1.1.1.3 ! root     4839: HBRUSH hBrCreateBrush(HDC hDC, DWORD dwRGB)
        !          4840: {
        !          4841:     HDC hdcMem;
        !          4842:     HBRUSH hbr;
        !          4843:     HBRUSH hbrOld;
        !          4844:     HBITMAP hbmPat;
        !          4845:     HBITMAP hbmOld;
1.1       root     4846: 
1.1.1.3 ! root     4847:     hbr = CreateSolidBrush(dwRGB);
1.1       root     4848:     hdcMem = CreateCompatibleDC(hDC);
                   4849: 
1.1.1.3 ! root     4850:     //
        !          4851:     // Minimum size for a bitmap to be used in a fill pattern is 8x8
        !          4852:     //
        !          4853:     hbmPat = CreateCompatibleBitmap(hDC, 8, 8);
1.1       root     4854: 
1.1.1.3 ! root     4855:     hbmOld = SelectObject(hdcMem, hbmPat);
        !          4856:     hbrOld = SelectObject(hdcMem, hbr);
        !          4857:     PatBlt(hdcMem, 0, 0, 8, 8, PATCOPY);
        !          4858: 
        !          4859:     //
        !          4860:     // Deselect hbmPat and hbr
        !          4861:     //
        !          4862:     SelectObject(hdcMem, hbmOld);
        !          4863:     SelectObject(hdcMem, hbrOld);
1.1       root     4864: 
                   4865:     DeleteDC(hdcMem);
1.1.1.3 ! root     4866:     DeleteObject(hbr);
1.1       root     4867: 
1.1.1.3 ! root     4868:     hbr = CreatePatternBrush(hbmPat);
        !          4869: 
        !          4870:     DeleteObject(hbmPat);
1.1       root     4871: 
1.1.1.3 ! root     4872:     return hbr;
1.1       root     4873: }
                   4874: 
1.1.1.3 ! root     4875: 
1.1       root     4876: /******************************Public*Routine******************************\
                   4877: *
1.1.1.3 ! root     4878: * bPrintBmp
1.1       root     4879: *
1.1.1.3 ! root     4880: * Effects: A Thread routine for printing bitmap
1.1       root     4881: *
                   4882: * Warnings:
                   4883: *
                   4884: * History:
1.1.1.3 ! root     4885: *  31-May-1992 -by- Petrus Wong
1.1       root     4886: * Wrote it.
                   4887: \**************************************************************************/
                   4888: 
1.1.1.3 ! root     4889: BOOL bPrintBmp(PPRTDATA pPrtData) {
        !          4890:     HDC         hdcPrinter;
        !          4891:     int         iWidth, iHeight;
1.1       root     4892: 
1.1.1.3 ! root     4893: #ifdef NEWPRTAPI
        !          4894:     DOCINFO     DocInfo;
        !          4895: #endif
1.1       root     4896: 
1.1.1.3 ! root     4897:     if (pPrtData->bUseDefault) {
        !          4898:           hdcPrinter = CreateDC( "", gpszPrinterNames[pPrtData->index],
        !          4899:                                  "", NULL);
1.1       root     4900:     } else {
1.1.1.3 ! root     4901:           hdcPrinter = CreateDC( "", gpszPrinterNames[pPrtData->index],
        !          4902:                                  "", &(pPrtData->DevMode));
1.1       root     4903:     }
                   4904: 
1.1.1.3 ! root     4905:     if (!hdcPrinter)
        !          4906:     {
        !          4907:         ExitThread(0);
        !          4908:         return(FALSE);
        !          4909:     }
        !          4910: 
        !          4911:     iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
        !          4912:     iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
        !          4913: 
        !          4914: #ifdef NEWPRTAPI
        !          4915: 
        !          4916:     DocInfo.cbSize      = sizeof(DOCINFO);
        !          4917:     DocInfo.lpszDocName = pPrtData->info.CaptionBarText;
        !          4918:     DocInfo.lpszOutput   = NULL;
        !          4919:     StartDoc(hdcPrinter, &DocInfo);
        !          4920:     StartPage(hdcPrinter);
        !          4921:     bDrawDIB(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight);
        !          4922:     EndPage(hdcPrinter);
        !          4923:     EndDoc(hdcPrinter);
        !          4924: 
        !          4925: #else
        !          4926: 
        !          4927:     Escape(hdcPrinter, STARTDOC, 20, "Mandelbrot", NULL);
        !          4928:     bDrawDIB(hdcPrinter, &(pPrtData->info), 0, 0, iWidth, iHeight);
        !          4929:     Escape(hdcPrinter, NEWFRAME, 0, NULL, NULL);
        !          4930:     Escape(hdcPrinter, ENDDOC, 0, NULL, NULL);
        !          4931: 
        !          4932: #endif
        !          4933: 
        !          4934:     DeleteDC(hdcPrinter);
        !          4935:     ExitThread(0);
        !          4936:     return(TRUE);
1.1       root     4937: 
                   4938: }
                   4939: 
1.1.1.2   root     4940: 
1.1.1.3 ! root     4941: 
        !          4942: /******************************Public*Routine******************************\
        !          4943: *
        !          4944: * StoreRleFile
        !          4945: *
        !          4946: * Effects:
        !          4947: *
        !          4948: * Warnings:
        !          4949: *
        !          4950: * History:
        !          4951: *  05-Dec-1992 -by- Petrus Wong
        !          4952: * Wrote it.
        !          4953: \**************************************************************************/
        !          4954: 
        !          4955: BOOL bStoreRleFile(HDC hDC, PINFO pInfo, PSTR pszFileName)
1.1.1.2   root     4956: {
1.1.1.3 ! root     4957:   BOOL                bSuccess;
        !          4958:   HANDLE              hFile, hMapFile;
        !          4959:   LPVOID              pMapFile;
        !          4960:   LPBITMAPINFOHEADER  pbmh;
        !          4961:   LPBITMAPINFO        pbmi;
        !          4962:   PBYTE               pjTmp, pjDIBits, pjRleBits;
        !          4963:   ULONG               sizBMI, sizImage, ulfSize;
        !          4964:   DWORD               dwOffBits;
        !          4965:   LONG                lScan;
        !          4966:   INT                 iNumClr;
        !          4967:   ULONG               ulFrames, ulFiles, ulOffset;
        !          4968:   PFILEINFO           pFileInfo;
        !          4969:   DWORD               dwFileSizeLow, dwFileSizeHigh;
        !          4970:   WORD                wBitCount;
        !          4971:   BOOL                bCoreHdr;
        !          4972: 
        !          4973:   bSuccess = TRUE;
        !          4974: 
        !          4975:   if ((hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
        !          4976:           OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) {
        !          4977:       ErrorOut("Fail in file open");
        !          4978:       bSuccess = FALSE;
        !          4979:       goto ErrExit1;
        !          4980:   }
        !          4981: 
        !          4982:   dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
        !          4983:   if ((dwFileSizeLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
        !          4984:       ErrorOut("GetFileSize failed");
        !          4985:       bSuccess = FALSE;
        !          4986:       goto ErrExit2;
        !          4987:   }
        !          4988: 
        !          4989:   //
        !          4990:   // Create a map file of the opened file
        !          4991:   //
        !          4992:   if ((hMapFile = CreateFileMapping(hFile, NULL,
        !          4993:                            PAGE_READONLY, 0, 0, NULL)) == (HANDLE)-1) {
        !          4994:       ErrorOut("Fail in creating map file");
        !          4995:       bSuccess = FALSE;
        !          4996:       goto ErrExit2;
        !          4997:   }
        !          4998: 
        !          4999:   //
        !          5000:   // Map a view of the whole file
        !          5001:   //
        !          5002:   if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) {
        !          5003:       ErrorOut("Fail in mapping view of the Map File object");
        !          5004:       bSuccess = FALSE;
        !          5005:       goto ErrExit3;
        !          5006:   }
        !          5007: 
        !          5008:   ulFiles = pInfo->RleData.ulFiles;
        !          5009:   pFileInfo = &(pInfo->RleData.rgFileInfo[ulFiles]);
        !          5010:   pFileInfo->hFile = hFile;
        !          5011:   pFileInfo->hMapFile = hMapFile;
        !          5012:   pFileInfo->lpvMapView = pMapFile;
1.1.1.2   root     5013: 
1.1.1.3 ! root     5014:   ulFrames = pInfo->RleData.ulFrames;
        !          5015:   ulOffset = 0;
1.1.1.2   root     5016: 
1.1.1.3 ! root     5017:   while (TRUE) {
        !          5018:     //
        !          5019:     // First check that it is a bitmap file
        !          5020:     //
        !          5021:     if (*((PWORD)pMapFile) != 0x4d42) {              // 'BM'
        !          5022:         MessageBox(ghwndMain, "This is not a DIB bitmap file!", "Error", MB_OK);
        !          5023:         bSuccess = FALSE;
        !          5024:         goto ErrExit3;
1.1.1.2   root     5025:     }
1.1.1.3 ! root     5026: #ifdef DEBUG
        !          5027:     {
        !          5028:     static ULONG ulCnt=0;
        !          5029:     char buf[128];
1.1.1.2   root     5030: 
1.1.1.3 ! root     5031:     ulCnt++;
        !          5032:     wsprintf(buf, "ulCnt = %ld", ulCnt);
        !          5033:     MessageBox(ghwndMain, buf, "debug", MB_OK);
        !          5034:     }
        !          5035: #endif
1.1.1.2   root     5036:     //
1.1.1.3 ! root     5037:     // Saving the bfSize field in the BITMAPFILEHEADER for incrementing to the
        !          5038:     // next frame.  bfSize does not start at DWORD boundary...
        !          5039:     //
        !          5040:     {
        !          5041:       PBYTE   pjTmp;
        !          5042:       FILEHDR fHdr, *pfHdr;
        !          5043:       ULONG   ulSiz;
        !          5044: 
        !          5045:       pjTmp = (PBYTE)pMapFile+2;
        !          5046:       pfHdr = &fHdr;
        !          5047: 
        !          5048:       ulSiz = sizeof(FILEHDR);
        !          5049:       while (ulSiz--) {
        !          5050:           *(((PBYTE)pfHdr)++) = *(((PBYTE)pjTmp)++);
        !          5051:       }
        !          5052:       ulfSize = fHdr.bfSize;
        !          5053:       dwOffBits = fHdr.bfOffbits;
1.1.1.2   root     5054:     }
                   5055: 
                   5056:     //
1.1.1.3 ! root     5057:     // advance pMapFile to point pass BITMAPFILEHEADER
1.1.1.2   root     5058:     //
1.1.1.3 ! root     5059:     //pMapFile = (PBYTE)pMapFile + sizeof(BITMAPFILEHEADER);
1.1.1.2   root     5060: 
                   5061:     //
1.1.1.3 ! root     5062:     // Since the file header doesn't end on DWORD boundary...
1.1.1.2   root     5063:     //
1.1.1.3 ! root     5064:     pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER));
        !          5065: 
        !          5066:     {
        !          5067:         BITMAPCOREHEADER bmch, *pbmch;
        !          5068:         BITMAPINFOHEADER bmih, *pbmih;
        !          5069:         PBYTE            pjTmp;
        !          5070:         ULONG            ulSiz;
        !          5071: 
        !          5072:         pbmch = &bmch;
        !          5073:         pbmih = &bmih;
        !          5074: 
        !          5075:         pjTmp = (PBYTE)pbmh;
        !          5076:         ulSiz = sizeof(BITMAPCOREHEADER);
        !          5077:         while (ulSiz--) {
        !          5078:             *(((PBYTE)pbmch)++) = *(((PBYTE)pjTmp)++);
        !          5079:         }
        !          5080: 
        !          5081:         pjTmp = (PBYTE)pbmh;
        !          5082:         ulSiz = sizeof(BITMAPINFOHEADER);
        !          5083:         while (ulSiz--) {
        !          5084:             *(((PBYTE)pbmih)++) = *(((PBYTE)pjTmp)++);
1.1.1.2   root     5085:         }
1.1.1.3 ! root     5086: 
1.1.1.2   root     5087:         //
1.1.1.3 ! root     5088:         // Use the size to determine if it is a BitmapCoreHeader or
        !          5089:         // BitmapInfoHeader
1.1.1.2   root     5090:         //
1.1.1.3 ! root     5091:         if (bmch.bcSize == sizeof(BITMAPCOREHEADER))
        !          5092:         {
        !          5093:             wBitCount = bmch.bcBitCount;
        !          5094:             iNumClr = ((wBitCount == 24) ? 0 : (1 << wBitCount));
        !          5095:             sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)*iNumClr;
        !          5096:             bCoreHdr = TRUE;
        !          5097:         }
        !          5098:         else            // BITMAPINFOHEADER
1.1.1.2   root     5099:         {
1.1.1.3 ! root     5100:             wBitCount = bmih.biBitCount;
        !          5101:             switch (wBitCount) {
        !          5102:                 case 16:
        !          5103:                 case 32:
        !          5104:                     sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3;
        !          5105:                     break;
        !          5106:                 case 24:
        !          5107:                     sizBMI = sizeof(BITMAPINFOHEADER);
        !          5108:                     break;
        !          5109:                 default:
        !          5110:                     iNumClr = (1 << wBitCount);
        !          5111:                     sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr;
        !          5112:                     break;
        !          5113:             }
        !          5114:             bCoreHdr = FALSE;
1.1.1.2   root     5115:         }
1.1.1.3 ! root     5116:     }
        !          5117: 
        !          5118:     if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) {
        !          5119:         MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
        !          5120:         bSuccess = FALSE;
        !          5121:         goto ErrExit3;
        !          5122:     }
        !          5123: 
        !          5124:     //
        !          5125:     // Make sure we pass in a DWORD aligned BitmapInfo to CreateDIBitmap
        !          5126:     // Otherwise, exception on the MIPS platform
        !          5127:     // CR!!!  Equivalent to memcpy
        !          5128:     //
        !          5129:     pjTmp = (PBYTE)pbmi;
1.1.1.2   root     5130: 
1.1.1.3 ! root     5131:     while(sizBMI--)
        !          5132:     {
        !          5133:         *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++);
1.1.1.2   root     5134:     }
                   5135: 
                   5136:     //
1.1.1.3 ! root     5137:     // assuming CreateDIBitmap() is doing a byte fetch...
        !          5138:     //
        !          5139:     pjDIBits = (PBYTE)pMapFile + dwOffBits;
        !          5140: 
        !          5141:     if (pbmi->bmiHeader.biCompression == BI_RGB)
        !          5142:     {
        !          5143:     //
        !          5144:     // Converting to RLE bits...
1.1.1.2   root     5145:     //
1.1.1.3 ! root     5146: 
        !          5147:         MessageBox(ghwndMain, "Converting to RLE format!", "Store", MB_OK);
        !          5148:         lScan = pbmi->bmiHeader.biHeight;
        !          5149:         sizImage = pbmi->bmiHeader.biSizeImage;
        !          5150: 
        !          5151:         //
        !          5152:         // select the palette into the DC first...
        !          5153:         //
        !          5154:         bSelectDIBPal(hDC, pInfo, pbmi, bCoreHdr);
        !          5155:         if ((pInfo->hBmpSaved = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)pbmi,
        !          5156:                             CBM_INIT, pjDIBits, pbmi, DIB_RGB_COLORS)) == NULL) {
        !          5157:             ErrorOut("Fail in creating DIB bitmap from file!");
1.1.1.2   root     5158:             bSuccess = FALSE;
                   5159:             goto ErrExit4;
                   5160:         }
1.1.1.3 ! root     5161: 
        !          5162:         // We want to retrieve the RLE format...
        !          5163:         pbmi->bmiHeader.biCompression = ((wBitCount==4) ? BI_RLE4 : BI_RLE8);
        !          5164: 
        !          5165:         pbmi->bmiHeader.biSizeImage = 0;
        !          5166:         pbmi->bmiHeader.biXPelsPerMeter = 0;
        !          5167:         pbmi->bmiHeader.biYPelsPerMeter = 0;
        !          5168:         pbmi->bmiHeader.biClrUsed = 0;
        !          5169:         pbmi->bmiHeader.biClrImportant = 0;
        !          5170: 
        !          5171:         if (GetDIBits(hDC, pInfo->hBmpSaved, 0, lScan, NULL, pbmi,
        !          5172:             DIB_RGB_COLORS) == 0) {
        !          5173:              MessageBox(ghwndMain, "Not all scans are converted!", "Error", MB_OK);
        !          5174:              bSuccess = FALSE;
        !          5175:              goto ErrExit4;
        !          5176:         }
        !          5177: 
        !          5178:         if (pbmi->bmiHeader.biSizeImage == 0) {
        !          5179:             if (sizImage == 0) {
        !          5180:                 MessageBox(ghwndMain, "biSizeImage == 0!", "Error", MB_OK);
        !          5181:                 bSuccess = FALSE;
        !          5182:                 goto ErrExit4;
        !          5183:             }
        !          5184:             MessageBox(ghwndMain,
        !          5185:                 "Engine returns zero image size, making one up!",
        !          5186:                 "Error", MB_OK);
        !          5187:             sizImage = (sizImage *3)/2;
        !          5188:         } else {
        !          5189:             sizImage = pbmi->bmiHeader.biSizeImage;
        !          5190:         }
        !          5191: 
        !          5192:         if ((pjRleBits = (PBYTE) LocalAlloc(LMEM_FIXED, sizImage)) == NULL) {
        !          5193:              MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
        !          5194:              bSuccess = FALSE;
        !          5195:              goto ErrExit4;
        !          5196:         }
        !          5197: 
        !          5198:         pbmi->bmiHeader.biSizeImage = sizImage;
        !          5199:         if (GetDIBits(hDC, pInfo->hBmpSaved, 0, lScan, pjRleBits, pbmi,
        !          5200:             DIB_RGB_COLORS) < lScan) {
        !          5201:              MessageBox(ghwndMain, "Not all scans are converted!", "Error", MB_OK);
        !          5202:              bSuccess = FALSE;
        !          5203:              goto ErrExit5;
        !          5204:         }
        !          5205: 
        !          5206:         SetDIBitsToDevice(hDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight,
        !          5207:                       0, 0, 0, lScan, pjRleBits, pbmi, DIB_RGB_COLORS);
        !          5208: 
        !          5209:         pInfo->RleData.rgpjFrame[ulFrames] = pjRleBits;
1.1.1.2   root     5210:     } else {
1.1.1.3 ! root     5211:         bSelectDIBPal(hDC, pInfo, pbmi, bCoreHdr);
        !          5212:         lScan = pbmi->bmiHeader.biHeight;
        !          5213:         if (bCoreHdr) {
        !          5214:            lScan = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight;
        !          5215:            SetDIBitsToDevice(hDC, 0, 0, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcWidth, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight,
        !          5216:                       0, 0, 0, lScan, pjDIBits, pbmi, DIB_RGB_COLORS);
        !          5217:         } else {
        !          5218:            lScan = pbmi->bmiHeader.biHeight;
        !          5219:            SetDIBitsToDevice(hDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight,
        !          5220:                       0, 0, 0, lScan, pjDIBits, pbmi, DIB_RGB_COLORS);
        !          5221:         }
        !          5222:         pInfo->RleData.rgpjFrame[ulFrames] = pjDIBits;
1.1.1.2   root     5223:     }
                   5224: 
1.1.1.3 ! root     5225:     pInfo->RleData.ulSize[ulFrames] = sizImage;
        !          5226:     pInfo->RleData.rgpbmi[ulFrames] = pbmi;
1.1.1.2   root     5227: 
1.1.1.3 ! root     5228:     //
        !          5229:     // Go to next frame
        !          5230:     //
        !          5231:     pMapFile = (PBYTE)pMapFile + ulfSize;
        !          5232:     ulOffset += ulfSize;
        !          5233:     ulFrames++;
1.1.1.2   root     5234: 
1.1.1.3 ! root     5235:     //
        !          5236:     // end condition
        !          5237:     //
        !          5238:     if (ulOffset >= dwFileSizeLow) {
        !          5239:         break;
1.1.1.2   root     5240:     }
                   5241: 
1.1.1.3 ! root     5242:   }
1.1.1.2   root     5243: 
1.1.1.3 ! root     5244:     //
        !          5245:     // set pbmi to the very first bmi
        !          5246:     //
        !          5247:     pInfo->RleData.pbmi = pInfo->RleData.rgpbmi[0];
        !          5248: 
        !          5249:     pInfo->RleData.hPal = pInfo->hPal;
        !          5250:     pInfo->RleData.ulFrames = ulFrames;
        !          5251:     return (bSuccess);
        !          5252: 
        !          5253: ErrExit5:
        !          5254:     LocalFree(pjRleBits);
1.1.1.2   root     5255: ErrExit4:
1.1.1.3 ! root     5256:     LocalFree(pbmi);
1.1.1.2   root     5257: ErrExit3:
1.1.1.3 ! root     5258:     CloseHandle(pFileInfo->hMapFile);
        !          5259: ErrExit2:
        !          5260:     CloseHandle(pFileInfo->hFile);
1.1.1.2   root     5261: ErrExit1:
1.1.1.3 ! root     5262:     return (bSuccess);
1.1.1.2   root     5263: 
1.1.1.3 ! root     5264: }
1.1.1.2   root     5265: 
1.1       root     5266: /******************************Public*Routine******************************\
                   5267: *
1.1.1.3 ! root     5268: * bSelectDIBPal
1.1       root     5269: *
1.1.1.3 ! root     5270: * Effects: Creates a logical palette from the DIB and select it into the DC
        !          5271: *          and realize the palette. Saving the hPal in the pInfo->hPal
1.1       root     5272: *
1.1.1.3 ! root     5273: * Warnings: Based on Windows NT DIB support.  If PM support 16,24,32 bpp
        !          5274: *           we need to modify this routine.
1.1       root     5275: *
                   5276: * History:
1.1.1.3 ! root     5277: *  22-Jan-1993      Petrus Wong         PM support
        !          5278: *  31-Dec-1992 -by- Petrus Wong
1.1       root     5279: * Wrote it.
                   5280: \**************************************************************************/
                   5281: 
1.1.1.3 ! root     5282: BOOL bSelectDIBPal(HDC hDC, PINFO pInfo, LPBITMAPINFO pbmi, BOOL bCoreHdr)
1.1       root     5283: {
1.1.1.3 ! root     5284:   LOGPALETTE    *plogPal;
        !          5285:   UINT          uiSizPal;
        !          5286:   INT           i, iNumClr;
        !          5287:   WORD          wBitCount;
        !          5288: 
        !          5289:   if (bCoreHdr) {
        !          5290:     wBitCount = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount;
        !          5291:   } else {
        !          5292:     wBitCount = pbmi->bmiHeader.biBitCount;
        !          5293:   }
        !          5294: 
        !          5295:   switch (wBitCount) {
        !          5296:     case 16:
        !          5297:     case 24:
        !          5298:     case 32:                            // Does PM supports these?
        !          5299:         return FALSE;
        !          5300:     default:
        !          5301:         iNumClr = (1 << wBitCount);
        !          5302:         break;
        !          5303:   }
1.1       root     5304: 
1.1.1.3 ! root     5305:   uiSizPal = sizeof(WORD)*2 + sizeof(PALETTEENTRY)*iNumClr;
        !          5306:   if ((plogPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED,uiSizPal)) == NULL) {
        !          5307:       ErrorOut("Fail in Allocating palette!");
        !          5308:       pInfo->hPal = NULL;
        !          5309:       return FALSE;
        !          5310:   }
        !          5311: 
        !          5312:   plogPal->palVersion = 0x300;
        !          5313:   plogPal->palNumEntries = (WORD) iNumClr;
        !          5314: 
        !          5315:   if (bCoreHdr) {
        !          5316:     for (i=0; i<iNumClr; i++) {
        !          5317:         plogPal->palPalEntry[i].peRed   = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtRed;
        !          5318:         plogPal->palPalEntry[i].peGreen = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtGreen;
        !          5319:         plogPal->palPalEntry[i].peBlue  = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtBlue;
        !          5320:         plogPal->palPalEntry[i].peFlags = PC_RESERVED;
1.1       root     5321:     }
1.1.1.3 ! root     5322:   } else {
        !          5323:     for (i=0; i<iNumClr; i++) {
        !          5324:         plogPal->palPalEntry[i].peRed   = pbmi->bmiColors[i].rgbRed;
        !          5325:         plogPal->palPalEntry[i].peGreen = pbmi->bmiColors[i].rgbGreen;
        !          5326:         plogPal->palPalEntry[i].peBlue  = pbmi->bmiColors[i].rgbBlue;
        !          5327:         plogPal->palPalEntry[i].peFlags = PC_RESERVED;
1.1       root     5328:     }
1.1.1.3 ! root     5329:   }
1.1       root     5330: 
1.1.1.3 ! root     5331:   DeleteObject(pInfo->hPal);
        !          5332:   pInfo->hPal = CreatePalette((LPLOGPALETTE)plogPal);
        !          5333:   if ((pInfo->hPal) == NULL) {
        !          5334:       ErrorOut("Fail in creating palette!");
        !          5335:       return FALSE;
        !          5336:   }
        !          5337: 
        !          5338:   if ((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE) {
        !          5339:     SelectPalette(hDC, pInfo->hPal, FALSE);
        !          5340:     RealizePalette(hDC);
        !          5341:   }
        !          5342: 
        !          5343:   GlobalFree(plogPal);
        !          5344: 
        !          5345:   return TRUE;
1.1       root     5346: }
                   5347: 
                   5348: /******************************Public*Routine******************************\
                   5349: *
1.1.1.3 ! root     5350: * bFreeRleFile
1.1       root     5351: *
1.1.1.3 ! root     5352: * Effects:
1.1       root     5353: *
1.1.1.3 ! root     5354: * Warnings:
1.1       root     5355: *
                   5356: * History:
1.1.1.3 ! root     5357: *  05-Dec-1992 -by- Petrus Wong
1.1       root     5358: * Wrote it.
                   5359: \**************************************************************************/
                   5360: 
1.1.1.3 ! root     5361: BOOL bFreeRleFile(PINFO pInfo)
1.1       root     5362: {
1.1.1.3 ! root     5363:     ULONG               ulFiles;
        !          5364:     ULONG               ulFrames;
        !          5365:     ULONG               i;
        !          5366:     PFILEINFO           pFileInfo;
        !          5367: 
        !          5368:     ulFiles = pInfo->RleData.ulFiles;
        !          5369:     ulFrames = pInfo->RleData.ulFrames;
        !          5370: 
        !          5371:     for (i = 0; i < ulFrames; i++) {
        !          5372:         LocalFree(pInfo->RleData.rgpjFrame[i]);
        !          5373:         LocalFree(pInfo->RleData.rgpbmi[i]);
        !          5374:     }
1.1       root     5375: 
1.1.1.3 ! root     5376:     for (i = 0; i < ulFiles; i++) {
        !          5377:         pFileInfo = &(pInfo->RleData.rgFileInfo[i]);
        !          5378:         CloseHandle(pFileInfo->hFile);
        !          5379:         CloseHandle(pFileInfo->hMapFile);
        !          5380:         UnmapViewOfFile(pFileInfo->lpvMapView);
1.1       root     5381:     }
                   5382: 
1.1.1.3 ! root     5383:     pInfo->RleData.ulFiles = 0;
        !          5384:     pInfo->RleData.ulFrames = 0;
        !          5385:     return TRUE;
1.1       root     5386: }
                   5387: 
                   5388: /******************************Public*Routine******************************\
                   5389: *
1.1.1.3 ! root     5390: * bPlayRle
1.1       root     5391: *
1.1.1.3 ! root     5392: * Effects:
1.1       root     5393: *
                   5394: * Warnings:
                   5395: *
                   5396: * History:
1.1.1.3 ! root     5397: *  05-Dec-1992 -by- Petrus Wong
1.1       root     5398: * Wrote it.
                   5399: \**************************************************************************/
                   5400: 
1.1.1.3 ! root     5401: BOOL bPlayRle(PINFO pInfo)
1.1       root     5402: {
1.1.1.3 ! root     5403:     ULONG               ulFrames;
        !          5404:     ULONG               i;
        !          5405:     LPBITMAPINFO        pbmi;
        !          5406:     HDC                 hDC;
        !          5407:     HWND                hViewSurf;
        !          5408:     int                 ii;
        !          5409: 
        !          5410: //    RECT                rc;
        !          5411: 
        !          5412:     hDC = GetDC(hViewSurf=pInfo->hwnd);
        !          5413: 
        !          5414:     SelectPalette(hDC, pInfo->RleData.hPal, FALSE);
        !          5415:     ii=RealizePalette(hDC);
        !          5416:     if (ii){
        !          5417:         UpdateColors (hDC);
1.1       root     5418:     }
1.1.1.3 ! root     5419: 
        !          5420:     ulFrames = pInfo->RleData.ulFrames;
        !          5421: 
        !          5422:     for (i = 0; i < ulFrames; i++) {
        !          5423:         pbmi = pInfo->RleData.rgpbmi[i];
        !          5424:         SetDIBitsToDevice(hDC,
        !          5425:                   0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight,
        !          5426:                   0, 0, 0, pbmi->bmiHeader.biHeight,
        !          5427:                   pInfo->RleData.rgpjFrame[i], pbmi, DIB_RGB_COLORS);
        !          5428: 
        !          5429: #if 0
        !          5430:         GetClientRect(pInfo->hwnd, &rc);
        !          5431:         StretchDIBits(hDC,
        !          5432:                0, 0, rc.right, rc.bottom,
        !          5433:                0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight,
        !          5434:                (LPSTR)pInfo->RleData.rgpjFrame[i], pbmi, DIB_RGB_COLORS,
        !          5435:                SRCCOPY);
        !          5436: #endif
        !          5437:     }
        !          5438: 
        !          5439:     ReleaseDC(hViewSurf, hDC);
        !          5440: 
1.1       root     5441:     return TRUE;
                   5442: }
                   5443: 
1.1.1.3 ! root     5444: 
1.1       root     5445: /******************************Public*Routine******************************\
                   5446: *
1.1.1.3 ! root     5447: * bSaveRleFile
1.1       root     5448: *
1.1.1.3 ! root     5449: * Effects:
1.1       root     5450: *
                   5451: * Warnings:
                   5452: *
                   5453: * History:
1.1.1.3 ! root     5454: *  14-Dec-1992 -by- Petrus Wong
1.1       root     5455: * Wrote it.
                   5456: \**************************************************************************/
                   5457: 
1.1.1.3 ! root     5458: BOOL bSaveRleFile(HDC hDC, PINFO pInfo, PSTR pszFileName)
1.1       root     5459: {
1.1.1.3 ! root     5460:     int                 hFile;
        !          5461:     OFSTRUCT            ofReOpenBuff;
        !          5462:     BOOL                bSuccess;
        !          5463:     BITMAPFILEHEADER    bfh;
        !          5464:     ULONG               ulFrames;
        !          5465:     ULONG               i;
        !          5466:     LPBITMAPINFO        pbmi;
        !          5467:     ULONG               ulNumClr;
        !          5468:     ULONG               ulSize;
        !          5469: 
        !          5470:     bSuccess = TRUE;
        !          5471:     ulFrames = pInfo->RleData.ulFrames;
        !          5472: 
        !          5473:     if (ulFrames == 0) {
        !          5474:         MessageBox(GetFocus(), "There's no RLE to save!", "Error", MB_OK);
        !          5475:         return FALSE;
        !          5476:     }
        !          5477: 
        !          5478:     // Let's open the file and get ready for writing
        !          5479:     if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff,
        !          5480:                  OF_CREATE | OF_WRITE)) == -1) {
        !          5481:         MessageBox(GetFocus(), "Failed in OpenFile!", "Error", MB_OK);
        !          5482:         ErrorOut("OpenFile");
        !          5483:         return FALSE;
        !          5484:     }
        !          5485: 
        !          5486:     for (i = 0; i < ulFrames; i++) {
        !          5487: 
        !          5488:         pbmi = pInfo->RleData.rgpbmi[i];
        !          5489: 
        !          5490:         switch(pbmi->bmiHeader.biBitCount) {
        !          5491:             case 24:
        !          5492:                 ulSize = 0;
        !          5493:                 break;
        !          5494:             case 16:
        !          5495:             case 32:
        !          5496:                 ulSize = sizeof(DWORD)*3;
        !          5497:                 break;
        !          5498:             default:
        !          5499:                 ulNumClr = 1<<pbmi->bmiHeader.biBitCount;
        !          5500:                 ulSize = sizeof(RGBQUAD)*ulNumClr;
        !          5501:                 break;
        !          5502:         }
        !          5503: #if 0
        !          5504:         ulNumClr = ((pbmi->bmiHeader.biBitCount == 24)
        !          5505:                        ? 0
        !          5506:                        : (1<<pbmi->bmiHeader.biBitCount));
        !          5507: #endif
        !          5508:         // fill in the info for the BitmapFileHeader
        !          5509:         bfh.bfType    = 0x4D42;                            // 'BM'
        !          5510:         bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
        !          5511:                         ulSize;
        !          5512:                         //sizeof(RGBQUAD)*ulNumClr;
        !          5513:         bfh.bfSize    = bfh.bfOffBits + pbmi->bmiHeader.biSizeImage;
        !          5514:         bfh.bfReserved1 =
        !          5515:         bfh.bfReserved2 = 0;
        !          5516: 
        !          5517:         // Write out the file header now
        !          5518:         if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) {
        !          5519:             MessageBox(GetFocus(), "Failed in Writing File Header!",
        !          5520:                         "Error", MB_OK);
        !          5521:             bSuccess = FALSE;
        !          5522:             goto ErrExit1;
        !          5523:         }
        !          5524: 
        !          5525:         // Now write out the BitmapInfoHeader and color table, if any
        !          5526:         if (_lwrite(hFile, (LPSTR)pbmi, sizeof(BITMAPINFOHEADER) +
        !          5527:                                         ulSize) == -1) {
        !          5528:                                         //sizeof(RGBQUAD)*ulNumClr) == -1) {
        !          5529:             MessageBox(GetFocus(), "Failed in Writing Bitmap Info!",
        !          5530:                         "Error", MB_OK);
        !          5531:             bSuccess = FALSE;
        !          5532:             goto ErrExit1;
        !          5533:         }
        !          5534: 
        !          5535:         // write the bits also
        !          5536:         if (_lwrite(hFile, (LPSTR)pInfo->RleData.rgpjFrame[i],
        !          5537:                            pbmi->bmiHeader.biSizeImage) == -1) {
        !          5538:             MessageBox(GetFocus(), "Failed in Writing RLE bits!",
        !          5539:                         "Error", MB_OK);
        !          5540:             bSuccess = FALSE;
        !          5541:             goto ErrExit1;
        !          5542:         }
        !          5543: 
        !          5544:     }
        !          5545: 
        !          5546: ErrExit1:
        !          5547:     _lclose(hFile);
        !          5548:     return bSuccess;
1.1       root     5549: }
                   5550: 
1.1.1.3 ! root     5551: 
1.1       root     5552: /******************************Public*Routine******************************\
                   5553: *
1.1.1.3 ! root     5554: * bPlayRleCont
1.1       root     5555: *
1.1.1.3 ! root     5556: * Effects:
1.1       root     5557: *
                   5558: * Warnings:
                   5559: *
                   5560: * History:
1.1.1.3 ! root     5561: *  14-Dec-1992 -by- Petrus Wong
1.1       root     5562: * Wrote it.
                   5563: \**************************************************************************/
                   5564: 
1.1.1.3 ! root     5565: BOOL bPlayRleCont(HDC hDC, PINFO pInfo)
1.1       root     5566: {
1.1.1.3 ! root     5567:     BOOL    bQuit;
        !          5568:     MSG     msg;
        !          5569:     int     ii;
        !          5570: 
        !          5571:     bQuit = FALSE;
        !          5572: 
        !          5573:     SelectPalette(hDC, pInfo->RleData.hPal, FALSE);
        !          5574:     ii=RealizePalette(hDC);
        !          5575:     if (ii){
        !          5576:         UpdateColors (hDC);
        !          5577:     }
        !          5578: 
        !          5579:     while (TRUE && !bQuit) {
        !          5580: 
        !          5581:         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        !          5582: 
        !          5583:             if ((msg.message == WM_QUIT) || (msg.message == WM_CLOSE) ||
        !          5584:                 ((msg.message == WM_SYSCOMMAND) && (msg.wParam == SC_CLOSE))) {
        !          5585:                 bQuit = TRUE;
        !          5586:                 PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);
        !          5587:             } else {
        !          5588:                 if (!TranslateAccelerator(msg.hwnd, ghAccel, &msg)) {
        !          5589:                     TranslateMessage(&msg);
        !          5590:                     DispatchMessage(&msg);
        !          5591:                 }
        !          5592:            }
        !          5593:         }
        !          5594: 
        !          5595:         if (!pInfo->bPlayRleCont) {
        !          5596:             bQuit = TRUE;
        !          5597:         }
        !          5598: 
        !          5599:         if (!bQuit) {
        !          5600:             bPlayRle(pInfo);
        !          5601:         }
        !          5602: 
        !          5603:     }
1.1       root     5604:     return TRUE;
                   5605: }
                   5606: 
1.1.1.3 ! root     5607: 
1.1       root     5608: /******************************Public*Routine******************************\
                   5609: *
1.1.1.3 ! root     5610: * bPlayRleCont2
1.1       root     5611: *
1.1.1.3 ! root     5612: * Effects:
1.1       root     5613: *
                   5614: * Warnings:
                   5615: *
                   5616: * History:
1.1.1.3 ! root     5617: *  14-Dec-1992 -by- Petrus Wong
1.1       root     5618: * Wrote it.
                   5619: \**************************************************************************/
                   5620: 
1.1.1.3 ! root     5621: BOOL bPlayRleCont2(PINFO pInfo)
1.1       root     5622: {
1.1.1.3 ! root     5623:     HDC             hDC;
        !          5624:     HWND            hViewSurf;
        !          5625:     DWORD           dwWait;
        !          5626:     BOOL            bQuit;
        !          5627:     int             ii;
        !          5628: 
        !          5629:     hDC = GetDC(hViewSurf=pInfo->hwnd);
        !          5630: 
        !          5631:     SelectPalette(hDC, pInfo->RleData.hPal, FALSE);
        !          5632:     ii=RealizePalette(hDC);
        !          5633:     if (ii){
        !          5634:         UpdateColors (hDC);
        !          5635:     }
1.1       root     5636: 
1.1.1.3 ! root     5637:     bQuit = FALSE;
        !          5638:     while (TRUE) {
        !          5639:         //
        !          5640:         // If parent gets a WM_CLOSE, we will return
        !          5641:         //
        !          5642:         dwWait = WaitForSingleObject(pInfo->hQuitEvent, 0);
        !          5643:         if (dwWait == WAIT_TIMEOUT) {
        !          5644:             MessageBox(ghwndMain,
        !          5645:                 "Continuous Play Thread Quitting!",
        !          5646:                 "Continuous Play Thread", MB_OK);
        !          5647:             break;
        !          5648:         }
1.1       root     5649: 
1.1.1.3 ! root     5650:         if (!pInfo->bPlayRleCont) {
        !          5651:             bQuit = TRUE;
        !          5652:         }
1.1       root     5653: 
1.1.1.3 ! root     5654:         if (!bQuit)
        !          5655:             bPlayRle(pInfo);
        !          5656:     }
1.1       root     5657: 
1.1.1.3 ! root     5658:     ReleaseDC(hViewSurf, hDC);
1.1       root     5659: 
1.1.1.3 ! root     5660:     ExitThread(0);
        !          5661:     return TRUE;
1.1       root     5662: 
                   5663: }
                   5664: 
                   5665: 
                   5666: /******************************Public*Routine******************************\
                   5667: *
1.1.1.3 ! root     5668: * DIBfromDDB
1.1       root     5669: *
1.1.1.3 ! root     5670: * Effects:  Call GetDIBits to retrieve the DIB info from DDB
1.1       root     5671: *
                   5672: * Warnings:
                   5673: *
                   5674: * History:
1.1.1.3 ! root     5675: *  17-Jun-1993 -by- Petrus Wong
1.1       root     5676: * Wrote it.
                   5677: \**************************************************************************/
                   5678: 
1.1.1.3 ! root     5679: HBITMAP DIBfromDDB(HDC hDC, HBITMAP hBmp, PINFO pInfo)
        !          5680: {
        !          5681:     LPBITMAPINFO        pbmi;
        !          5682:     HBITMAP             hDIB;
        !          5683:     INT                 iBitCount, iNumClr;
        !          5684:     BITMAP              bm;
        !          5685:     DWORD               sizImage;
        !          5686:     PBYTE               pjBits;
        !          5687:     ULONG               sizBMI;
        !          5688:     LONG                lScan;
        !          5689: 
        !          5690:     iBitCount = GetDeviceCaps(hDC, BITSPIXEL);
        !          5691:     switch (iBitCount) {
        !          5692:         case 16:
        !          5693:         case 32:
        !          5694:             sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3;
        !          5695:             break;
        !          5696:         case 24:
        !          5697:             sizBMI = sizeof(BITMAPINFOHEADER);
        !          5698:             break;
        !          5699:         default:
        !          5700:             iNumClr = (1 << iBitCount);
        !          5701:             sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr;
        !          5702:             break;
        !          5703:     }
1.1       root     5704: 
1.1.1.3 ! root     5705:     if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) {
        !          5706:         MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
        !          5707:         goto ErrExit1;
        !          5708:     }
1.1       root     5709: 
1.1.1.3 ! root     5710:     pbmi->bmiHeader.biSize = 0x28;              // GDI need this to work
        !          5711:     pbmi->bmiHeader.biBitCount = 0;             // don't get the color table
        !          5712:     pbmi->bmiHeader.biCompression = BI_RGB;
        !          5713:     pbmi->bmiHeader.biSizeImage = 0;
        !          5714:     pbmi->bmiHeader.biXPelsPerMeter = 0;
        !          5715:     pbmi->bmiHeader.biYPelsPerMeter = 0;
        !          5716:     pbmi->bmiHeader.biClrUsed = 0;
        !          5717:     pbmi->bmiHeader.biClrImportant = 0;
        !          5718: 
        !          5719:     GetObject(hBmp, sizeof(BITMAP), &bm);
        !          5720: 
        !          5721:     //
        !          5722:     // Important!  Select the correct palette corresponding to the DDB
        !          5723:     //
        !          5724:     SelectPalette(hDC, pInfo->hPal, FALSE);
        !          5725:     if (GetDIBits(hDC, hBmp, 0, bm.bmHeight, NULL, pbmi,
        !          5726:         DIB_RGB_COLORS) == 0) {
        !          5727:          MessageBox(ghwndMain, "Not all scans are returned!", "Error", MB_OK);
        !          5728:          goto ErrExit2;
1.1       root     5729:     }
                   5730: 
1.1.1.3 ! root     5731:     sizImage = pbmi->bmiHeader.biSizeImage;
        !          5732:     if (sizImage == 0) {
        !          5733:         MessageBox(ghwndMain, "biSizeImage == 0!", "Error", MB_OK);
        !          5734:         goto ErrExit2;
1.1       root     5735:     }
                   5736: 
1.1.1.3 ! root     5737:     if ((pjBits = (PBYTE) LocalAlloc(LMEM_FIXED, sizImage)) == NULL) {
        !          5738:          MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
        !          5739:          goto ErrExit2;
        !          5740:     }
1.1       root     5741: 
1.1.1.3 ! root     5742:     lScan = pbmi->bmiHeader.biHeight;
1.1       root     5743: 
1.1.1.3 ! root     5744:     if (GetDIBits(hDC, pInfo->hBmpSaved, 0, lScan, pjBits, pbmi,
        !          5745:         DIB_RGB_COLORS) < lScan) {
        !          5746:          MessageBox(ghwndMain, "Not all scans are returned!", "Error", MB_OK);
        !          5747:          goto ErrExit3;
        !          5748:     }
1.1       root     5749: 
1.1.1.3 ! root     5750:     //
        !          5751:     // Saving the DIB...free memory when the windows is closed.
        !          5752:     //
        !          5753:     pInfo->RleData.rgpjFrame[0] = pjBits;
        !          5754:     pInfo->RleData.rgpbmi[0]    = pbmi;
        !          5755:     pInfo->RleData.pbmi         = (PBITMAPINFO) &(pInfo->RleData.rgpbmi[0]);
        !          5756:     pInfo->RleData.ulFrames     = 1;
        !          5757:     pInfo->RleData.ulFiles      = 1;
1.1       root     5758: 
1.1.1.3 ! root     5759:     // set flag to use original DIB as source for blting so HT can be done
        !          5760:     pInfo->bUseDIB = TRUE;
1.1       root     5761: 
1.1.1.3 ! root     5762:     pInfo->bCoreHdr = FALSE;
1.1       root     5763: 
1.1.1.3 ! root     5764:     hDIB = CreateDIBitmap(hDC, NULL, CBM_CREATEDIB | CBM_INIT, pjBits, pbmi,
        !          5765:            DIB_RGB_COLORS);
        !          5766: 
        !          5767:     return hDIB;
1.1       root     5768: 
1.1.1.3 ! root     5769: ErrExit3:
        !          5770:     LocalFree(pjBits);
        !          5771: ErrExit2:
        !          5772:     LocalFree(pbmi);
        !          5773: ErrExit1:
        !          5774:     return ((HBITMAP)NULL);
1.1       root     5775: }

unix.superglobalmegacorp.com

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