home *** CD-ROM | disk | FTP | other *** search
/ Computerworld 1996 March / Computerworld_1996-03_cd.bin / idg_cd3 / grafika / fraktaly / bmand11 / mand.c < prev    next >
C/C++ Source or Header  |  1996-02-14  |  34KB  |  1,063 lines

  1. /***********************************************
  2.  *  Mand.C - jcb - started on: 8/21/94         *
  3.  *                                             *
  4.  *   -----Bare's Mandelbrot Program-----       *
  5.  *                                             *
  6.  *   Draws the Mandelbrot Set.                 *
  7.  *                                             *
  8.  ***********************************************/
  9.  
  10. #include <windows.h>
  11. #include <math.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <time.h>
  15. #include "mand.h"
  16. #include <stdio.h>
  17. #include <mem.h>
  18.  
  19. #define PALETTESIZE 256
  20. #define HDIB HANDLE
  21. #define HPAL HANDLE
  22. #define VerInfo "1.1"
  23.  
  24. LONG FAR PASCAL _export WndProc(HWND,UINT,WPARAM,LPARAM);
  25. BOOL FAR PASCAL _export AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
  26. BOOL FAR PASCAL _export OptionsDlgProc(HWND,UINT,WPARAM,LPARAM);
  27.  
  28. // Global Variables:
  29. char szProgName[] = "MandProg";
  30. char szIconName[] = "MandIcon";
  31. char szMenuName[] = "Menu";
  32. HDIB hMandelbrotDIB;
  33. int Do=0;
  34. long int BytesPerLine;
  35.  
  36. char szBuffer[256];
  37. unsigned int iMaxDel=256;
  38. double topMand,botMand,leftMand,rightMand;
  39. HINSTANCE hInstance;
  40.  
  41. /***********************************************
  42.  *  DIB functions                              *
  43.  *                                             *
  44.  *   Functions that manipulate windows Device  *
  45.  *   Independent Bitmaps.                      *
  46.  *                                             *
  47.  ***********************************************/
  48. HDIB CreateDIB(int x, int y) {
  49.     long int MemBlockSize;
  50.     HANDLE hlocBmi;
  51.     HDIB hDib;
  52.     LPBITMAPINFO lpbmi, lpbmiMyDIB;
  53.  
  54.     hlocBmi = LocalAlloc(LHND | LMEM_ZEROINIT,
  55.                                     sizeof(BITMAPINFOHEADER)
  56.                                  + sizeof(RGBQUAD)*256);
  57.     lpbmi = (LPBITMAPINFO)LocalLock(hlocBmi);
  58.     lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  59.     lpbmi->bmiHeader.biWidth = x;
  60.     lpbmi->bmiHeader.biHeight = y;
  61.     lpbmi->bmiHeader.biPlanes = 1;
  62.     lpbmi->bmiHeader.biBitCount = 8;
  63.     lpbmi->bmiHeader.biCompression = BI_RGB;
  64.     lpbmi->bmiHeader.biSizeImage = (LONG)
  65.         ((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biBitCount + 31) / 32 * 4)
  66.         * lpbmi->bmiHeader.biHeight;
  67.     lpbmi->bmiHeader.biXPelsPerMeter = 0;
  68.     lpbmi->bmiHeader.biYPelsPerMeter = 0;
  69.     lpbmi->bmiHeader.biClrUsed = 256;
  70.     lpbmi->bmiHeader.biClrImportant = 256;
  71.  
  72.     BytesPerLine = (LONG)((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biBitCount + 31) / 32 * 4);
  73.  
  74.     MemBlockSize = sizeof(BITMAPINFOHEADER)
  75.                     + sizeof(RGBQUAD)*lpbmi->bmiHeader.biClrUsed
  76.                     + lpbmi->bmiHeader.biSizeImage;
  77.     if (MemBlockSize%65536!=0)
  78.         MemBlockSize = ((MemBlockSize+65536) / 65536 ) * 65536;
  79.  
  80.     hDib = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE, MemBlockSize);
  81.  
  82.     if (hDib == NULL)
  83.         MessageBox(NULL,"GlobalAlloc Failed.","DEBUG", MB_OK);
  84.     lpbmiMyDIB = (LPBITMAPINFO)GlobalLock(hDib);
  85.     if (lpbmiMyDIB == NULL)
  86.         MessageBox(NULL,"Can't Lock hDib. (createDIB)","DEBUG", MB_OK);
  87.     memcpy(lpbmiMyDIB,lpbmi,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD));
  88.     LocalUnlock(hlocBmi);
  89.     LocalFree(hlocBmi);
  90.     GlobalUnlock(hDib);
  91.     return hDib;
  92. }
  93.  
  94. int SetDIBPixel(HDIB hdib, int x, int y, int color) {
  95.     char huge *PixelLoc;
  96.     BITMAPINFO huge *lpbmi;
  97.  
  98.     lpbmi = (BITMAPINFO huge *)GlobalLock(hdib);
  99.     if (lpbmi == NULL) {
  100.         MessageBox(NULL,"Can't Lock hDib. (SetDIBPixel)","DEBUG", MB_OK);
  101.         return 0;
  102.     }
  103.     if ((x<lpbmi->bmiHeader.biWidth)&&(y<lpbmi->bmiHeader.biHeight)) {
  104.         PixelLoc = (char huge *)lpbmi
  105.                 + sizeof(BITMAPINFOHEADER)
  106.                 + sizeof(RGBQUAD)*256
  107.                 + y * BytesPerLine + x;
  108.         *(char huge *)PixelLoc = (char)color;    // Set Color
  109.         GlobalUnlock(hdib);
  110.     }
  111.     else return 0;
  112.     return 1;
  113. }
  114.  
  115. HDIB CopyDIB(HDIB hSourceDIB) {
  116.     DWORD    size;
  117.     HDIB    hDestDIB;
  118.     BYTE huge *src;
  119.     BYTE huge *dest;
  120.  
  121.     size = GlobalSize(hSourceDIB);
  122.     if (size != 0) {
  123.         hDestDIB = GlobalAlloc(GMEM_MOVEABLE, size);
  124.         if (hDestDIB != (HANDLE)NULL) {
  125.             src = (BYTE huge *)GlobalLock(hSourceDIB);
  126.             if (src != NULL) {
  127.                 dest = (BYTE huge *)GlobalLock(hDestDIB);
  128.                 if (dest != NULL) {
  129.                     while (size != 0){
  130.                         *dest = *src;
  131.                         dest++;
  132.                         src++;
  133.                         size--;
  134.                     }
  135.                     GlobalUnlock(hDestDIB);
  136.                 }
  137.                 else {
  138.                     GlobalFree(hDestDIB);
  139.                     hDestDIB = (HANDLE)NULL;
  140.                 }
  141.                 GlobalUnlock(hSourceDIB);
  142.             }
  143.             else {
  144.                 GlobalFree(hDestDIB);
  145.                 hDestDIB = (HANDLE)NULL;
  146.             }
  147.         }
  148.     }
  149.     else hDestDIB = (HANDLE)NULL;
  150.     return hDestDIB;
  151. }
  152.  
  153. HPAL GetDIBPalette(HDIB hdib) {
  154.     HANDLE hLogPal;
  155.     NPLOGPALETTE pLogPal;
  156.     LPBITMAPINFO lpbmi;
  157.     HPAL hPal;
  158.     int i;
  159.  
  160.     hLogPal= (HANDLE) LocalAlloc(LMEM_FIXED,(sizeof(LOGPALETTE)+
  161.                             (sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*(PALETTESIZE))));
  162.     pLogPal= (NPLOGPALETTE)LocalLock(hLogPal);
  163.     lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  164.     pLogPal->palVersion=0x300;
  165.     pLogPal->palNumEntries=lpbmi->bmiHeader.biClrUsed;
  166.     for (i=0;i<256;i++) {
  167.         pLogPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
  168.         pLogPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
  169.         pLogPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
  170.         pLogPal->palPalEntry[i].peFlags=lpbmi->bmiColors[i].rgbReserved;
  171.     }
  172.     hPal=CreatePalette(pLogPal);
  173.     LocalUnlock(hLogPal);
  174.     LocalFree(hLogPal);
  175.     GlobalUnlock(hdib);
  176.     return hPal;
  177. }
  178.  
  179. void ShowDIB(HDC hdc,HDIB hdib) {
  180.     BITMAPINFO huge *lpbmi;
  181.     char huge *Data;
  182.  
  183.     lpbmi = (BITMAPINFO huge *)GlobalLock(hdib);
  184.     if (lpbmi == NULL)
  185.         MessageBox(NULL,"Can't Lock DIB memory. (ShowDIB)","DEBUG", MB_OK);
  186.     Data = (LPSTR)lpbmi
  187.             + sizeof(BITMAPINFOHEADER)
  188.             + sizeof(RGBQUAD)*256;
  189.     SetDIBitsToDevice(hdc,0,0,lpbmi->bmiHeader.biWidth,
  190.                                     lpbmi->bmiHeader.biHeight,0,0,0,lpbmi->bmiHeader.biHeight,
  191.                                     Data,lpbmi,DIB_RGB_COLORS);
  192.     GlobalUnlock(hdib);
  193. }
  194.  
  195. void ShowLine(HDC hdc,HDIB hdib,int line) {
  196.     BITMAPINFO huge *lpbmi;
  197.     char huge *Data;
  198.  
  199.     lpbmi = (BITMAPINFO huge *)GlobalLock(hdib);
  200.     if (lpbmi == NULL)
  201.         MessageBox(NULL,"Can't Lock DIB memory. (ShowIt)","DEBUG", MB_OK);
  202.     Data = (LPSTR)lpbmi
  203.             + sizeof(BITMAPINFOHEADER)
  204.             + sizeof(RGBQUAD)*256;
  205.     SetDIBitsToDevice(hdc,0,lpbmi->bmiHeader.biHeight-line-1,
  206.                                     lpbmi->bmiHeader.biWidth,
  207.                                     1,0,line,0,lpbmi->bmiHeader.biHeight,
  208.                                     Data,lpbmi,DIB_RGB_COLORS);
  209.     GlobalUnlock(hdib);
  210. }
  211.  
  212. /***********************************************
  213.  *  Mandelbrot                                 *
  214.  *                                             *
  215.  *   Calculates and draws the fractal.         *
  216.  *                                             *
  217.  ***********************************************/
  218. void Mandelbrot(HDC hdc,HDIB hdib,int xMax, int yMax,
  219. //                        float left, float top, float right, float bottom) {
  220.                         double left, double top, double right, double bottom) {
  221.     MSG lpMsg;
  222.     int x, y, Del;
  223. //    float Zr, Zi, Cr, Ci, ZrSq, ZiSq, dist, xScale, yScale;
  224.     double Zr, Zi, Cr, Ci, ZrSq, ZiSq, dist2, xScale, yScale;
  225.  
  226.     y=0;
  227.     xScale = (right-left)/(float)xMax; yScale = (top-bottom)/(float)yMax;
  228.     while(Do==1) {
  229.         PeekMessage(&lpMsg,NULL,0,0,PM_REMOVE);
  230.         for (x=0;x<xMax;x++) {
  231.  
  232.             Del = 1; dist2 = 0;
  233.             Cr = x * xScale+left; Ci = bottom + y * yScale;
  234.             Zr = Cr; Zi = Ci;
  235.             while ((dist2<4)&&(++Del<iMaxDel)) {
  236.                 ZrSq = Zr*Zr; ZiSq=Zi*Zi;
  237.                 Zi = 2*Zr*Zi + Ci;
  238.                 Zr = ZrSq - ZiSq + Cr;
  239.                 dist2 = ZrSq + ZiSq;
  240.             }
  241.             if (Del==iMaxDel) Del=0;
  242.             else if (Del > 255) Del = (Del%255)+1;
  243.             SetDIBPixel(hdib,x,y,Del);
  244.         }
  245.         ShowLine(hdc,hdib,y);
  246.         y++; if (y>yMax) Do=0;
  247.  
  248.         TranslateMessage(&lpMsg);    // allow windows message processing
  249.         DispatchMessage(&lpMsg);
  250.     }
  251. }
  252.  
  253. /***********************************************
  254.  *  Palette functions:                         *
  255.  *                                             *
  256.  *   Define the various palettes available in  *
  257.  *      Bare' Mandelbrot program.                 *
  258.  *                                             *
  259.  ***********************************************/
  260. void DefaultPalette(HDIB hdib) {
  261.     LPBITMAPINFO lpbmi;
  262.     int i;
  263.     if (hdib!=NULL) {
  264.         lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  265.         if (lpbmi!=NULL) {
  266.             lpbmi->bmiColors[0].rgbRed = 0;
  267.             lpbmi->bmiColors[0].rgbGreen = 0;
  268.             lpbmi->bmiColors[0].rgbBlue = 0;
  269.             lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
  270.             for (i=1;i<32;i++) {    // fade blue to red
  271.                 lpbmi->bmiColors[i].rgbRed=i*8;
  272.                 lpbmi->bmiColors[i].rgbGreen=0x00;
  273.                 lpbmi->bmiColors[i].rgbBlue=255 - (i*8);
  274.                 lpbmi->bmiColors[i].rgbReserved=PC_RESERVED;
  275.             }
  276.             for (i=32;i<64;i++) {   // fade red to green
  277.                 lpbmi->bmiColors[i].rgbRed=255 - ((i-32)*8);
  278.                 lpbmi->bmiColors[i].rgbGreen=(i-32)*8;
  279.                 lpbmi->bmiColors[i].rgbBlue=0x00;
  280.                 lpbmi->bmiColors[i].rgbReserved=PC_RESERVED;
  281.             }
  282.             for (i=64;i<96;i++) {   // fade green to blue
  283.                 lpbmi->bmiColors[i].rgbRed=0x00;
  284.                 lpbmi->bmiColors[i].rgbGreen=255 - ((i-64)*8);
  285.                 lpbmi->bmiColors[i].rgbBlue=(i-64)*8;
  286.                 lpbmi->bmiColors[i].rgbReserved=PC_RESERVED;
  287.             }
  288.             for (i=96;i<128;i++) {  // fade blue to yellow
  289.                 lpbmi->bmiColors[i].rgbRed = (i-96)*8;
  290.                 lpbmi->bmiColors[i].rgbGreen = (i-96)*8;
  291.                 lpbmi->bmiColors[i].rgbBlue = 255 - ((i-96)*8);
  292.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  293.             }
  294.             for (i=128;i<192;i++) { // fade yellow to red
  295.                 lpbmi->bmiColors[i].rgbRed = 255;
  296.                 lpbmi->bmiColors[i].rgbGreen = 255 - ((i-128)*4);
  297.                 lpbmi->bmiColors[i].rgbBlue = 0;
  298.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  299.             }
  300.             for (i=192;i<224;i++) { // fade red to purple
  301.                 lpbmi->bmiColors[i].rgbRed = 255;
  302.                 lpbmi->bmiColors[i].rgbGreen = 0;
  303.                 lpbmi->bmiColors[i].rgbBlue = (i-192)*8;
  304.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  305.             }
  306.             for (i=224;i<256;i++) { // fade purple to blue
  307.                 lpbmi->bmiColors[i].rgbRed = 255 - ((i-224)*8);
  308.                 lpbmi->bmiColors[i].rgbGreen = 0;
  309.                 lpbmi->bmiColors[i].rgbBlue = 255;
  310.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  311.             }
  312.         }
  313.         GlobalUnlock(hdib);
  314.     }
  315. }
  316.  
  317. void PurpleGreenPalette(HDIB hdib) {
  318.     LPBITMAPINFO lpbmi;
  319.     int i;
  320.     if (hdib!=NULL) {
  321.         lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  322.         for (i=0;i<256;i++) {
  323.             lpbmi->bmiColors[i].rgbRed = (i<128) ? (256 -(2*i)) : 0;
  324.             lpbmi->bmiColors[i].rgbGreen = i;
  325.             lpbmi->bmiColors[i].rgbBlue = 256-i;
  326.             lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  327.         }
  328.         GlobalUnlock(hdib);
  329.     }
  330. }
  331.  
  332. void GreyPalette(HDIB hdib) {
  333.     LPBITMAPINFO lpbmi;
  334.     int i;
  335.     if (hdib!=NULL) {
  336.         lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  337.         if (lpbmi!=NULL) {
  338.             lpbmi->bmiColors[0].rgbRed = 0;
  339.             lpbmi->bmiColors[0].rgbGreen = 0;
  340.             lpbmi->bmiColors[0].rgbBlue = 0;
  341.             lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
  342.             for (i=1;i<32;i++) {
  343.                 lpbmi->bmiColors[i].rgbRed = i*6+50;
  344.                 lpbmi->bmiColors[i].rgbGreen = i*6+50;
  345.                 lpbmi->bmiColors[i].rgbBlue = i*6+50;
  346.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  347.             }
  348.             for (i=32;i<64;i++) {
  349.                 lpbmi->bmiColors[i].rgbRed = 255-6*(i-32);
  350.                 lpbmi->bmiColors[i].rgbGreen = 255-6*(i-32);
  351.                 lpbmi->bmiColors[i].rgbBlue = 255-6*(i-32);
  352.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  353.             }
  354.             for (i=64;i<128;i++) {
  355.                 lpbmi->bmiColors[i].rgbRed = 50+3*(i-64);
  356.                 lpbmi->bmiColors[i].rgbGreen = 50+3*(i-64);
  357.                 lpbmi->bmiColors[i].rgbBlue = 50+3*(i-64);
  358.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  359.             }
  360.             for (i=128;i<192;i++) {
  361.                 lpbmi->bmiColors[i].rgbRed = 256-3*(i-128);
  362.                 lpbmi->bmiColors[i].rgbGreen = 256-3*(i-128);
  363.                 lpbmi->bmiColors[i].rgbBlue = 256-3*(i-128);
  364.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  365.             }
  366.             for (i=192;i<256;i++) {
  367.                 lpbmi->bmiColors[i].rgbRed = 50+3*(i-192);
  368.                 lpbmi->bmiColors[i].rgbGreen = 50+3*(i-192);
  369.                 lpbmi->bmiColors[i].rgbBlue = 50+3*(i-192);
  370.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  371.             }
  372.         }
  373.         GlobalUnlock(hdib);
  374.     }
  375. }
  376.  
  377. void ZebraPalette(HDIB hdib) {
  378.     LPBITMAPINFO lpbmi;
  379.     int i;
  380.     if (hdib!=NULL) {
  381.         lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  382.         if (lpbmi!=NULL) {
  383.             for (i=0;i<255;i+=2) {
  384.                 lpbmi->bmiColors[i].rgbRed = 0;
  385.                 lpbmi->bmiColors[i].rgbGreen = 0;
  386.                 lpbmi->bmiColors[i].rgbBlue = 0;
  387.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  388.                 lpbmi->bmiColors[i+1].rgbRed = 255;
  389.                 lpbmi->bmiColors[i+1].rgbGreen = 255;
  390.                 lpbmi->bmiColors[i+1].rgbBlue = 255;
  391.                 lpbmi->bmiColors[i+1].rgbReserved = PC_RESERVED;
  392.             }
  393.         }
  394.         GlobalUnlock(hdib);
  395.     }
  396. }
  397.  
  398. void RandomPalette(HDIB hdib) {
  399.     LPBITMAPINFO lpbmi;
  400.     int i;
  401.     if (hdib!=NULL) {
  402.         lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  403.         if (lpbmi!=NULL) {
  404.             lpbmi->bmiColors[0].rgbRed = 0;
  405.             lpbmi->bmiColors[0].rgbGreen = 0;
  406.             lpbmi->bmiColors[0].rgbBlue = 0;
  407.             lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
  408.             lpbmi->bmiColors[1].rgbRed = (int)((double)rand()/(double)RAND_MAX*256);
  409.             lpbmi->bmiColors[1].rgbGreen = (int)((double)rand()/(double)RAND_MAX*256);
  410.             lpbmi->bmiColors[1].rgbBlue = (int)((double)rand()/(double)RAND_MAX*256);
  411.             lpbmi->bmiColors[1].rgbReserved = PC_RESERVED;
  412.             for (i=2;i<256;i++) {
  413.                 lpbmi->bmiColors[i].rgbRed = (lpbmi->bmiColors[i-1].rgbRed + (int)((double)rand()/(double)RAND_MAX*10))%256;
  414.                 lpbmi->bmiColors[i].rgbGreen = (lpbmi->bmiColors[i-1].rgbGreen + (int)((double)rand()/(double)RAND_MAX*10))%256;
  415.                 lpbmi->bmiColors[i].rgbBlue = (lpbmi->bmiColors[i-1].rgbBlue + (int)((double)rand()/(double)RAND_MAX*10))%256;
  416.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  417.             }
  418.         }
  419.         GlobalUnlock(hdib);
  420.     }
  421. }
  422.  
  423. void RainbowPalette(HDIB hdib) {
  424.     LPBITMAPINFO lpbmi;
  425.     int i;
  426.     if (hdib!=NULL) {
  427.         lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
  428.         if (lpbmi!=NULL) {
  429.             for (i=0;i<16;i++) {
  430.                 lpbmi->bmiColors[i].rgbRed = 255;
  431.                 lpbmi->bmiColors[i].rgbGreen = i*16;
  432.                 lpbmi->bmiColors[i].rgbBlue = 0;
  433.                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  434.  
  435.                 lpbmi->bmiColors[i+16].rgbRed = 255-(i*16);
  436.                 lpbmi->bmiColors[i+16].rgbGreen = 255;
  437.                 lpbmi->bmiColors[i+16].rgbBlue = 0;
  438.                 lpbmi->bmiColors[i+16].rgbReserved = PC_RESERVED;
  439.  
  440.                 lpbmi->bmiColors[i+32].rgbRed = 0;
  441.                 lpbmi->bmiColors[i+32].rgbGreen = 255-(i*16);
  442.                 lpbmi->bmiColors[i+32].rgbBlue = i*16;
  443.                 lpbmi->bmiColors[i+32].rgbReserved = PC_RESERVED;
  444.  
  445.                 lpbmi->bmiColors[i+48].rgbRed = i*16;
  446.                 lpbmi->bmiColors[i+48].rgbGreen = 0;
  447.                 lpbmi->bmiColors[i+48].rgbBlue = 255-(i*16);
  448.                 lpbmi->bmiColors[i+48].rgbReserved = PC_RESERVED;
  449.             }
  450.             for (i=0;i<64;i++) {
  451.                 lpbmi->bmiColors[i+64].rgbRed = lpbmi->bmiColors[i].rgbRed;
  452.                 lpbmi->bmiColors[i+64].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
  453.                 lpbmi->bmiColors[i+64].rgbBlue = lpbmi->bmiColors[i].rgbBlue ;
  454.                 lpbmi->bmiColors[i+64].rgbReserved = PC_RESERVED;
  455.                 lpbmi->bmiColors[i+128].rgbRed = lpbmi->bmiColors[i].rgbRed;
  456.                 lpbmi->bmiColors[i+128].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
  457.                 lpbmi->bmiColors[i+128].rgbBlue = lpbmi->bmiColors[i].rgbBlue ;
  458.                 lpbmi->bmiColors[i+128].rgbReserved = PC_RESERVED;
  459.                 lpbmi->bmiColors[i+192].rgbRed = lpbmi->bmiColors[i].rgbRed;
  460.                 lpbmi->bmiColors[i+192].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
  461.                 lpbmi->bmiColors[i+192].rgbBlue = lpbmi->bmiColors[i].rgbBlue ;
  462.                 lpbmi->bmiColors[i+192].rgbReserved = PC_RESERVED;
  463.             }     
  464.             lpbmi->bmiColors[0].rgbRed = 0;
  465.             lpbmi->bmiColors[0].rgbGreen = 0;
  466.             lpbmi->bmiColors[0].rgbBlue = 0;
  467.             lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
  468.         }
  469.         GlobalUnlock(hdib);
  470.     }
  471. }
  472.  
  473. void RotateColors(HANDLE hPal, PALETTEENTRY *palScratch) {
  474.     PALETTEENTRY palTemp;
  475.     int i;
  476.     palTemp.peRed   = palScratch[1].peRed;
  477.     palTemp.peGreen = palScratch[1].peGreen;
  478.     palTemp.peBlue  = palScratch[1].peBlue;
  479.     for (i=1;i<255;i++) {
  480.         palScratch[i].peRed   = palScratch[i+1].peRed;
  481.         palScratch[i].peGreen = palScratch[i+1].peGreen;
  482.         palScratch[i].peBlue  = palScratch[i+1].peBlue;
  483.     }
  484.     palScratch[255].peRed   = palTemp.peRed;
  485.     palScratch[255].peGreen = palTemp.peGreen;
  486.     palScratch[255].peBlue  = palTemp.peBlue;
  487.     AnimatePalette(hPal,0,256,palScratch);
  488. }
  489.  
  490. void DrawStatusBar(HDC hdc, int x, int y, float left, float top,
  491.                             float right, float bot) {
  492.     HBRUSH hbrush, hbrushOld;
  493.     HFONT hOldFont, hNewFont;
  494.     char szBuffer[256];
  495.     int iTabs[5] = {100,150,200,250,300};
  496.  
  497.     hbrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
  498.     hbrushOld = SelectObject(hdc,hbrush);
  499.     Rectangle(hdc,0,y,x,y+30);
  500.     SelectObject(hdc,hbrushOld);
  501.     hNewFont=CreateFont(10,0,0,0,FW_BOLD,0,0,0,0,
  502.                             0,0,0,
  503.                             0,"Times New Roman");
  504.     hOldFont=SelectObject(hdc,hNewFont);
  505.  
  506.     SetBkMode(hdc,TRANSPARENT);
  507.     sprintf(szBuffer,"Window: %d,%d\tView Vertical:\t%g,%g",x,y,top,bot);
  508.     TabbedTextOut(hdc,10,y+5,szBuffer,strlen(szBuffer),5,iTabs,10);
  509.     sprintf(szBuffer,"\tView Horizontal:\t%g,%g",left,right);
  510.     TabbedTextOut(hdc,10,y+15,szBuffer,strlen(szBuffer),5,iTabs,10);
  511.     SelectObject(hdc,hOldFont);
  512.     DeleteObject(hNewFont);
  513.     DeleteObject(hbrush);
  514. }
  515.  
  516. /***********************************************
  517.  *  WinMain                                    *
  518.  *                                             *
  519.  *   Register WNDCLASS, create window, enter   *
  520.  *      message loop, and do exit clean-up.       *
  521.  *                                             *
  522.  ***********************************************/
  523. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPreInst, LPSTR lpszCmdLine,
  524.                             int nCmdShow)
  525. {
  526.     HWND hWnd;
  527.     MSG lpMsg;
  528.     WNDCLASS wcApp;
  529.    time_t t;
  530.  
  531.     srand((unsigned) time(&t));
  532.  
  533.     if (!hPreInst) {
  534.         wcApp.lpszClassName=szProgName;
  535.         wcApp.hInstance=hInst;
  536.         wcApp.lpfnWndProc=WndProc;
  537.         wcApp.hCursor=LoadCursor( NULL, IDC_ARROW );
  538.         wcApp.hIcon=LoadIcon(hInst, szIconName );
  539.         wcApp.lpszMenuName=szMenuName;
  540.         wcApp.hbrBackground=(HBRUSH)GetStockObject( BLACK_BRUSH );
  541.         wcApp.style=CS_HREDRAW|CS_VREDRAW|CS_BYTEALIGNCLIENT|CS_BYTEALIGNWINDOW;
  542.         wcApp.cbClsExtra=0;
  543.         wcApp.cbWndExtra=0;
  544.         if (!RegisterClass(&wcApp))
  545.             return FALSE;
  546.     }
  547. /*    hWnd = CreateWindow(szProgName, "Bare's Mandelbrot Program",
  548.                             WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
  549.                             CW_USEDEFAULT,CW_USEDEFAULT,
  550.                             CW_USEDEFAULT,NULL,NULL,
  551.                             hInst,NULL);    */
  552.     hWnd = CreateWindow(szProgName, "Bare's Mandelbrot Program",
  553.                             WS_OVERLAPPEDWINDOW,500,
  554.                             50,400,
  555.                             400,NULL,NULL,
  556.                             hInst,NULL);
  557.     if (hWnd==NULL) return FALSE;
  558.     hInstance = hInst;
  559.     ShowWindow(hWnd,nCmdShow);
  560.     UpdateWindow(hWnd);
  561.  
  562.     while (GetMessage(&lpMsg,NULL,0,0)) {
  563.         TranslateMessage(&lpMsg);
  564.         DispatchMessage(&lpMsg);
  565.     }
  566.  
  567.     DestroyIcon(wcApp.hIcon);
  568.     DestroyCursor(wcApp.hCursor);
  569.     DestroyMenu(GetMenu(hWnd));
  570.     UnregisterClass(szProgName,hInst);
  571.     return(lpMsg.wParam);
  572. }
  573.  
  574. /***********************************************
  575.  *  WndProc                                    *
  576.  *                                             *
  577.  *   Process messages to the main window.      *
  578.  *                                             *
  579.  ***********************************************/
  580. LONG FAR PASCAL _export WndProc(HWND hWnd, UINT messg, WPARAM wParam,
  581.                                             LPARAM lParam)
  582. {
  583.     static FARPROC lpfnAboutDlgProc, lpfnOptionsDlgProc;
  584.     static HWND hInst1;
  585.     static int xWinSize, yWinSize, Resize;
  586. //    static double topMand,botMand,leftMand,rightMand;
  587.     static double oldtopMand,oldbotMand,oldleftMand,oldrightMand;
  588.     PAINTSTRUCT ps;
  589.     static HDC hdc;
  590. //    NPLOGPALETTE pLogPal;
  591.     static HANDLE hPal;
  592.     HDIB hCopyDIB;
  593.     static PALETTEENTRY palScratch[256];
  594.     LPBITMAPINFO lpbmi;
  595.  
  596.     static int MouseDown, BoxDrawn, TimerOn;
  597.     static int xPos1, yPos1, xPos2, yPos2;
  598.     double xScale, yScale;
  599.     static POINT pntBox[5];
  600.     static HPEN hpen, hpenOld;
  601.  
  602.     HBITMAP hbmpMyBitmap, hbmpOld;
  603.     BITMAP bm;
  604.     HFONT hOldFont, hNewFont;
  605.     char szMessage[80];
  606.     HDC MemDC;
  607.  
  608.     int i;
  609.  
  610.     switch (messg) {
  611.         case WM_SIZE:
  612.             xWinSize=LOWORD(lParam);
  613.             yWinSize=HIWORD(lParam)-30;
  614.             Resize = TRUE;
  615.             break;
  616.         case WM_CREATE:
  617.             hInst1 = ((LPCREATESTRUCT) lParam)->hInstance;
  618.             lpfnAboutDlgProc=MakeProcInstance((FARPROC)AboutDlgProc,hInst1);
  619.             lpfnOptionsDlgProc=MakeProcInstance((FARPROC)OptionsDlgProc,hInst1);
  620.             MouseDown=FALSE; BoxDrawn=FALSE; Resize = FALSE; TimerOn = FALSE;
  621.             topMand=1.3;botMand=-1.3;leftMand=-2;rightMand=.8;
  622.             oldtopMand=1.3;oldbotMand=-1.3;oldleftMand=-2;oldrightMand=.8;
  623.             break;
  624.         case WM_TIMER:
  625.             RotateColors(hPal, palScratch);
  626.             break;
  627.         case WM_PAINT:
  628.             hdc=BeginPaint(hWnd,&ps);
  629.             DrawStatusBar(hdc,xWinSize,yWinSize,leftMand,topMand,rightMand,botMand);
  630.             if (hMandelbrotDIB!=NULL) {
  631.                 hPal = GetDIBPalette(hMandelbrotDIB);
  632.                 SelectPalette(hdc,hPal,0);
  633.                 RealizePalette(hdc);
  634.                 ShowDIB(hdc,hMandelbrotDIB);
  635.                 DeleteObject(hPal);
  636.             }
  637.             else {
  638.                 hbmpMyBitmap = LoadBitmap(hInstance, "Black_Sun");
  639.                 GetObject(hbmpMyBitmap, sizeof(BITMAP), &bm);
  640.  
  641.                 MemDC = CreateCompatibleDC(hdc);
  642.                 hbmpOld = SelectObject(MemDC, hbmpMyBitmap);
  643.  
  644.                 BitBlt(hdc, 200, 20, bm.bmWidth, bm.bmHeight, MemDC, 0, 0, SRCCOPY);
  645.                 SelectObject(MemDC, hbmpOld);
  646.  
  647.                 DeleteObject(hbmpMyBitmap);
  648.                 DeleteDC(MemDC);
  649.  
  650.                 hNewFont=CreateFont(70,0,0,0,FW_BOLD,0,0,0,0,
  651.                         0,0,0,0,"Times New Roman");
  652.                 hOldFont=SelectObject(hdc,hNewFont);
  653.                 SetTextColor(hdc,PALETTEINDEX(2));
  654.                 sprintf(szMessage,"Bare's");
  655.                 TextOut(hdc,10,5,szMessage,strlen(szMessage));
  656.                 SelectObject(hdc,hOldFont);
  657.                 DeleteObject(hNewFont);
  658.  
  659.                 hNewFont=CreateFont(36,0,100,100,FW_BOLD,0,0,0,0,
  660.                         0,0,0,0,"Times New Roman");
  661.                 hOldFont=SelectObject(hdc,hNewFont);
  662.                 SetTextColor(hdc,PALETTEINDEX(1));
  663.                 sprintf(szMessage,"Mandelbrot");
  664.                 TextOut(hdc,10,90,szMessage,strlen(szMessage));
  665.                 sprintf(szMessage,"Program");
  666.                 TextOut(hdc,40,120,szMessage,strlen(szMessage));
  667.                 SelectObject(hdc,hOldFont);
  668.                 DeleteObject(hNewFont);
  669.  
  670.                 hNewFont=CreateFont(18,0,0,0,FW_BOLD,0,0,0,0,
  671.                         0,0,0,0,"Times New Roman");
  672.                 hOldFont=SelectObject(hdc,hNewFont);
  673.                 SetTextColor(hdc,PALETTEINDEX(1));
  674.                 sprintf(szMessage,"Version: %s",VerInfo);
  675.                 TextOut(hdc,100,155,szMessage,strlen(szMessage));
  676.                 sprintf(szMessage,"Build Date: %s",__DATE__);
  677.                 TextOut(hdc,10,195,szMessage,strlen(szMessage));
  678.                 sprintf(szMessage,"Written By: J. Christopher Bare");
  679.                 TextOut(hdc,10,215,szMessage,strlen(szMessage));
  680.                 SelectObject(hdc,hOldFont);
  681.                 DeleteObject(hNewFont);
  682.             }
  683.             ReleaseDC(hWnd,hdc);
  684.             ValidateRect(hWnd,NULL);
  685.             EndPaint(hWnd,&ps);
  686.             BoxDrawn=FALSE;
  687.             break;
  688.         case WM_LBUTTONDOWN:
  689.             if ((!Do)&&(hMandelbrotDIB!=NULL)) {
  690.                 MouseDown=TRUE;
  691.                 hdc = GetDC(hWnd);
  692.                 hpen = CreatePen(PS_DOT, 1, PALETTEINDEX(0));
  693.                 hpenOld = SelectObject(hdc, hpen);
  694.                 SetROP2(hdc,R2_XORPEN);
  695.                 if (BoxDrawn) Polyline(hdc,pntBox,5);
  696.                 xPos1 = LOWORD(lParam);
  697.                 yPos1 = HIWORD(lParam);
  698.                 SetCapture(hWnd);
  699.                 xPos2 = xPos1; yPos2 = yPos1;
  700.                 pntBox[0].x = xPos1;pntBox[0].y = yPos1;
  701.                 pntBox[1].x = xPos2;pntBox[1].y = yPos1;
  702.                 pntBox[2].x = xPos2;pntBox[2].y = yPos2;
  703.                 pntBox[3].x = xPos1;pntBox[3].y = yPos2;
  704.                 pntBox[4].x = xPos1;pntBox[4].y = yPos1;
  705.             }
  706.             break;
  707.         case WM_MOUSEMOVE:
  708.             if (MouseDown) {
  709.                 Polyline(hdc,pntBox,5);
  710.                 xPos2 = LOWORD(lParam);
  711.                 yPos2 = HIWORD(lParam);
  712.                 if (xPos2>=xWinSize) xPos2=xWinSize-1;
  713.                 else if (xPos2<0) xPos2=0;
  714.                 if (yPos2>=yWinSize) yPos2=yWinSize-1;
  715.                 else if (yPos2<0) yPos2 = 0;
  716.                 pntBox[0].x = xPos1;pntBox[0].y = yPos1;
  717.                 pntBox[1].x = xPos2;pntBox[1].y = yPos1;
  718.                 pntBox[2].x = xPos2;pntBox[2].y = yPos2;
  719.                 pntBox[3].x = xPos1;pntBox[3].y = yPos2;
  720.                 pntBox[4].x = xPos1;pntBox[4].y = yPos1;
  721.                 Polyline(hdc,pntBox,5);
  722.             }
  723.             break;
  724.         case WM_LBUTTONUP:
  725.             if (MouseDown) {
  726.                 xPos2 = LOWORD(lParam);
  727.                 yPos2 = HIWORD(lParam);
  728.                 if (xPos2>xWinSize) xPos2=xWinSize;
  729.                 if (xPos2<0) xPos2=0;
  730.                 if (yPos2>yWinSize) yPos2=yWinSize;
  731.                 if (yPos2<0) yPos2 = 0;
  732.                 ReleaseCapture();
  733.                 MouseDown = FALSE;
  734.                 BoxDrawn = TRUE;
  735.                 SetROP2(hdc,R2_COPYPEN);
  736.                 SelectObject(hdc, hpenOld);
  737.                 DeleteObject(hpen);
  738.                 ReleaseDC(hWnd,hdc);
  739.                 xScale = (oldrightMand-oldleftMand)/xWinSize;
  740.                 yScale = (oldtopMand-oldbotMand)/yWinSize;
  741.                 if (xPos1 > xPos2) {
  742.                     rightMand = xPos1*xScale+oldleftMand; leftMand = xPos2*xScale+oldleftMand;
  743.                 }
  744.                 else if (xPos2 > xPos1){
  745.                     rightMand = xPos2*xScale+oldleftMand; leftMand = xPos1*xScale+oldleftMand;
  746.                 }
  747.                 if (yPos1 > yPos2) {
  748.                     botMand = oldtopMand - yPos1*yScale; topMand = oldtopMand - yPos2*yScale;
  749.                 }
  750.                 else if (yPos2 > yPos1) {
  751.                     botMand = oldtopMand - yPos2*yScale; topMand = oldtopMand - yPos1*yScale;
  752.                 }
  753.             }
  754.             break;
  755.         case WM_COMMAND:
  756.             switch(wParam) {
  757.                 case CM_ABOUT:
  758.                     DialogBox(hInst1,"AboutDlg",hWnd,lpfnAboutDlgProc);
  759.                     break;
  760.                 case CM_OPTIONS:
  761.                     DialogBox(hInst1,"OptionsDlg",hWnd,lpfnOptionsDlgProc);
  762.                     break;
  763.                 case CM_DEFAULTPALETTE:
  764.                     if (Do==0) {
  765.                         DefaultPalette(hMandelbrotDIB);
  766.                         InvalidateRect(hWnd,NULL,TRUE);
  767.                     }
  768.                     break;
  769.                 case CM_PURPLEGREENPALETTE:
  770.                     if (Do==0) {
  771.                         PurpleGreenPalette(hMandelbrotDIB);
  772.                         InvalidateRect(hWnd,NULL,TRUE);
  773.                     }
  774.                     break;
  775.                 case CM_RAINBOWPALETTE:
  776.                     if (Do==0) {
  777.                         RainbowPalette(hMandelbrotDIB);
  778.                         InvalidateRect(hWnd,NULL,TRUE);
  779.                     }
  780.                     break;
  781.                 case CM_ZEBRAPALETTE:
  782.                     if (Do==0) {
  783.                         ZebraPalette(hMandelbrotDIB);
  784.                         InvalidateRect(hWnd,NULL,TRUE);
  785.                     }
  786.                     break;
  787.                 case CM_GREYPALETTE:
  788.                     if (Do==0) {
  789.                         GreyPalette(hMandelbrotDIB);
  790.                         InvalidateRect(hWnd,NULL,TRUE);
  791.                     }
  792.                     break;
  793.                 case CM_RANDOMPALETTE:
  794.                     if (Do==0) {
  795.                         RandomPalette(hMandelbrotDIB);
  796.                         InvalidateRect(hWnd,NULL,TRUE);
  797.                     }
  798.                     break;
  799.                 case CM_COPY:
  800.                     hCopyDIB = CopyDIB(hMandelbrotDIB);
  801.                     if (hCopyDIB!=NULL) {
  802.                         if (!OpenClipboard(hWnd))
  803.                             MessageBox(hWnd,"Open Clipboard failed.","DEBUG",MB_OK);
  804.                         if (!EmptyClipboard())
  805.                             MessageBox(hWnd,"Empty Clipboard failed.","DEBUG",MB_OK);
  806.                         SetClipboardData(CF_DIB,hCopyDIB);
  807.                         SetClipboardData(CF_PALETTE,hPal);
  808.                         CloseClipboard();
  809.                     }
  810.                     break;
  811.                 case CM_START:
  812.                     if (Do==0) {
  813.                         if (Resize) {
  814.                             GlobalFree(hMandelbrotDIB);
  815.                             hMandelbrotDIB = CreateDIB(xWinSize,yWinSize);
  816.                             DefaultPalette(hMandelbrotDIB);
  817.                             Resize = FALSE;
  818.                         }
  819.                         if (hMandelbrotDIB==NULL) {
  820.                             hMandelbrotDIB = CreateDIB(xWinSize,yWinSize);
  821.                             DefaultPalette(hMandelbrotDIB);
  822.                         }
  823.                         hPal = GetDIBPalette(hMandelbrotDIB);
  824.                         hdc = GetDC(hWnd);
  825.                         DrawStatusBar(hdc,xWinSize,yWinSize,leftMand,topMand,
  826.                                             rightMand,botMand);
  827.                         SelectPalette(hdc,hPal,0);
  828.                         RealizePalette(hdc);
  829.                         Do = 1;
  830.                         Mandelbrot(hdc,hMandelbrotDIB,xWinSize,yWinSize,
  831.                                         leftMand,topMand,rightMand,botMand);
  832.                         DeleteObject(hPal);
  833.                         ReleaseDC(hWnd,hdc);
  834.                         BoxDrawn=FALSE;
  835.                         oldleftMand=leftMand; oldrightMand=rightMand;
  836.                         oldtopMand=topMand; oldbotMand = botMand;
  837.                     }
  838.                     break;
  839.                 case CM_STOP:
  840.                     Do=0;
  841.                     break;
  842.                 case CM_RESET:
  843.                     topMand=1.3;botMand=-1.3;leftMand=-2;rightMand=.8;
  844.                     oldtopMand=1.3;oldbotMand=-1.3;oldleftMand=-2;oldrightMand=.8;
  845.                     break;
  846.                 case CM_ANIMATE:
  847.                     if (TimerOn) {
  848.                         DeleteObject(hPal);
  849.                         ReleaseDC(hWnd,hdc);
  850.                         KillTimer(hWnd,ID_TIMER);
  851.                         TimerOn=FALSE;
  852.                         lpbmi = (LPBITMAPINFO)GlobalLock(hMandelbrotDIB);
  853.                         if (lpbmi!=NULL) {
  854.                             for (i=0;i<256;i++) {
  855.                                 lpbmi->bmiColors[i].rgbRed = palScratch[i].peRed;
  856.                                 lpbmi->bmiColors[i].rgbGreen = palScratch[i].peGreen;
  857.                                 lpbmi->bmiColors[i].rgbBlue = palScratch[i].peBlue;
  858.                                 lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
  859.                             }
  860.                         }
  861.                         GlobalUnlock(hMandelbrotDIB);
  862.                     }
  863.                     else {
  864.                         hdc = GetDC(hWnd);
  865.                         if (GetDeviceCaps(hdc, BITSPIXEL)  == 8) {
  866.                             hPal = GetDIBPalette(hMandelbrotDIB);
  867.                             SelectPalette(hdc,hPal,0);
  868.                             RealizePalette(hdc);
  869.                             lpbmi = (LPBITMAPINFO)GlobalLock(hMandelbrotDIB);
  870.                             if (lpbmi!=NULL) {
  871.                                 for (i=0;i<256;i++) {
  872.                                     palScratch[i].peRed = lpbmi->bmiColors[i].rgbRed;
  873.                                     palScratch[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
  874.                                     palScratch[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
  875.                                     palScratch[i].peFlags = PC_RESERVED;
  876.                                 }
  877.                             }
  878.                             GlobalUnlock(hMandelbrotDIB);
  879.                             SetTimer(hWnd,ID_TIMER,100,NULL);
  880.                             TimerOn=TRUE;
  881.                         }
  882.                         else {
  883.                             sprintf(szBuffer,"Palette animation is only possible in 256 color mode.\nBits per pixel = %d",GetDeviceCaps(hdc, BITSPIXEL));
  884.                             MessageBox(NULL,szBuffer,"Error",MB_OK);
  885.                             ReleaseDC(hWnd,hdc);
  886.                         }
  887.                     }
  888.                     break;
  889.                 case CM_EXIT:
  890. //                    ReleaseDC(hWnd,hdc);
  891.                     DestroyWindow(hWnd);
  892.                     return 0;
  893.                     break;
  894.             }
  895.             break;
  896.         case WM_DESTROY:
  897.             if (TimerOn) {
  898.                 KillTimer(hWnd,ID_TIMER);
  899.                 DeleteObject(hPal);
  900.                 ReleaseDC(hWnd,hdc);
  901.             }
  902.             FreeProcInstance(lpfnAboutDlgProc);
  903.             FreeProcInstance(lpfnOptionsDlgProc);
  904.             GlobalFree(hMandelbrotDIB);
  905.             PostQuitMessage(0);
  906.             break;
  907.         default:
  908.             return DefWindowProc(hWnd,messg,wParam,lParam);
  909.     }
  910.     return(0);
  911. }
  912.  
  913. /***********************************************
  914.  *  AboutDlgProc                               *
  915.  *                                             *
  916.  *   Process messages to the About window.     *
  917.  *                                             *
  918.  ***********************************************/
  919. BOOL FAR PASCAL _export AboutDlgProc(HWND hdlg, UINT messg, WPARAM wParam,
  920.                                                     LPARAM lParam)
  921. {
  922.     HDC AboutDC, MemDC;
  923.     HBITMAP hbmpMyBitmap, hbmpOld;
  924.     BITMAP bm;
  925.     HFONT hOldFont, hNewFont;
  926.     char szMessage[512] = {  "This program was written in straight C using "
  927.                                      "Borland C++ 4.0, but not using owl or any other "
  928.                                      "libraries. Source code is included. It is "
  929.                                      "shareware and all rights are retained by the "
  930.                                      "author. ItÆs mostly free, but if you send me ten "
  931.                                      "bucks, I will declare you an enlightened and "
  932.                                      "exalted human being. HereÆs how to contact me:\n\n"
  933.                                      "J. Christopher Bare\n"
  934.                                      "610 W. Beaver Ave. #1\n"
  935.                                      "State College, PA 16801\n\n"
  936.                                      "<jcb110@psu.edu>" };
  937.  
  938.     switch (messg) {
  939.         case WM_INITDIALOG:
  940.             SetDlgItemText(hdlg,IDC_TEXTBOX,szMessage);
  941.             sprintf(szMessage,"%s",VerInfo);
  942.             SetDlgItemText(hdlg,IDC_VERSION,szMessage);
  943.             sprintf(szMessage,"%s",__DATE__);
  944.             SetDlgItemText(hdlg,IDC_BUILDDATE,szMessage);
  945.             break;
  946.         case WM_PAINT:
  947.             hbmpMyBitmap = LoadBitmap(hInstance, "MAND_BITMAP");
  948.             GetObject(hbmpMyBitmap, sizeof(BITMAP), &bm);
  949.  
  950.             AboutDC = GetDC(hdlg);
  951.             MemDC = CreateCompatibleDC(AboutDC);
  952.             hbmpOld = SelectObject(MemDC, hbmpMyBitmap);
  953.  
  954.             BitBlt(AboutDC, 20, 20, bm.bmWidth, bm.bmHeight, MemDC, 0, 0, SRCCOPY);
  955.             SelectObject(MemDC, hbmpOld);
  956.  
  957.             DeleteObject(hbmpMyBitmap);
  958.             DeleteDC(MemDC);
  959.  
  960.             hNewFont=CreateFont(54,0,100,100,FW_BOLD,0,0,0,0,
  961.                         0,0,0,0,"Times New Roman");
  962.             hOldFont=SelectObject(AboutDC,hNewFont);
  963.             SetTextColor(AboutDC,PALETTEINDEX(0));
  964.             sprintf(szMessage,"Bare's");
  965.             TextOut(AboutDC,200,30,szMessage,strlen(szMessage));
  966.             sprintf(szMessage,"Mandelbrot");
  967.             TextOut(AboutDC,200,75,szMessage,strlen(szMessage));
  968.             sprintf(szMessage,"Program");
  969.             TextOut(AboutDC,250,115,szMessage,strlen(szMessage));
  970.             SelectObject(AboutDC,hOldFont);
  971.             DeleteObject(hNewFont);
  972.  
  973.             ReleaseDC(hdlg,AboutDC);
  974.             return FALSE;
  975.             break;
  976.         case WM_COMMAND:
  977.             switch (wParam) {
  978.                 case IDOK:
  979.                     EndDialog(hdlg,TRUE);
  980.                     break;
  981.                 default:
  982.                     return FALSE;
  983.             }
  984.             break;
  985.         default:
  986.             return FALSE;
  987.     }
  988.     return TRUE;
  989. }
  990.  
  991. /***********************************************
  992.  *  OptionsDlgProc                             *
  993.  *                                             *
  994.  *   Process messages to the Options window.   *
  995.  *                                             *
  996.  ***********************************************/
  997. BOOL FAR PASCAL _export OptionsDlgProc(HWND hdlg, UINT messg, WPARAM wParam,
  998.                                                     LPARAM lParam)
  999. {
  1000.     char szMessage[80];
  1001.  
  1002.     switch (messg) {
  1003.         case WM_INITDIALOG:
  1004.             sprintf(szMessage,"%u",iMaxDel);
  1005.             SetDlgItemText(hdlg,IDC_MAXITER,szMessage);
  1006.             sprintf(szMessage,"%.10f",topMand);
  1007.             SetDlgItemText(hdlg,IDC_TOP,szMessage);
  1008.             sprintf(szMessage,"%.10f",leftMand);
  1009.             SetDlgItemText(hdlg,IDC_LEFT,szMessage);
  1010.             sprintf(szMessage,"%.10f",botMand);
  1011.             SetDlgItemText(hdlg,IDC_BOT,szMessage);
  1012.             sprintf(szMessage,"%.10f",rightMand);
  1013.             SetDlgItemText(hdlg,IDC_RIGHT,szMessage);
  1014.             break;
  1015.         case WM_COMMAND:
  1016.             switch (wParam) {
  1017.                 case IDOK:
  1018.                     GetDlgItemText(hdlg,IDC_MAXITER,szMessage,80);
  1019.                     if (sscanf(szMessage,"%u",&iMaxDel)!=1) {
  1020.                         MessageBox(hdlg,"Maximum iterations can be any "
  1021.                                                 "integer from 1 to 65535.","Error",MB_OK);
  1022.                         break;
  1023.                     }
  1024.                     GetDlgItemText(hdlg,IDC_TOP,szMessage,80);
  1025.                     if (sscanf(szMessage,"%f",&topMand)!=1) {
  1026.                         MessageBox(hdlg,"Re-enter the top coordinate.","Error",MB_OK);
  1027.                         break;
  1028.                     }
  1029.                     topMand = atof(szMessage);
  1030.                     GetDlgItemText(hdlg,IDC_LEFT,szMessage,80);
  1031.                     if (sscanf(szMessage,"%f",&leftMand)!=1) {
  1032.                         MessageBox(hdlg,"Re-enter the left coordinate.","Error",MB_OK);
  1033.                         break;
  1034.                     }
  1035.                     leftMand = atof(szMessage);
  1036.                     GetDlgItemText(hdlg,IDC_RIGHT,szMessage,80);
  1037.                     if (sscanf(szMessage,"%f",&rightMand)!=1) {
  1038.                         MessageBox(hdlg,"Re-enter the right coordinate.","Error",MB_OK);
  1039.                         break;
  1040.                     }
  1041.                     rightMand = atof(szMessage);
  1042.                     GetDlgItemText(hdlg,IDC_BOT,szMessage,80);
  1043.                     if (sscanf(szMessage,"%f",&botMand)!=1) {
  1044.                         MessageBox(hdlg,"Re-enter the bottom coordinate.","Error",MB_OK);
  1045.                         break;
  1046.                     }
  1047.                     botMand = atof(szMessage);
  1048.                     EndDialog(hdlg,TRUE);
  1049.                     break;
  1050.                 case IDCANCEL:
  1051.                     EndDialog(hdlg,TRUE);
  1052.                     break;
  1053.                 default:
  1054.                     return FALSE;
  1055.             }
  1056.             break;
  1057.         default:
  1058.             return FALSE;
  1059.     }
  1060.     return TRUE;
  1061. }
  1062.  
  1063.