Annotation of q_a/samples/scrnsave/fractal.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: fractal.c
        !             3: *
        !             4: * Fractal generation Screen saver
        !             5: *
        !             6: * Created: 19-Dec-1992 20:43:00
        !             7: * Author: Petrus Wong
        !             8: *
        !             9: * Copyright (c) 1992 Microsoft Corporation
        !            10: *
        !            11: * The screen saver generates the Mandelbrot picture...
        !            12: *
        !            13: * Dependencies:
        !            14: *
        !            15: *   (#defines)
        !            16: *   (#includes)
        !            17: *
        !            18: \**************************************************************************/
        !            19: #include            <windows.h>
        !            20: #include            <scrnsave.h>
        !            21: #include            <stdio.h>
        !            22: #include            <math.h>
        !            23: #include            <commdlg.h>
        !            24: #include            "fractal.h"
        !            25: 
        !            26: LONG APIENTRY ScreenSaverProc(HWND, UINT, WPARAM, LPARAM);
        !            27: BOOL APIENTRY ScreenSaverConfigureDialog(HWND, UINT, WPARAM, LPARAM);
        !            28: BOOL WINAPI RegisterDialogClasses(HANDLE);
        !            29: BOOL StartMandelbrot (PINFO);
        !            30: INT  iCreatePenFrPal(HDC, PVOID *, INT, HPALETTE *);
        !            31: BOOL bInitInfo(PINFO);
        !            32: void vLoadStrings(VOID);
        !            33: BOOL SaveBitmapFile(HDC, HBITMAP, PSTR);
        !            34: void ErrorOut(char errstring[30]);
        !            35: BOOL bGetPPStr(char szXFr[MAXDOUBLELEN], char szYFr[MAXDOUBLELEN],
        !            36:                char szX2[MAXDOUBLELEN],  char szY2[MAXDOUBLELEN],
        !            37:                char szSavef[MAXFILELEN], char szIter[MAXDOUBLELEN]);
        !            38: BOOL bInitDlgItems(HWND);
        !            39: BOOL bColorCycle(HDC, PINFO);
        !            40: /******************************Public*Routine******************************\
        !            41: *
        !            42: * ScreenSaverProc
        !            43: *
        !            44: * Effects:  Creates a drawing thread.
        !            45: *
        !            46: * Warnings:
        !            47: *
        !            48: * History:
        !            49: *  18-Dec-1992 -by- Petrus Wong
        !            50: * Wrote it.
        !            51: \**************************************************************************/
        !            52: 
        !            53: LONG APIENTRY
        !            54: ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
        !            55: {
        !            56:     static HBRUSH hBkBr;
        !            57: 
        !            58:     switch(message)
        !            59:     {
        !            60:         case WM_CREATE:
        !            61:             hBkBr = GetStockObject(BLACK_BRUSH);
        !            62:             hpnRed     = CreatePen(PS_SOLID, 0, RGB(0xFF, 0,    0));
        !            63:             hpnGreen   = CreatePen(PS_SOLID, 0, RGB(0,    0xFF, 0));
        !            64:             hpnBlack   = CreatePen(PS_SOLID, 0, RGB(0,    0,    0));
        !            65: 
        !            66:             vLoadStrings();
        !            67:             bInitInfo(&gInfo);
        !            68:             break;
        !            69: 
        !            70:         case WM_ERASEBKGND: {
        !            71:             RECT    rc;
        !            72: 
        !            73:             GetClientRect(hWnd, &rc);
        !            74:             FillRect((HDC)wParam, &rc, hBkBr);
        !            75:             gInfo.bMandel = TRUE;
        !            76:             gInfo.hwnd = hWnd;
        !            77:             gInfo.hHTPal = CreateHalftonePalette((HDC)wParam);
        !            78:             gInfo.hThrd = CreateThread(NULL, 0,
        !            79:                                  (LPTHREAD_START_ROUTINE)StartMandelbrot,
        !            80:                                  &gInfo,
        !            81:                                  STANDARD_RIGHTS_REQUIRED,
        !            82:                                  &gInfo.dwThreadId );
        !            83: 
        !            84:             if (gInfo.hThrd) {
        !            85:                 SetThreadPriority(gInfo.hThrd, THREAD_PRIORITY_BELOW_NORMAL);
        !            86:             }
        !            87: 
        !            88: 
        !            89:             return 0L;
        !            90:         }
        !            91:         case WM_DESTROY:
        !            92:             DeleteObject(hBkBr);
        !            93:             DeleteObject(hpnRed);
        !            94:             DeleteObject(hpnGreen);
        !            95:             DeleteObject(hpnBlack);
        !            96:             TerminateThread(gInfo.hThrd, (DWORD)0L);
        !            97:             break;
        !            98:     }
        !            99:     return (DefScreenSaverProc(hWnd,message,wParam,lParam));
        !           100: }
        !           101: 
        !           102: 
        !           103: /******************************Public*Routine******************************\
        !           104: *
        !           105: * ScreenSaverConfigureDialog
        !           106: *
        !           107: * Effects:
        !           108: *
        !           109: * Warnings:
        !           110: *
        !           111: * History:
        !           112: *  19-Dec-1992 -by- Petrus Wong
        !           113: * Wrote it.
        !           114: \**************************************************************************/
        !           115: 
        !           116: BOOL APIENTRY
        !           117: ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        !           118: {
        !           119:     switch(message)
        !           120:     {
        !           121:         case WM_INITDIALOG: {
        !           122:             vLoadStrings();
        !           123:             bInitDlgItems(hDlg);
        !           124:             return TRUE;
        !           125:         }
        !           126:         case WM_COMMAND:
        !           127: 
        !           128:             switch(LOWORD(wParam))
        !           129:             {
        !           130:                 static char         szFile[MAXPATHLEN];
        !           131:                 static BOOL         bSave2DiffFile = FALSE;
        !           132: 
        !           133:                 case ID_SAVEAS: {
        !           134:                     OPENFILENAME ofn;
        !           135:                     char         szDirName[MAXPATHLEN];
        !           136:                     char         szFileTitle[256];
        !           137:                     static char  *szFilter;
        !           138: 
        !           139:                     szFilter = "DIB files (*.bmp)\0\0";
        !           140: 
        !           141:                     GetSystemDirectory((LPSTR) szDirName, MAXPATHLEN);
        !           142:                     strcpy(szFile, "*.bmp\0");
        !           143:                     ofn.lStructSize = sizeof(OPENFILENAME);
        !           144:                     ofn.hwndOwner = hDlg;
        !           145:                     ofn.lpstrFilter = szFilter;
        !           146:                     ofn.lpstrCustomFilter = (LPSTR) NULL;
        !           147:                     ofn.nMaxCustFilter = 0L;
        !           148:                     ofn.nFilterIndex = 0L;
        !           149:                     ofn.lpstrFile = szFile;
        !           150:                     ofn.nMaxFile = sizeof(szFile);
        !           151:                     ofn.lpstrFileTitle = szFileTitle;
        !           152:                     ofn.nMaxFileTitle = sizeof(szFileTitle);
        !           153:                     ofn.lpstrInitialDir = szDirName;
        !           154:                     ofn.lpstrTitle = "Save Bitmap As";
        !           155:                     ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
        !           156:                     ofn.nFileOffset = 0;
        !           157:                     ofn.nFileExtension = 0;
        !           158:                     ofn.lpstrDefExt = (LPSTR)NULL;
        !           159: 
        !           160:                     if (GetSaveFileName(&ofn))
        !           161:                         bSave2DiffFile = TRUE;
        !           162: 
        !           163:                     break;
        !           164:                 }
        !           165:                 case IDOK: {
        !           166:                     char    szXFr[MAXDOUBLELEN];
        !           167:                     char    szYFr[MAXDOUBLELEN];
        !           168:                     char    szX2[MAXDOUBLELEN];
        !           169:                     char    szY2[MAXDOUBLELEN];
        !           170:                     char    szIter[MAXDOUBLELEN];
        !           171: 
        !           172:                     if (bSave2DiffFile)
        !           173:                         WritePrivateProfileString(szAppName, szSaveFile, szFile, szIniFile);
        !           174: 
        !           175:                     //
        !           176:                     // Saves new configuartion...
        !           177:                     //
        !           178:                     GetDlgItemText(hDlg, ID_XFROM, szXFr, MAXDOUBLELEN);
        !           179:                     GetDlgItemText(hDlg, ID_YFROM, szYFr, MAXDOUBLELEN);
        !           180:                     GetDlgItemText(hDlg, ID_XTO,   szX2,  MAXDOUBLELEN);
        !           181:                     GetDlgItemText(hDlg, ID_YTO,   szY2,  MAXDOUBLELEN);
        !           182:                     GetDlgItemText(hDlg, ID_ITERATION, szIter, MAXDOUBLELEN);
        !           183:                     WritePrivateProfileString(szAppName, szXFrom, szXFr, szIniFile);
        !           184:                     WritePrivateProfileString(szAppName, szYFrom, szYFr, szIniFile);
        !           185:                     WritePrivateProfileString(szAppName, szXTo,    szX2,  szIniFile);
        !           186:                     WritePrivateProfileString(szAppName, szYTo,    szY2,  szIniFile);
        !           187:                     WritePrivateProfileString(szAppName, szIteration, szIter,  szIniFile);
        !           188:                 }
        !           189:                 case IDCANCEL:
        !           190:                     bSave2DiffFile = FALSE;
        !           191:                     EndDialog(hDlg,LOWORD(wParam) == IDOK);
        !           192:                     return TRUE;
        !           193:                 default:
        !           194:                     break;
        !           195:             }
        !           196:         default:
        !           197:             break;
        !           198:     }
        !           199:     return FALSE;
        !           200: }
        !           201: 
        !           202: /******************************Public*Routine******************************\
        !           203: *
        !           204: * RegisterDialogClasses
        !           205: *
        !           206: * Effects: Register window classes used by the configuration dialog
        !           207: *
        !           208: * Warnings: Return TRUE even if no class needed to be registered.
        !           209: *
        !           210: * History:
        !           211: *  18-Dec-1992 -by- Petrus Wong
        !           212: * Wrote it.
        !           213: \**************************************************************************/
        !           214: 
        !           215: BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
        !           216: {
        !           217:     return TRUE;
        !           218: }
        !           219: 
        !           220: /**************************************************************************\
        !           221: *
        !           222: * StartMandelbrot
        !           223: *                                           2
        !           224: * Effects: Draw'g the Mandelbrot Set for Q (z) = z  + c, where z, c complex
        !           225: *
        !           226: * Warnings:
        !           227: *
        !           228: * History:
        !           229: *  15-Jan-1993      Petrus Wong     Added color cycle and removed the red &
        !           230: *                                   black for saving the screen
        !           231: *  19-Dec-1992      Petrus Wong     Adapted from the Mandel SDK Sample
        !           232: *  14-Dec-1992 -by- Petrus Wong     Enable shadow bitmap
        !           233: *  14-Jun-1992 -by- Petrus Wong     Modified to use the pen array and LineTo
        !           234: *  20-Nov-1991 -by- Petrus Wong
        !           235: * Wrote it.
        !           236: \**************************************************************************/
        !           237: BOOL StartMandelbrot(PINFO pInfo)
        !           238: {
        !           239:    DWORD       dwTick1;
        !           240:    HDC         hDC;
        !           241:    RECT        rc;
        !           242:    int        m, n, i, iPrev;
        !           243:    int         xCurr, yCurr;
        !           244:    int         iPen;
        !           245: 
        !           246: #ifndef THRDONE
        !           247:    INT      iNumClr;
        !           248:    char     text[256];
        !           249: #endif
        !           250: 
        !           251:    double c1, c2;
        !           252:    double x1, y1, x, y, r;
        !           253: 
        !           254:    HDC          hDCMem;
        !           255:    HBITMAP      hBitmap, hOldBitmap;
        !           256: 
        !           257:    pInfo->bMandel = TRUE;
        !           258:    pInfo->bDrawing = TRUE;
        !           259:    hDC = GetDC(pInfo->hwnd);
        !           260: 
        !           261: #ifndef THRDONE
        !           262:     if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) {
        !           263:         sprintf( gtext,"iNumClr = %d\n", iNumClr);
        !           264:         OutputDebugString( gtext);
        !           265: 
        !           266:         if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
        !           267:             MessageBox(GetFocus(), "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
        !           268:         } else {
        !           269:             if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 1, &(pInfo->hPal))) == 0)
        !           270:                 MessageBox(GetFocus(), "Failed in creating pen!", "Error", MB_OK);
        !           271:         }
        !           272:     }
        !           273: 
        !           274:    hDCMem = CreateCompatibleDC(hDC);
        !           275: 
        !           276:    if (pInfo->hPal) {
        !           277:     SelectPalette(hDCMem, pInfo->hPal, FALSE);
        !           278:     RealizePalette(hDCMem);
        !           279:    }
        !           280:    iPen = pInfo->iPen + 1;
        !           281:    wsprintf(text, "iPen = %d\n", iPen);
        !           282:    //MessageBox(GetFocus(), text, "Error", MB_OK);
        !           283: #endif
        !           284: 
        !           285:    GetClientRect(pInfo->hwnd, &rc);
        !           286: 
        !           287:    hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom);
        !           288:    hOldBitmap = SelectObject(hDCMem, hBitmap);
        !           289: 
        !           290: //#if 0
        !           291:  {
        !           292:    int iWidth, i, j;
        !           293: 
        !           294:    iWidth = (((iWidth = rc.right/iNumClr) == 0) ? 1 : iWidth);
        !           295:    sprintf( gtext,"iWidth = %d\n", iWidth);
        !           296:    OutputDebugString( gtext);
        !           297: 
        !           298:    for (i = 0; i < iNumClr; i++) {
        !           299:    //for (i = 0; i < 256; i++) {
        !           300:        //sprintf( gtext,"i mod iNumClr = %d\n", i % iNumClr);
        !           301:        //OutputDebugString( gtext);
        !           302:        if ((SelectObject(hDC, (HPEN)(pInfo->prghPen)[i % iNumClr])) == NULL) {
        !           303:             sprintf( gtext,"Select Pen failed\n");
        !           304:             OutputDebugString( gtext);
        !           305:        }
        !           306:        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iNumClr]);
        !           307:        for (j = 0; j < iWidth; j++) {
        !           308:             MoveToEx(hDC, i*iWidth+j, 0, NULL);
        !           309:             LineTo(hDC, i*iWidth+j, rc.bottom);
        !           310:             MoveToEx(hDCMem, i*iWidth+j, 0, NULL);
        !           311:             LineTo(hDCMem, i*iWidth+j, rc.bottom);
        !           312:        }
        !           313: 
        !           314:    }
        !           315:  }
        !           316: //#endif
        !           317: 
        !           318:    dwTick1 = GetTickCount();
        !           319: 
        !           320:    sprintf( gtext,"Start Drawing\n");
        !           321:    OutputDebugString( gtext);
        !           322:    yCurr = rc.top;
        !           323:    for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
        !           324:        xCurr = rc.left;                   // since LineTo excludes last point
        !           325:        MoveToEx(hDC, 0, yCurr, NULL);
        !           326:        MoveToEx(hDCMem, 0, yCurr, NULL);
        !           327:        c2 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
        !           328: 
        !           329:        for (m=rc.left; m<=rc.right; m++, xCurr++) {
        !           330:            c1 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
        !           331:           x = c1;
        !           332:           y = c2;
        !           333: 
        !           334:           for (i=1; i<=pInfo->iIteration; i++) {
        !           335:                x1 = (x - y) * (x + y) + c1;
        !           336:                y1 = 2 * x * y + c2;
        !           337:               r = x1 * x1 + y1 * y1;
        !           338:               x = x1;
        !           339:               y = y1;
        !           340:               if (r > 4.0) {
        !           341:                    break;
        !           342:                }
        !           343:            }
        !           344: 
        !           345:            if (i != iPrev) {
        !           346:                if (iPrev != FIRST_PIXEL) {
        !           347:                  switch(iPrev) {
        !           348:                    case 1: SelectObject(hDC, (HPEN)(pInfo->prghPen)[0]);
        !           349:                            SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !           350:                     break;
        !           351:                    default:
        !           352:                        if (iPrev >= pInfo->iIteration) {
        !           353:                             SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPen/3]);
        !           354:                             SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPen/3]);
        !           355:                             break;
        !           356:                        }
        !           357:                        SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
        !           358:                        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
        !           359:                        //SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPrev % iNumClr]);
        !           360:                        break;
        !           361:                  }
        !           362:                  iPrev = i;
        !           363:                  LineTo(hDC, xCurr, yCurr);
        !           364:                  LineTo(hDCMem, xCurr, yCurr);
        !           365:                }
        !           366:                else
        !           367:                  iPrev = i;    // remember the color for the first pixel
        !           368:            }
        !           369:        }
        !           370: 
        !           371:             switch(i)
        !           372:                {
        !           373:                    case 1: SelectObject(hDC, (HPEN)(pInfo->prghPen)[0]);
        !           374:                            SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
        !           375:                     break;
        !           376:                    default:
        !           377:                        if (i >= pInfo->iIteration) {
        !           378:                             SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPen/3]);
        !           379:                             SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPen/3]);
        !           380:                             break;
        !           381:                        }
        !           382:                        SelectObject(hDC, (HPEN)(pInfo->prghPen)[i % iPen]);
        !           383:                        SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]);
        !           384:                        //SelectObject(hDC, (HPEN)(pInfo->prghPen)[i % iNumClr]);
        !           385:                        break;
        !           386:                }
        !           387: 
        !           388:                 LineTo(hDC,xCurr,yCurr);
        !           389:                  LineTo(hDCMem,xCurr,yCurr);
        !           390: 
        !           391:    }
        !           392: 
        !           393: 
        !           394: 
        !           395:    pInfo->dwElapsed = GetTickCount() - dwTick1;
        !           396: 
        !           397:    if (pInfo->hBmpSaved)
        !           398:        DeleteObject(pInfo->hBmpSaved);
        !           399: 
        !           400:    pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap);
        !           401:    pInfo->bDrawing = FALSE;
        !           402:    SaveBitmapFile(hDC, pInfo->hBmpSaved, pInfo->szSavef);
        !           403:    pInfo->bClrCycle = TRUE;
        !           404:    if (pInfo->hPal)
        !           405:       bColorCycle(hDC, pInfo);
        !           406:    ReleaseDC(pInfo->hwnd, hDC);
        !           407: 
        !           408: #ifndef THRDONE
        !           409:    if (pInfo->prghPen != NULL) {
        !           410:        for (i = 0; i <= pInfo->iPen; i++) {
        !           411:            DeleteObject((HPEN) (pInfo->prghPen)[i]);
        !           412:        }
        !           413:        GlobalFree(pInfo->prghPen);
        !           414:    }
        !           415: #endif
        !           416: 
        !           417:    DeleteDC(hDCMem);
        !           418: 
        !           419:    ExitThread(0);
        !           420:    if (!CloseHandle(pInfo->hThrd))
        !           421:        MessageBox(GetFocus(), "Failed in CloseHandle!", "Error", MB_OK);
        !           422: 
        !           423:    return TRUE;
        !           424: }
        !           425: 
        !           426: 
        !           427: /******************************Public*Routine******************************\
        !           428: *
        !           429: * iCreatePenFrPal
        !           430: *
        !           431: * Effects: Create an array of pens from palette.
        !           432: *          If device supports palette, then first creates a logical palette
        !           433: *          with a good spread of color. Then select the logical palette into
        !           434: *          the DC. Create pen that corresponds to each palette entry.
        !           435: *          If system does not support palette, then use the system palette.
        !           436: *
        !           437: *          prghPen pointer to an array of hPen
        !           438: *                  If this is NULL, the required size of the array is
        !           439: *                  returned. If this is not NULL, the array will be filled
        !           440: *                  with hPens.
        !           441: *
        !           442: *          returns the number of hPens created.
        !           443: *
        !           444: * Warnings:
        !           445: *
        !           446: * History:
        !           447: *  13-Jun-1992 -by- Petrus Wong
        !           448: * Wrote it.
        !           449: \**************************************************************************/
        !           450: 
        !           451: INT iCreatePenFrPal(HDC hDC, PVOID *prghPen, INT iWidth, HPALETTE *phPal)
        !           452: {
        !           453:     INT             iNumClr, iResult, i, iEntry;
        !           454:     PLOGPALETTE     plogPat;
        !           455:     ULONG           ulSize;
        !           456: 
        !           457:     iResult = 0;
        !           458: 
        !           459:     if (!((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE)) {
        !           460: 
        !           461:         if (iNumClr = GetSystemPaletteEntries(hDC, 0, 0, NULL)) {
        !           462:             if (prghPen == NULL) {
        !           463:                 return (iNumClr);
        !           464:             }
        !           465: 
        !           466:             if (iWidth < 0) {
        !           467:                 MessageBox(GetFocus(), "Invalid pen width!", "Error", MB_OK);
        !           468:                 return 0L;
        !           469:             }
        !           470: 
        !           471:             for (i = 0; i < iNumClr; i++) {
        !           472:                 prghPen[i] =
        !           473:                      (PVOID) CreatePen(PS_SOLID, iWidth, PALETTEINDEX(i));
        !           474:                 iResult = i;
        !           475: #if 0
        !           476:                 SelectObject(hDC, (HPEN)prghPen[i]);
        !           477:                 MoveToEx(hDC, i*iWidth, 0, NULL);
        !           478:                 LineTo(hDC, i*iWidth, 300);
        !           479: #endif
        !           480:             }
        !           481:             return iResult;
        !           482:         }
        !           483: 
        !           484:         // GetPaletteEntries returns 0
        !           485:         iNumClr = 1 << GetDeviceCaps(hDC, BITSPIXEL);
        !           486: 
        !           487:         if (iNumClr <= 16) {
        !           488:             sprintf( gtext,"Assertion failed: iCreatePenFrPal() \n");
        !           489:             OutputDebugString( gtext);
        !           490:             sprintf( gtext,"iNumClr <= 16! iNumClr = %d\n", iNumClr);
        !           491:             OutputDebugString( gtext);
        !           492:             return (iNumClr);
        !           493:         }
        !           494: 
        !           495:         // Assuming at least 16 bit device
        !           496:         //
        !           497:         iNumClr = 768;      // COLORREF format: 0x00bbggrr r,g,b=[0,255]
        !           498: 
        !           499:         if (prghPen == NULL) {
        !           500:             return (iNumClr);
        !           501:         }
        !           502: 
        !           503:         if (iWidth < 0) {
        !           504:             MessageBox(GetFocus(), "Invalid pen width!", "Error", MB_OK);
        !           505:             return 0L;
        !           506:         }
        !           507: 
        !           508:         for (i = 0; i < iNumClr; i++) {
        !           509:             if (i < 256) {
        !           510:                 prghPen[i] =
        !           511:                     (PVOID) CreatePen(PS_SOLID, iWidth, RGB(i,0,255-i));
        !           512:                 iResult = i;
        !           513: #if 0
        !           514:                 SelectObject(hDC, (HPEN)prghPen[i]);
        !           515:                 MoveToEx(hDC, i*iWidth, 0, NULL);
        !           516:                 LineTo(hDC, i*iWidth, 300);
        !           517: #endif
        !           518:                 continue;
        !           519:             }
        !           520: 
        !           521:             if (i < 512) {
        !           522:                 prghPen[i] =
        !           523:                     (PVOID) CreatePen(PS_SOLID, iWidth, RGB(511-i,i-256,0));
        !           524:                 iResult = i;
        !           525: #if 0
        !           526:                 SelectObject(hDC, (HPEN)prghPen[i]);
        !           527:                 MoveToEx(hDC, i*iWidth, 0, NULL);
        !           528:                 LineTo(hDC, i*iWidth, 300);
        !           529: #endif
        !           530:                 continue;
        !           531:             }
        !           532: 
        !           533: 
        !           534:             prghPen[i] =
        !           535:                 (PVOID) CreatePen(PS_SOLID, iWidth, RGB(0,767-i,i-512));
        !           536:             iResult = i;
        !           537: #if 0
        !           538:             SelectObject(hDC, (HPEN)prghPen[i]);
        !           539:             MoveToEx(hDC, i*iWidth, 0, NULL);
        !           540:             LineTo(hDC, i*iWidth, 300);
        !           541: #endif
        !           542:         }
        !           543: 
        !           544:         return iResult;
        !           545:     }
        !           546: 
        !           547:     //
        !           548:     // Palette managed device
        !           549:     //
        !           550:     iEntry = iNumClr = 1 << GetDeviceCaps(hDC, BITSPIXEL);
        !           551: 
        !           552:     if (iNumClr > 256) {
        !           553:         sprintf( gtext,"Assertion failed: iCreatePenFrPal() \n");
        !           554:         OutputDebugString( gtext);
        !           555:         sprintf( gtext,"iNumClr > 256! iNumClr = %d\n", iNumClr);
        !           556:         OutputDebugString( gtext);
        !           557:         iEntry=iNumClr = 256;
        !           558:     }
        !           559: 
        !           560:     ulSize = sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*iNumClr;
        !           561: 
        !           562:     iNumClr -= GetDeviceCaps(hDC, NUMRESERVED);
        !           563: 
        !           564:     if (prghPen == NULL)
        !           565:         return iNumClr;
        !           566: 
        !           567:     if ((plogPat = (PLOGPALETTE) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, ulSize)) == NULL) {
        !           568:         MessageBox(GetFocus(), "Failed in Memory Allocation for plogPat!", "Error", MB_OK);
        !           569:         goto ErrExit1;
        !           570:     }
        !           571: 
        !           572:     plogPat->palVersion = 0x300;
        !           573:     plogPat->palNumEntries = (WORD) iEntry;
        !           574: 
        !           575:     {
        !           576:     int     iFirst, iSecond, iInc;
        !           577: 
        !           578:         iFirst = iNumClr/3;
        !           579:         iSecond = iFirst * 2;
        !           580:         iInc = (iNumClr <= 256) ? 3 : 1;
        !           581: 
        !           582: 
        !           583:         for (i = 0; i < iNumClr; i++) {
        !           584:             if (i < iFirst) {
        !           585:                 plogPat->palPalEntry[i+10].peBlue   = 255-(i+1)*iInc;
        !           586:                 plogPat->palPalEntry[i+10].peGreen  = 0;
        !           587:                 plogPat->palPalEntry[i+10].peRed    = (i+1)*iInc;
        !           588:                 plogPat->palPalEntry[i+10].peFlags  = PC_RESERVED;
        !           589:                 continue;
        !           590:             }
        !           591:             if (i < iSecond) {
        !           592:                 plogPat->palPalEntry[i+10].peBlue   = 0;
        !           593:                 plogPat->palPalEntry[i+10].peGreen  = (i+1-iFirst)*iInc;
        !           594:                 plogPat->palPalEntry[i+10].peRed    = 255-(i+1-iFirst)*iInc;
        !           595:                 plogPat->palPalEntry[i+10].peFlags  = PC_RESERVED;
        !           596:                 continue;
        !           597:             }
        !           598:             plogPat->palPalEntry[i+10].peBlue   = (i+1-iSecond)*iInc;
        !           599:             plogPat->palPalEntry[i+10].peGreen  = 255-(i+1-iSecond)*iInc;
        !           600:             plogPat->palPalEntry[i+10].peRed    = 0;
        !           601:             plogPat->palPalEntry[i+10].peFlags  = PC_RESERVED;
        !           602:         }
        !           603:     }
        !           604: 
        !           605:     DeleteObject(*phPal);
        !           606: 
        !           607:     if ((*phPal = CreatePalette(plogPat)) == (HPALETTE) NULL) {
        !           608:         MessageBox(GetFocus(), "Failed in creating palette!", "Error", MB_OK);
        !           609:         goto ErrExit2;
        !           610:     }
        !           611:     if (*phPal) {
        !           612:        SelectPalette(hDC, *phPal, FALSE);
        !           613:        RealizePalette(hDC);
        !           614:     }
        !           615: 
        !           616:     for (i = 0; i < iNumClr; i++) {
        !           617:         HPEN    hPen;
        !           618: 
        !           619:         hPen = CreatePen(PS_SOLID, iWidth, PALETTEINDEX(i+10));
        !           620:         prghPen[i] = (PVOID) hPen;
        !           621:         iResult = i;
        !           622: #if 0
        !           623:         SelectObject(hDC, hPen);
        !           624:         MoveToEx(hDC, i*iWidth, 0, NULL);
        !           625:         LineTo(hDC, i*iWidth, 300);
        !           626: #endif
        !           627:     }
        !           628: 
        !           629: ErrExit2:
        !           630:     GlobalFree(plogPat);
        !           631: ErrExit1:
        !           632:     return iResult;
        !           633: 
        !           634: }
        !           635: 
        !           636: /******************************Public*Routine******************************\
        !           637: *
        !           638: * bInitInfo
        !           639: *
        !           640: * Effects: Initialize the Info data structure
        !           641: *
        !           642: * Warnings:
        !           643: *
        !           644: * History:
        !           645: *  19-Dec-1992      Petrus Wong         Retrieve setup info fr control.ini
        !           646: *  14-Dec-1992 -by- Petrus Wong         Added Rle and pens stuff
        !           647: *  28-Jan-1992 -by- Petrus Wong
        !           648: * Wrote it.
        !           649: \**************************************************************************/
        !           650: 
        !           651: BOOL bInitInfo(PINFO pInfo)
        !           652: {
        !           653:     char    szXFr[MAXDOUBLELEN], szYFr[MAXDOUBLELEN], szX2[MAXDOUBLELEN],
        !           654:             szY2[MAXDOUBLELEN], szSavef[MAXPATHLEN], szIter[MAXDOUBLELEN];
        !           655: 
        !           656:     bGetPPStr(szXFr, szYFr, szX2, szY2, szSavef, szIter);
        !           657:     pInfo->xFrom        = atof(szXFr);
        !           658:     pInfo->xTo          = atof(szX2);
        !           659:     pInfo->yFrom        = atof(szYFr);
        !           660:     pInfo->yTo          = atof(szY2);
        !           661:     pInfo->lxFrom       = -4096;                // 20.11 fix point
        !           662:     pInfo->lxTo         = 4096;                 // representation of
        !           663:     pInfo->lyFrom       = 4096;                 // -2, 2, 2, and -2
        !           664:     pInfo->lyTo         = -4096;                //
        !           665:     pInfo->iIteration   = (INT) atof(szIter);
        !           666:     pInfo->iStep        = gStep;
        !           667:     pInfo->bStretch     = gbStretch;
        !           668:     pInfo->iStretchMode = giStretchMode;
        !           669:     pInfo->hwnd         = NULL;
        !           670:     pInfo->hThrd        = NULL;
        !           671:     pInfo->bDrawing     = FALSE;
        !           672:     pInfo->dwThreadId   = 0;
        !           673:     pInfo->dwElapsed    = 0L;
        !           674:     pInfo->c1           = 0.0;
        !           675:     pInfo->c2           = 0.0;
        !           676:     pInfo->lc1          = 0L;
        !           677:     pInfo->lc2          = 0L;
        !           678:     pInfo->hBmpSaved    = NULL;
        !           679:     pInfo->bMandel      = TRUE;
        !           680:     pInfo->bSetDIBsToDevice = FALSE;
        !           681:     pInfo->hPal         = NULL;
        !           682:     pInfo->prghPen      = NULL;
        !           683:     pInfo->iPen         = 0;
        !           684:     pInfo->bClrCycle    = FALSE;
        !           685:     wsprintf((LPSTR) &(pInfo->szSavef), szSavef);
        !           686:     return TRUE;
        !           687: }
        !           688: 
        !           689: 
        !           690: 
        !           691: 
        !           692: /******************************Public*Routine******************************\
        !           693: *
        !           694: * vLoadStrings
        !           695: *
        !           696: * Effects: Load strings from resource
        !           697: *
        !           698: * Warnings:
        !           699: *
        !           700: * History:
        !           701: *  19-Dec-1992 -by- Petrus Wong
        !           702: * Wrote it.
        !           703: \**************************************************************************/
        !           704: 
        !           705: void vLoadStrings(VOID)
        !           706: {
        !           707:     LoadString(hMainInstance, idsAppName, szAppName, APPNAMEBUFFERLEN);
        !           708:     LoadString(hMainInstance, idsName, szName, TITLEBARNAMELEN);
        !           709:     LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);
        !           710:     LoadString(hMainInstance, idsScreenSaver, szScreenSaver, 22);
        !           711:     LoadString(hMainInstance, idsHelpFile, szHelpFile, MAXFILELEN);
        !           712:     LoadString(hMainInstance, idsNoHelpMemory, szNoHelpMemory, BUFFLEN);
        !           713:     LoadString(hMainInstance, idsXFrom, szXFrom, MAXDOUBLELEN);
        !           714:     LoadString(hMainInstance, idsYFrom, szYFrom, MAXDOUBLELEN);
        !           715:     LoadString(hMainInstance, idsXTo, szXTo, MAXDOUBLELEN);
        !           716:     LoadString(hMainInstance, idsYTo, szYTo, MAXDOUBLELEN);
        !           717:     LoadString(hMainInstance, idsSaveAs, szSaveFile, MAXPATHLEN);
        !           718:     LoadString(hMainInstance, idsIteration, szIteration, MAXDOUBLELEN);
        !           719: }
        !           720: 
        !           721: 
        !           722: 
        !           723: /******************************Public*Routine******************************\
        !           724: * SaveBitmapFile
        !           725: *
        !           726: *
        !           727: * Effects: Save pInfo->hBmpSaved into disk specified by pszFileName
        !           728: *
        !           729: * Warnings: assumes hBmpSaved is not selected into window's DC other than
        !           730: *           pInfo->hwnd's DC
        !           731: *
        !           732: * History:
        !           733: *  14-Jan-1992 -by- Petrus Wong
        !           734: * Wrote it.
        !           735: \**************************************************************************/
        !           736: 
        !           737: BOOL SaveBitmapFile(HDC hDC, HBITMAP hBmp, PSTR pszFileName)
        !           738: {
        !           739:     int         hFile;
        !           740:     OFSTRUCT    ofReOpenBuff;
        !           741:     HBITMAP     hTmpBmp, hBmpOld;
        !           742:     BOOL        bSuccess;
        !           743:     BITMAPFILEHEADER    bfh;
        !           744:     PBITMAPINFO pbmi;
        !           745:     PBYTE       pBits;
        !           746:     BITMAPINFO  bmi;
        !           747:     PBYTE pjTmp, pjTmpBmi;
        !           748:     ULONG sizBMI;
        !           749: 
        !           750: 
        !           751:     bSuccess = TRUE;
        !           752:     if (!hBmp) {
        !           753:         MessageBox(GetFocus(), "There's no Bitmap to save!", "Error", MB_OK);
        !           754:         return FALSE;
        !           755:     }
        !           756: 
        !           757:     //
        !           758:     // Let the graphics engine to retrieve the dimension of the bitmap for us
        !           759:     // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO
        !           760:     // if BitCount != 0, color table will be retrieved
        !           761:     //
        !           762:     bmi.bmiHeader.biSize = 0x28;              // GDI need this to work
        !           763:     bmi.bmiHeader.biBitCount = 0;             // don't get the color table
        !           764:     if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, &bmi, DIB_RGB_COLORS)) == 0) {
        !           765:         MessageBox(GetFocus(), "GetDIBits failed!", "Error", MB_OK);
        !           766:         return FALSE;
        !           767:     }
        !           768: 
        !           769:     //
        !           770:     // Now that we know the size of the image, alloc enough memory to retrieve
        !           771:     // the actual bits
        !           772:     //
        !           773:     if ((pBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
        !           774:                 bmi.bmiHeader.biSizeImage)) == NULL) {
        !           775:         MessageBox(GetFocus(), "Failed in Memory Allocation for pBits!", "Error", MB_OK);
        !           776:         return FALSE;
        !           777:     }
        !           778: 
        !           779:     //
        !           780:     // Note: 24 bits per pixel has no color table.  So, we don't have to
        !           781:     // allocate memory for retrieving that.  Otherwise, we do.
        !           782:     //
        !           783:     pbmi = &bmi;                                      // assume no color table
        !           784:     if (bmi.bmiHeader.biBitCount != 24) {             // has color table
        !           785:         sizBMI = sizeof(BITMAPINFO)+sizeof(RGBQUAD)*(1<<bmi.bmiHeader.biBitCount);
        !           786:         //
        !           787:         // I need more memory for the color table
        !           788:         //
        !           789:         if ((pbmi = (PBITMAPINFO)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizBMI )) == NULL) {
        !           790:             MessageBox(GetFocus(), "Failed in Memory Allocation for pbmi!", "Error", MB_OK);
        !           791:             bSuccess = FALSE;
        !           792:             goto ErrExit1;
        !           793:         }
        !           794:         //
        !           795:         // Now that we've a bigger chunk of memory, let's copy the Bitmap
        !           796:         // info header data over
        !           797:         //
        !           798:         pjTmp = (PBYTE)pbmi;
        !           799:         pjTmpBmi = (PBYTE)&bmi;
        !           800:         sizBMI = sizeof(BITMAPINFOHEADER);
        !           801: 
        !           802:         while(sizBMI--)
        !           803:         {
        !           804:             *(((PBYTE)pjTmp)++) = *((pjTmpBmi)++);
        !           805:         }
        !           806: 
        !           807:     }
        !           808: 
        !           809:     //
        !           810:     // Let's open the file and get ready for writing
        !           811:     //
        !           812:     if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff,
        !           813:                  OF_CREATE | OF_WRITE)) == -1) {
        !           814:         MessageBox(GetFocus(), "Failed in OpenFile!", "Error", MB_OK);
        !           815:         ErrorOut("OpenFile");
        !           816:         goto ErrExit2;
        !           817:     }
        !           818: 
        !           819:     //
        !           820:     // But first, fill in the info for the BitmapFileHeader
        !           821:     //
        !           822:     bfh.bfType = 0x4D42;                            // 'BM'
        !           823:     bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*
        !           824:         ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount))+
        !           825:         pbmi->bmiHeader.biSizeImage;
        !           826:     bfh.bfReserved1 =
        !           827:     bfh.bfReserved2 = 0;
        !           828:     bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
        !           829:         sizeof(RGBQUAD)*((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount));
        !           830: 
        !           831:     //
        !           832:     // Write out the file header now
        !           833:     //
        !           834:     if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) {
        !           835:         MessageBox(GetFocus(), "Failed in WriteFile!", "Error", MB_OK);
        !           836:         bSuccess = FALSE;
        !           837:         goto ErrExit3;
        !           838:     }
        !           839: 
        !           840:     //
        !           841:     // Bitmap can't be selected into a DC when calling GetDIBits
        !           842:     // Assume that the hDC is the DC where the bitmap would have been selected
        !           843:     // if indeed it has been selected
        !           844:     //
        !           845:     if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) {
        !           846:         hBmpOld = SelectObject(hDC, hTmpBmp);
        !           847:         if ((GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)pBits, pbmi, DIB_RGB_COLORS))==0){
        !           848:             MessageBox(GetFocus(), "Failed in GetDIBits!", "Error", MB_OK);
        !           849:             bSuccess = FALSE;
        !           850:             goto ErrExit4;
        !           851:         }
        !           852:     } else {
        !           853:         MessageBox(GetFocus(), "Failed in creating bitmap!", "Error", MB_OK);
        !           854:         bSuccess = FALSE;
        !           855:         goto ErrExit3;
        !           856:     }
        !           857: 
        !           858:     //
        !           859:     // Now write out the BitmapInfoHeader and color table, if any
        !           860:     //
        !           861:     if (_lwrite(hFile, (LPSTR)pbmi, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *
        !           862:         ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1 << pbmi->bmiHeader.biBitCount))) == -1) {
        !           863:         MessageBox(GetFocus(), "Failed in WriteFile!", "Error", MB_OK);
        !           864:         bSuccess = FALSE;
        !           865:         goto ErrExit4;
        !           866:     }
        !           867: 
        !           868:     //
        !           869:     // write the bits also
        !           870:     //
        !           871:     if (_lwrite(hFile, (LPSTR)pBits, pbmi->bmiHeader.biSizeImage) == -1) {
        !           872:         MessageBox(GetFocus(), "Failed in WriteFile!", "Error", MB_OK);
        !           873:         bSuccess = FALSE;
        !           874:         goto ErrExit4;
        !           875:     }
        !           876: 
        !           877: 
        !           878: ErrExit4:
        !           879:     SelectObject(hDC, hBmpOld);
        !           880:     DeleteObject(hTmpBmp);
        !           881: ErrExit3:
        !           882:     _lclose(hFile);
        !           883: ErrExit2:
        !           884:     GlobalFree(pbmi);
        !           885: ErrExit1:
        !           886:     GlobalFree(pBits);
        !           887:     return bSuccess;
        !           888: }
        !           889: 
        !           890: /************************************************************************
        !           891:  * void ErrorOut(char errstring[30])
        !           892:  *
        !           893:  * Purpose: Print out an meainful error code by means of
        !           894:  *       GetLastError and printf
        !           895:  *
        !           896:  * Inputs:  errstring - the action that failed, passed by the
        !           897:  *                   calling proc.
        !           898:  *
        !           899:  * Returns: none
        !           900:  *
        !           901:  * Calls:   GetLastError
        !           902:  *
        !           903:  * History:
        !           904:  *
        !           905: \************************************************************************/
        !           906: 
        !           907: 
        !           908: void ErrorOut(char errstring[30])
        !           909: {
        !           910: DWORD Error;
        !           911: CHAR  str[80];
        !           912: 
        !           913: Error= GetLastError();
        !           914: wsprintf((LPSTR) str, "Error on %s = %d\n", errstring, Error);
        !           915: MessageBox(GetFocus(), (LPSTR)str, "Error", MB_OK);
        !           916: }
        !           917: 
        !           918: BOOL bInitDlgItems(HWND hDlg)
        !           919: {
        !           920:     char    szXFr[MAXDOUBLELEN], szYFr[MAXDOUBLELEN], szX2[MAXDOUBLELEN],
        !           921:             szY2[MAXDOUBLELEN], szSavef[MAXPATHLEN], szIter[MAXDOUBLELEN];
        !           922:     BOOL    bSuccess;
        !           923: 
        !           924:     bSuccess = bGetPPStr(szXFr, szYFr, szX2, szY2, szSavef, szIter);
        !           925:     SetDlgItemText(hDlg, ID_XFROM, szXFr);
        !           926:     SetDlgItemText(hDlg, ID_YFROM, szYFr);
        !           927:     SetDlgItemText(hDlg, ID_XTO, szX2);
        !           928:     SetDlgItemText(hDlg, ID_YTO, szY2);
        !           929:     SetDlgItemText(hDlg, ID_ITERATION, szIter);
        !           930: 
        !           931:     return bSuccess;
        !           932: }
        !           933: 
        !           934: 
        !           935: /******************************Public*Routine******************************\
        !           936: *
        !           937: * bGetPPStr
        !           938: *
        !           939: * Effects: GetPrivateProfileString from control.ini
        !           940: *
        !           941: * Warnings:
        !           942: *
        !           943: * History:
        !           944: *  19-Dec-1992 -by- Petrus Wong
        !           945: * Wrote it.
        !           946: \**************************************************************************/
        !           947: 
        !           948: BOOL bGetPPStr(char szXFr[MAXDOUBLELEN], char szYFr[MAXDOUBLELEN],
        !           949:                char szX2[MAXDOUBLELEN],  char szY2[MAXDOUBLELEN],
        !           950:                char szSavef[MAXPATHLEN], char szIter[MAXDOUBLELEN])
        !           951: {
        !           952:     char    szDefXFr[MAXDOUBLELEN];
        !           953:     char    szDefYFr[MAXDOUBLELEN];
        !           954:     char    szDefX2[MAXDOUBLELEN];
        !           955:     char    szDefY2[MAXDOUBLELEN];
        !           956:     char    szDefSavef[MAXPATHLEN];
        !           957:     char    szDefIter[MAXDOUBLELEN];
        !           958: 
        !           959:     sprintf(szDefXFr, "-2.00");
        !           960:     sprintf(szDefYFr, "1.00");
        !           961:     sprintf(szDefX2,  "1.00");
        !           962:     sprintf(szDefY2,  "-1.00");
        !           963:     sprintf(szDefSavef, "c:\\fractal.bmp");
        !           964:     sprintf(szDefIter, "500");
        !           965:     GetPrivateProfileString(szAppName, szXFrom, szDefXFr, szXFr, MAXDOUBLELEN, szIniFile);
        !           966:     GetPrivateProfileString(szAppName, szYFrom, szDefYFr, szYFr, MAXDOUBLELEN, szIniFile);
        !           967:     GetPrivateProfileString(szAppName, szXTo, szDefX2, szX2, MAXDOUBLELEN, szIniFile);
        !           968:     GetPrivateProfileString(szAppName, szYTo, szDefY2, szY2, MAXDOUBLELEN, szIniFile);
        !           969:     GetPrivateProfileString(szAppName, szSaveFile, szDefSavef, szSavef, MAXPATHLEN, szIniFile);
        !           970:     GetPrivateProfileString(szAppName, szIteration, szDefIter, szIter, MAXDOUBLELEN, szIniFile);
        !           971:     return TRUE;
        !           972: }
        !           973: 
        !           974: 
        !           975: 
        !           976: /******************************Public*Routine******************************\
        !           977: *
        !           978: * bColorCycle
        !           979: *
        !           980: * Effects:  Create a logical palette with a good spread of color
        !           981: *           Animate the palette, shift the palette entries and animate
        !           982: *           again for 256 times altogether.
        !           983: *           This creates the color cycling effect.
        !           984: *
        !           985: * Warnings: Only works in device that support palette.
        !           986: *
        !           987: * History:
        !           988: *  15-Jan-1993      Petrus Wong     Adaped from the SDK Mandel sample
        !           989: *  24-Apr-1992 -by- Petrus Wong
        !           990: * Wrote it.
        !           991: \**************************************************************************/
        !           992: 
        !           993: BOOL bColorCycle(HDC hDC, PINFO pInfo)
        !           994: {
        !           995:     INT             iEntry, i, iNumClr;
        !           996:     PLOGPALETTE     plogPat;
        !           997:     ULONG           ulSize;
        !           998:     BOOL            bSuccess;
        !           999:     HPALETTE        hPal, hPalOld;
        !          1000:     PALETTEENTRY    peTemp;
        !          1001:     BOOL            bQuit;
        !          1002: 
        !          1003: 
        !          1004: UINT uRC;
        !          1005: 
        !          1006:     bSuccess = TRUE;
        !          1007:     iEntry = 1<<GetDeviceCaps(hDC, BITSPIXEL);
        !          1008:     iNumClr = 236;          // 256 minus 20 reserved colors
        !          1009:     ulSize = sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256;
        !          1010: 
        !          1011:     if ((plogPat = (PLOGPALETTE) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, ulSize)) == NULL) {
        !          1012:         MessageBox(hMainWindow, "Failed in Memory Allocation for plogPat!", "Error", MB_OK);
        !          1013:         bSuccess = FALSE;
        !          1014:         goto ErrExit1;
        !          1015:     }
        !          1016: 
        !          1017:     plogPat->palVersion = 0x300;
        !          1018:     plogPat->palNumEntries = (WORD) 256;
        !          1019:     {
        !          1020:     int     iFirst, iSecond, iInc;
        !          1021: 
        !          1022:         iFirst = iNumClr/3;
        !          1023:         iSecond = iFirst * 2;
        !          1024:         iInc = (iNumClr <= 256) ? 3 : 1;
        !          1025: 
        !          1026:         for (i = 0; i < iNumClr; i++) {
        !          1027:             if (i < iFirst) {
        !          1028:                 plogPat->palPalEntry[i+10].peBlue   = 255-(i+1)*iInc;
        !          1029:                 plogPat->palPalEntry[i+10].peGreen  = 0;
        !          1030:                 plogPat->palPalEntry[i+10].peRed    = (i+1)*iInc;
        !          1031:                 plogPat->palPalEntry[i+10].peFlags  = PC_RESERVED;
        !          1032:                 continue;
        !          1033:             }
        !          1034:             if (i < iSecond) {
        !          1035:                 plogPat->palPalEntry[i+10].peBlue   = 0;
        !          1036:                 plogPat->palPalEntry[i+10].peGreen  = (i+1-iFirst)*iInc;
        !          1037:                 plogPat->palPalEntry[i+10].peRed    = 255-(i+1-iFirst)*iInc;
        !          1038:                 plogPat->palPalEntry[i+10].peFlags  = PC_RESERVED;
        !          1039:                 continue;
        !          1040:             }
        !          1041:             plogPat->palPalEntry[i+10].peBlue   = (i+1-iSecond)*iInc;
        !          1042:             plogPat->palPalEntry[i+10].peGreen  = 255-(i+1-iSecond)*iInc;
        !          1043:             plogPat->palPalEntry[i+10].peRed    = 0;
        !          1044:             plogPat->palPalEntry[i+10].peFlags  = PC_RESERVED;
        !          1045:         }
        !          1046:     }
        !          1047: 
        !          1048:     if ((hPal = CreatePalette(plogPat)) == (HPALETTE) NULL) {
        !          1049:         MessageBox(hMainWindow, "Failed in creating palette!", "Error", MB_OK);
        !          1050:         bSuccess = FALSE;
        !          1051:         goto ErrExit2;
        !          1052:     }
        !          1053: 
        !          1054:     hPalOld = SelectPalette(hDC, hPal, FALSE);
        !          1055:     RealizePalette(hDC);
        !          1056:     //SelectPalette(hDC, hPalOld, FALSE);
        !          1057: 
        !          1058:     bQuit = FALSE;
        !          1059:     while (TRUE && !bQuit) {
        !          1060:         if (!pInfo->bClrCycle) {
        !          1061:             //sprintf( gtext,"NOT to animate palette\n");
        !          1062:             //OutputDebugString( gtext );
        !          1063:             bQuit = TRUE;
        !          1064:         }
        !          1065: 
        !          1066:         if (!bQuit) {
        !          1067:             //sprintf( gtext,"About to animate palette\n");
        !          1068:             //OutputDebugString( gtext );
        !          1069: 
        !          1070: 
        !          1071:             peTemp = plogPat->palPalEntry[10];
        !          1072:             for (i = 0; i < iNumClr; i++) {
        !          1073:                 plogPat->palPalEntry[i+10] = plogPat->palPalEntry[i+10+1];
        !          1074:             }
        !          1075:             plogPat->palPalEntry[i+10] = peTemp;
        !          1076: 
        !          1077:             Sleep(25);
        !          1078: 
        !          1079:             if (!AnimatePalette(hPal, 0, 256, plogPat->palPalEntry)) {
        !          1080:                 sprintf( gtext,"Anmiate palette failed\n");
        !          1081:                 OutputDebugString( gtext );
        !          1082:             }
        !          1083: 
        !          1084:             if ((uRC = RealizePalette(hDC)) == -1) {
        !          1085:                 sprintf( gtext,"Realize palette failed\n");
        !          1086:                 OutputDebugString( gtext );
        !          1087:             }
        !          1088: 
        !          1089:             if (!UpdateColors(hDC)) {
        !          1090:                 sprintf( gtext,"Update Colors failed\n");
        !          1091:                 OutputDebugString( gtext );
        !          1092:             }
        !          1093: 
        !          1094:         }
        !          1095: 
        !          1096:     }
        !          1097: 
        !          1098:     SelectPalette(hDC, hPalOld, 0);
        !          1099:     DeleteObject(hPal);
        !          1100: ErrExit2:
        !          1101:     GlobalFree(plogPat);
        !          1102: ErrExit1:
        !          1103:     return bSuccess;
        !          1104: 
        !          1105: }

unix.superglobalmegacorp.com

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