Annotation of mstools/samples/rpc/mandel/mandel.c, revision 1.1

1.1     ! root        1: /****************************************************************************
        !             2: 
        !             3:     MANDEL.C --
        !             4: 
        !             5:     Main code for the Windows Mandelbrot Set distributed drawing program.
        !             6: 
        !             7:     Copyright (C) 1990 Microsoft Corporation.
        !             8: 
        !             9:     This code sample is provided for demonstration purposes only.
        !            10:     Microsoft makes no warranty, either express or implied,
        !            11:     as to its usability in any given situation.
        !            12: 
        !            13: ****************************************************************************/
        !            14: 
        !            15: #include <sys\types.h>
        !            16: #include <sys\stat.h>
        !            17: #include <direct.h>
        !            18: #include <dos.h>
        !            19: #include <string.h>
        !            20: #include <ctype.h>
        !            21: #include <malloc.h>   // malloc, free
        !            22: #include <stdio.h>
        !            23: #include <stdlib.h>
        !            24: #include <time.h>
        !            25: 
        !            26: #ifdef RPC
        !            27: #include <rpc.h>
        !            28: #include "mdlrpc.h"
        !            29: #endif
        !            30: 
        !            31: #include <windows.h>               /* Required for all Windows applications */
        !            32: #include "mandel.h"                /* Specific to this program              */
        !            33: 
        !            34: #define MENUNAME            "MandelMenu"
        !            35: #define CLASSNAME           "MandelClass"
        !            36: #define ABOUTBOX            "AboutBox"
        !            37: #define SAVEBOX             "SAVEBOX"
        !            38: 
        !            39: 
        !            40: #define POLL_TIME           100
        !            41: #define LINES               4
        !            42: 
        !            43: #ifdef RPC
        !            44: char szTitle[] = "Mandelbrot RPC";
        !            45: #else
        !            46: char szTitle[] = "Mandelbrot Standalone";
        !            47: #endif
        !            48: 
        !            49: char szBitmap[] = "Mandel";
        !            50: 
        !            51: CPOINT  cptUL = { (double) -2.05, (double) 1.4 };
        !            52: double  dPrec = (double) .01;
        !            53: 
        !            54: void PaintLine( HWND, svr_table *, HDC, int);
        !            55: COLORREF MapColor( DWORD, DWORD );
        !            56: void DrawRect( HWND, PRECT, BOOL, HDC);
        !            57: long get_drivemap(void);
        !            58: void set_dlgitems(HWND, char *, long);
        !            59: BOOL update_curdir(HWND, char *, long);
        !            60: char * getdcwd( int, char *, unsigned);
        !            61: void set_filename( HWND );
        !            62: BOOL munge_path( char *);
        !            63: 
        !            64: HANDLE hInst;                      /* current instance                      */
        !            65: 
        !            66: int iLines = LINES;
        !            67: svr_table SvrTable[20];
        !            68: int SvrTableSz = 0;
        !            69: 
        !            70: #define NCOLORS 11
        !            71: int fContinueZoom = TRUE;
        !            72: int fZoomIn = TRUE;
        !            73: int Histogram[4][4][NCOLORS+1] = {0};  /* split current picture into 16 regions */
        !            74:     /* zoom on most complex region; region with most colors represented */
        !            75: int ColorCount[4][4] = {0};
        !            76: int Max[4][4] = { 0 };
        !            77: int iHistMaxI = 2;
        !            78: int iHistMaxJ = 3;
        !            79: RECT rcZoom;
        !            80: BOOL fRectDefined = FALSE;
        !            81: 
        !            82: 
        !            83: /*
        !            84:  *
        !            85:  *  FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
        !            86:  *
        !            87:  *  PURPOSE: Calls initialization function, processes message loop
        !            88:  *
        !            89:  *  COMMENTS:
        !            90:  *
        !            91:  *      Windows recognizes this function by name as the initial entry point
        !            92:  *      for the program.  This function calls the application initialization
        !            93:  *      routine, if no other instance of the program is running, and always
        !            94:  *      calls the instance initialization routine.  It then executes a message
        !            95:  *      retrieval and dispatch loop that is the top-level control structure
        !            96:  *      for the remainder of execution.  The loop is terminated when a WM_QUIT
        !            97:  *      message is received, at which time this function exits the application
        !            98:  *      instance by returning the value passed by PostQuitMessage().
        !            99:  *
        !           100:  *      If this function must abort before entering the message loop, it
        !           101:  *      returns the conventional value NULL.
        !           102:  *
        !           103:  */
        !           104: 
        !           105: int APIENTRY WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
        !           106: HANDLE hInstance;                           /* current instance             */
        !           107: HANDLE hPrevInstance;                       /* previous instance            */
        !           108: LPSTR lpCmdLine;                            /* command line                 */
        !           109: int nCmdShow;                               /* show-window type (open/icon) */
        !           110: {
        !           111:     MSG msg;                                /* message                      */
        !           112: 
        !           113:     UNREFERENCED_PARAMETER(lpCmdLine);
        !           114: 
        !           115: // add a runtime exception handler for RPC version
        !           116: // see below for additional exception handling code
        !           117: #ifdef RPC
        !           118: RpcTryExcept {
        !           119: #endif
        !           120: 
        !           121:     if (!hPrevInstance)                         /* Other instances of app running? */
        !           122:        if (!InitApplication(hInstance)) /* Initialize shared things */
        !           123:            return (FALSE);              /* Exits if unable to initialize     */
        !           124: 
        !           125:     /* Perform initializations that apply to a specific instance */
        !           126: 
        !           127:     if (!InitInstance(hInstance, nCmdShow))
        !           128:         return (FALSE);
        !           129: 
        !           130:     /* Acquire and dispatch messages until a WM_QUIT message is received. */
        !           131: 
        !           132: 
        !           133:     while (GetMessage(&msg,       /* message structure                      */
        !           134:            NULL,                  /* handle of window receiving the message */
        !           135:            0,                     /* lowest message to examine              */
        !           136:            0))                    /* highest message to examine             */
        !           137:     {
        !           138:        TranslateMessage(&msg);    /* Translates virtual key codes           */
        !           139:        DispatchMessage(&msg);     /* Dispatches message to window           */
        !           140:     }
        !           141: 
        !           142:     return (msg.wParam);          /* Returns the value from PostQuitMessage */
        !           143: 
        !           144: // add a runtime exception handler for RPC version
        !           145: // see above for additional exception handling code
        !           146: #ifdef RPC
        !           147: } // end of RpcTryExcept statements
        !           148: RpcExcept(1) {
        !           149:     sprintf(pszFail, "Please start the server application.");
        !           150:     MessageBox(msg.hwnd, pszFail, "Mandel Server Not Started",
        !           151:                MB_ICONHAND | MB_SYSTEMMODAL);
        !           152: }
        !           153: RpcEndExcept
        !           154: #endif
        !           155: 
        !           156: }  // end WinMain
        !           157: 
        !           158: 
        !           159: 
        !           160: 
        !           161: /*
        !           162:  *   FUNCTION: InitApplication(HANDLE)
        !           163:  *
        !           164:  *   PURPOSE: Initializes window data and registers window class
        !           165:  *
        !           166:  *   COMMENTS:
        !           167:  *
        !           168:  *       This function is called at initialization time only if no other
        !           169:  *       instances of the application are running.  This function performs
        !           170:  *       initialization tasks that can be done once for any number of running
        !           171:  *       instances.
        !           172:  *
        !           173:  *       In this case, we initialize a window class by filling out a data
        !           174:  *       structure of type WNDCLASS and calling the Windows RegisterClass()
        !           175:  *       function.  Since all instances of this application use the same window
        !           176:  *       class, we only need to do this when the first instance is initialized.
        !           177:  */
        !           178: 
        !           179: BOOL InitApplication(hInstance)
        !           180: HANDLE hInstance;                             /* current instance           */
        !           181: {
        !           182:     WNDCLASS  wc;
        !           183: 
        !           184:     /* Fill in window class structure with parameters that describe the       */
        !           185:     /* main window.                                                           */
        !           186: 
        !           187:     wc.style = 0;                       /* Class style(s).                    */
        !           188:     wc.lpfnWndProc = (WNDPROC)MainWndProc;       /* Function to retrieve messages for  */
        !           189:                                         /* windows of this class.             */
        !           190:     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
        !           191:     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
        !           192:     wc.hInstance = hInstance;           /* Application that owns the class.   */
        !           193:     wc.hIcon = LoadIcon(hInstance, "RPC_ICON");
        !           194:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           195:     wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
        !           196:     wc.lpszMenuName =  MENUNAME;   /* Name of menu resource in .RC file. */
        !           197:     wc.lpszClassName = CLASSNAME; /* Name used in call to CreateWindow. */
        !           198: 
        !           199:     /* Register the window class and return success/failure code. */
        !           200: 
        !           201:     return (RegisterClass(&wc));
        !           202: 
        !           203: }
        !           204: 
        !           205: 
        !           206: 
        !           207: /*
        !           208:  *   FUNCTION:  InitInstance(HANDLE, int)
        !           209:  *
        !           210:  *   PURPOSE:  Saves instance handle and creates main window.
        !           211:  *
        !           212:  *   COMMENTS:
        !           213:  *
        !           214:  *       This function is called at initialization time for every instance of
        !           215:  *       this application.  This function performs initialization tasks that
        !           216:  *       cannot be shared by multiple instances.
        !           217:  *
        !           218:  *       In this case, we save the instance handle in a static variable and
        !           219:  *       create and display the main program window.
        !           220:  */
        !           221: 
        !           222: BOOL InitInstance(hInstance, nCmdShow)
        !           223:     HANDLE          hInstance;          /* Current instance identifier.       */
        !           224:     int             nCmdShow;           /* Param for first ShowWindow() call. */
        !           225: {
        !           226:     HWND            hWnd;               /* Main window handle.                */
        !           227:     RECT            rc;
        !           228: 
        !           229:     /* Save the instance handle in static variable, which will be used in  */
        !           230:     /* many subsequence calls from this application to Windows.            */
        !           231: 
        !           232:     hInst = hInstance;
        !           233: 
        !           234:     /* Create a main window for this application instance.  */
        !           235: 
        !           236:     hWnd = CreateWindow(
        !           237:         CLASSNAME,                      /* See RegisterClass() call.          */
        !           238:         szTitle,                        /* Text for window title bar.         */
        !           239:         WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX,
        !           240:         CW_USEDEFAULT,                  /* Default horizontal position.       */
        !           241:         CW_USEDEFAULT,                  /* Default vertical position.         */
        !           242:         WIDTH,                          /* Default width.                     */
        !           243:         HEIGHT,                         /* Default height.                    */
        !           244:         NULL,                           /* Overlapped windows have no parent. */
        !           245:         NULL,                           /* Use the window class menu.         */
        !           246:         hInstance,                      /* This instance owns this window.    */
        !           247:         NULL                            /* Pointer not needed.                */
        !           248:     );
        !           249: 
        !           250:     /* If window could not be created, return "failure" */
        !           251: 
        !           252:     if (!hWnd)
        !           253:         return (FALSE);
        !           254: 
        !           255:     /* Make the window visible; update its client area; and return "success" */
        !           256: 
        !           257:     ShowWindow(hWnd, nCmdShow);  /* Show the window                        */
        !           258:     UpdateWindow(hWnd);          /* Sends WM_PAINT message                 */
        !           259: 
        !           260:     rc.top = rc.left = 0;
        !           261:     rc.bottom = HEIGHT-1;
        !           262:     rc.right = WIDTH-1;
        !           263: 
        !           264:     SetNewCalc(cptUL, dPrec, rc);
        !           265: 
        !           266:     return (TRUE);               /* Returns the value from PostQuitMessage */
        !           267: }
        !           268: 
        !           269: 
        !           270: 
        !           271: /*
        !           272:  *   FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
        !           273:  *
        !           274:  *   PURPOSE:  Processes messages
        !           275:  *
        !           276:  *   MESSAGES:
        !           277:  *
        !           278:  *     WM_COMMAND    - application menu (About dialog box)
        !           279:  *     WM_DESTROY    - destroy window
        !           280:  *
        !           281:  *   COMMENTS:
        !           282:  *
        !           283:  *     To process the IDM_ABOUT message, call MakeProcInstance() to get
        !           284:  *      the current instance address of the About() function, then call
        !           285:  *      DialogBox to create the box according to the information in the
        !           286:  *     MANDEL.RC file and turn control over to the About() function.
        !           287:  *     When it returns, free the intance address.
        !           288:  */
        !           289: 
        !           290: LONG APIENTRY MainWndProc(
        !           291: HWND hWnd,                               /* window handle                   */
        !           292: UINT message,                            /* type of message                 */
        !           293: UINT wParam,                             /* additional information          */
        !           294: LONG lParam)                             /* additional information          */
        !           295: {
        !           296:     FARPROC lpProcAbout;                 /* pointer to the "About" function */
        !           297:     PAINTSTRUCT ps;
        !           298:     HDC hdc;
        !           299:     static HDC  hdcMem;
        !           300:     static HBITMAP hbmMem;
        !           301:     static int width;
        !           302:     static int height;
        !           303:     RECT        rc;
        !           304:     static BOOL fButtonDown = FALSE;
        !           305:     static POINT pSelected;
        !           306:     POINT       pMove;
        !           307:     int         iWidthNew;
        !           308:     int         iHeightNew;
        !           309:     static int  miOldLines;
        !           310:     double      scaling;
        !           311: 
        !           312:     switch (message)
        !           313:     {
        !           314: 
        !           315:         case WM_CREATE:
        !           316:             if (!InitRemote(hWnd))
        !           317:                 return FALSE;
        !           318: 
        !           319:             InitHistogram();
        !           320: 
        !           321:             hdc = GetDC(hWnd);
        !           322:             hdcMem = CreateCompatibleDC(hdc);
        !           323:             GetWindowRect(hWnd, &rc);
        !           324:             width = rc.right - rc.left;
        !           325:             height = rc.bottom - rc.top;
        !           326:             hbmMem = CreateCompatibleBitmap(hdc, width, height);
        !           327:             SelectObject(hdcMem, hbmMem);
        !           328: 
        !           329:             ReleaseDC(hWnd,hdc);
        !           330: 
        !           331:             rc.left = rc.top = 0;
        !           332:             rc.right = width+1;
        !           333:             rc.bottom = height + 1;
        !           334:             FillRect(hdcMem, &rc, GetStockObject(WHITE_BRUSH));
        !           335: 
        !           336:             SetTimer(hWnd, 1, POLL_TIME, NULL);  // set timer for polls
        !           337: 
        !           338:             CheckMenuItem(GetMenu(hWnd), IDM_4LINES, MF_CHECKED);
        !           339:             CheckMenuItem(GetMenu(hWnd), IDM_CONTINUOUS, MF_CHECKED);
        !           340:             miOldLines = IDM_4LINES;  // save to uncheck
        !           341: 
        !           342:             break;
        !           343: 
        !           344:         case WM_PAINT:
        !           345:             hdc = BeginPaint(hWnd, &ps);
        !           346:             BitBlt(hdc, ps.rcPaint.left,
        !           347:                    ps.rcPaint.top,
        !           348:                    ps.rcPaint.right - ps.rcPaint.left,
        !           349:                    ps.rcPaint.bottom - ps.rcPaint.top,
        !           350:                    hdcMem, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
        !           351:             EndPaint(hWnd, &ps);
        !           352:             break;
        !           353: 
        !           354:        case WM_COMMAND:           /* message: command from application menu */
        !           355:             switch(wParam)
        !           356:            {
        !           357: 
        !           358:             case IDM_ABOUT:
        !           359:                lpProcAbout = MakeProcInstance((FARPROC)About, hInst);
        !           360: 
        !           361:                DialogBox(hInst,                 /* current instance         */
        !           362:                    ABOUTBOX,                    /* resource to use          */
        !           363:                    hWnd,                        /* parent handle            */
        !           364:                    (WNDPROC)lpProcAbout);               /* About() instance address */
        !           365: 
        !           366:                FreeProcInstance(lpProcAbout);
        !           367:                break;
        !           368: 
        !           369:             case IDM_ZOOMOUT:
        !           370:                 if (dPrec > (double)MAXPREC)  // don't allow the zoom out
        !           371:                     break;
        !           372:                 rcZoom.left = WIDTH/4 + (WIDTH/8);       // center square
        !           373:                 rcZoom.top   = HEIGHT/4 + (HEIGHT/8);
        !           374:                 rcZoom.right = rcZoom.left + (WIDTH/4);
        !           375:                 rcZoom.bottom = rcZoom.top + (HEIGHT/4);
        !           376: 
        !           377:                 cptUL.real -= (rcZoom.left * dPrec); // inverse of zoom in
        !           378:                 cptUL.imag += (rcZoom.top * dPrec);
        !           379:                iWidthNew = (rcZoom.right - rcZoom.left + 1);
        !           380:                iHeightNew = (rcZoom.bottom - rcZoom.top + 1);
        !           381:                scaling =
        !           382:                  ( (double) ((iWidthNew > iHeightNew) ? iWidthNew : iHeightNew)
        !           383:                   / (double)width);
        !           384:                 dPrec /= scaling;
        !           385: 
        !           386:                 rc.left = rc.top = 0;
        !           387:                 rc.bottom = height - 1;
        !           388:                 rc.right = width - 1;
        !           389: 
        !           390:                 SetNewCalc(cptUL, dPrec, rc);
        !           391:                 fRectDefined = FALSE;
        !           392:                 DoSomeWork(hWnd, FALSE);
        !           393:                 break;
        !           394: 
        !           395:             case IDM_ZOOMIN:            // zoom in on selected rectangle
        !           396:                 // if no rectangle, don't zoom in
        !           397:                 if (!fRectDefined)
        !           398:                     break;
        !           399:                 if (dPrec < (double)MINPREC)  // don't allow zoom in
        !           400:                     break;
        !           401:                 DrawRect(hWnd, &rcZoom, TRUE, hdcMem);  // draw new rect
        !           402: 
        !           403:                 // calculate new upper-left
        !           404:                 cptUL.real += (rcZoom.left * dPrec);
        !           405:                 cptUL.imag -= (rcZoom.top * dPrec);
        !           406: 
        !           407:                iWidthNew = (rcZoom.right - rcZoom.left + 1);
        !           408:                iHeightNew = (rcZoom.bottom - rcZoom.top + 1);
        !           409:                scaling =
        !           410:                  ( (double) ((iWidthNew > iHeightNew) ? iWidthNew : iHeightNew)
        !           411:                   / (double)width);
        !           412: 
        !           413:                dPrec *= scaling;
        !           414: 
        !           415:                 rc.left = rc.top = 0;
        !           416:                 rc.bottom = height - 1;
        !           417:                 rc.right = width - 1;
        !           418: 
        !           419:                 SetNewCalc( cptUL, dPrec, rc);
        !           420:                 IncPictureID();
        !           421: 
        !           422:                 fRectDefined = FALSE;
        !           423:                 DoSomeWork(hWnd, FALSE);
        !           424:                 break;
        !           425: 
        !           426:             case IDM_CONTINUOUS:  // continuous zoom in
        !           427:                 if (fContinueZoom == TRUE) {
        !           428:                    CheckMenuItem(GetMenu(hWnd), IDM_CONTINUOUS, MF_UNCHECKED);
        !           429:                    fContinueZoom = FALSE;
        !           430:                 }
        !           431:                 else {
        !           432:                    CheckMenuItem(GetMenu(hWnd), IDM_CONTINUOUS, MF_CHECKED);
        !           433:                    fContinueZoom = TRUE;
        !           434:                 }
        !           435:                 break;
        !           436: 
        !           437:             case IDM_REDRAW:
        !           438:                 if (fContinueZoom == TRUE)
        !           439:                     InitHistogram();
        !           440:                 rc.left = rc.top = 0;
        !           441:                 rc.right = width+1;
        !           442:                 rc.bottom = height + 1;
        !           443:                 FillRect(hdcMem, &rc, GetStockObject(WHITE_BRUSH));
        !           444:                 InvalidateRect(hWnd, NULL, TRUE);
        !           445: 
        !           446:                 rc.left = rc.top = 0;
        !           447:                 rc.bottom = height - 1;
        !           448:                 rc.right = width - 1;
        !           449:                 SetNewCalc( cptUL, dPrec, rc);
        !           450: 
        !           451:                 fRectDefined = FALSE;
        !           452:                 DoSomeWork(hWnd, FALSE);
        !           453:                 break;
        !           454: 
        !           455:             case IDM_EXIT:
        !           456:                 DestroyWindow(hWnd);
        !           457:                 break;
        !           458: 
        !           459:             case IDM_TOP:
        !           460:                 cptUL.real = (double) -2.05;
        !           461:                 cptUL.imag = (double) 1.4;
        !           462:                 dPrec = .01;
        !           463: 
        !           464:                 rc.left = rc.top = 0;
        !           465:                 rc.bottom = height - 1;
        !           466:                 rc.right = width - 1;
        !           467:                 SetNewCalc( cptUL, dPrec, rc);
        !           468:                 cPictureID = 0; // incremented past original
        !           469: 
        !           470:                 fRectDefined = FALSE;
        !           471:                 DoSomeWork(hWnd, FALSE);
        !           472:                 break;
        !           473: 
        !           474:             case IDM_1LINE:
        !           475:             case IDM_2LINES:
        !           476:             case IDM_4LINES:
        !           477:             case IDM_8LINES:
        !           478:             case IDM_16LINES:
        !           479:             case IDM_32LINES:
        !           480: 
        !           481:                 CheckMenuItem(GetMenu(hWnd), miOldLines, MF_UNCHECKED);
        !           482:                 miOldLines = wParam;
        !           483:                 switch(wParam)
        !           484:                {
        !           485:                 case IDM_1LINE:
        !           486:                     iLines = 1;
        !           487:                     break;
        !           488:                 case IDM_2LINES:
        !           489:                     iLines = 2;
        !           490:                     break;
        !           491:                 case IDM_4LINES:
        !           492:                     iLines = 4;
        !           493:                     break;
        !           494:                 case IDM_8LINES:
        !           495:                     iLines = 8;
        !           496:                     break;
        !           497:                 case IDM_16LINES:
        !           498:                     iLines = 16;
        !           499:                     break;
        !           500:                 case IDM_32LINES:
        !           501:                     iLines = 32;
        !           502:                 }
        !           503: 
        !           504:                 CheckMenuItem(GetMenu(hWnd), miOldLines, MF_CHECKED);
        !           505:                 break;
        !           506: 
        !           507: 
        !           508:            default:                        /* Lets Windows process it       */
        !           509:                return (DefWindowProc(hWnd, message, wParam, lParam));
        !           510:             }
        !           511:             break;
        !           512: 
        !           513:        case WM_DESTROY:                  /* message: window being destroyed */
        !           514:            PostQuitMessage(0);
        !           515:             DeleteDC(hdcMem);
        !           516:             DeleteObject(hbmMem);
        !           517:            break;
        !           518: 
        !           519:         case WM_DOSOMEWORK:
        !           520:             // do another slice of calculation work
        !           521:             DoSomeWork(hWnd, FALSE);
        !           522:             break;
        !           523: 
        !           524:         case WM_PAINTLINE:
        !           525:             // The shared buffer contains a line of data; draw it
        !           526:             PaintLine(hWnd,
        !           527:                      (svr_table *)&SvrTable[(signed int)wParam],
        !           528:                      hdcMem,
        !           529:                      height);
        !           530:             break;
        !           531: 
        !           532:         case WM_TIMER:
        !           533:             // timer means we should do another slice of work
        !           534:             DoSomeWork(hWnd, TRUE);
        !           535:             break;
        !           536: 
        !           537:         case WM_LBUTTONDOWN:
        !           538:             // left button down; start to define a zoom rectangle
        !           539: 
        !           540:             if (fRectDefined)
        !           541:                 DrawRect(hWnd, &rcZoom, FALSE, hdcMem); // undraw old rectangle
        !           542: 
        !           543:             // initialize rectangle
        !           544:             rcZoom.left = rcZoom.right = pSelected.x = LOWORD(lParam);
        !           545:             rcZoom.top = rcZoom.bottom = pSelected.y = HIWORD(lParam);
        !           546: 
        !           547:             // draw the new rectangle
        !           548:             DrawRect(hWnd, &rcZoom, TRUE, hdcMem);
        !           549: 
        !           550:             fRectDefined = TRUE;
        !           551:             fButtonDown = TRUE;
        !           552:             SetCapture(hWnd);       // capture all mouse events
        !           553:             break;
        !           554: 
        !           555:         case WM_MOUSEMOVE:
        !           556: 
        !           557:             // mouse move -- if the button is down, change the rect
        !           558:             if (!fButtonDown)
        !           559:                 break;
        !           560: 
        !           561:             DrawRect(hWnd, &rcZoom, FALSE, hdcMem); // undraw old rect
        !           562: 
        !           563:             pMove.x = LOWORD(lParam);
        !           564:             pMove.y = HIWORD(lParam);
        !           565: 
        !           566:             // update the selection rectangle
        !           567:             if (pMove.x <= pSelected.x)
        !           568:                 rcZoom.left = pMove.x;
        !           569:             if (pMove.x >= pSelected.x)
        !           570:                 rcZoom.right = pMove.x;
        !           571:             if (pMove.y <= pSelected.y)
        !           572:                 rcZoom.top = pMove.y;
        !           573:             if (pMove.y >= pSelected.y)
        !           574:                 rcZoom.bottom = pMove.y;
        !           575: 
        !           576:             DrawRect(hWnd, &rcZoom, TRUE, hdcMem);  // draw new rect
        !           577:             break;
        !           578: 
        !           579:        case WM_LBUTTONUP:
        !           580:           // button up; end selection
        !           581:            fButtonDown = FALSE;
        !           582:            ReleaseCapture();
        !           583:            break;
        !           584: 
        !           585:        default: /* Passes it on if unproccessed    */
        !           586:            return (DefWindowProc(hWnd, message, wParam, lParam));
        !           587:     }
        !           588:     return (0L);
        !           589: }
        !           590: 
        !           591: 
        !           592: 
        !           593: /*
        !           594:  *   FUNCTION: About(HWND, unsigned, WORD, LONG)
        !           595:  *
        !           596:  *   PURPOSE:  Processes messages for "About" dialog box
        !           597:  *
        !           598:  *   MESSAGES:
        !           599:  *
        !           600:  *     WM_INITDIALOG - initialize dialog box
        !           601:  *     WM_COMMAND    - Input received
        !           602:  *
        !           603:  *   COMMENTS:
        !           604:  *
        !           605:  *     No initialization is needed for this particular dialog box, but TRUE
        !           606:  *     must be returned to Windows.
        !           607:  *
        !           608:  *     Wait for user to click on "Ok" button, then close the dialog box.
        !           609:  */
        !           610: 
        !           611: BOOL APIENTRY About(
        !           612: HWND hDlg,                                /* window handle of the dialog box */
        !           613: UINT message,                         /* type of message                 */
        !           614: UINT wParam,                              /* message-specific information    */
        !           615: LONG lParam)
        !           616: {
        !           617:     UNREFERENCED_PARAMETER(lParam);
        !           618: 
        !           619:     switch (message)
        !           620:     {
        !           621:        case WM_INITDIALOG:                /* message: initialize dialog box */
        !           622: 
        !           623:            return (TRUE);
        !           624: 
        !           625:        case WM_COMMAND:                      /* message: received a command */
        !           626:            if (wParam == IDOK                /* "OK" box selected?          */
        !           627:                 || wParam == IDCANCEL)        /* System menu close command? */
        !           628:            {
        !           629:                EndDialog(hDlg, TRUE);        /* Exits the dialog box        */
        !           630:                return (TRUE);
        !           631:            }
        !           632:            break;
        !           633:     }
        !           634:     return (FALSE);                          /* Didn't process a message    */
        !           635: }
        !           636: 
        !           637: 
        !           638: 
        !           639: 
        !           640: /*
        !           641:  *  DoSomeWork --
        !           642:  *
        !           643:  *  This function does our work for us. It does it in little pieces, and
        !           644:  *  will schedule itself as it sees fit.
        !           645:  */
        !           646: 
        !           647: void
        !           648: DoSomeWork( HWND    hwnd,
        !           649:             BOOL    fTimer)
        !           650: {
        !           651: 
        !           652:     static WORD   wIteration = 0;
        !           653: 
        !           654:     if (fTimer) {
        !           655:         wIteration++;
        !           656: 
        !           657:         // on every nth tick, we send out a poll
        !           658:         if (wIteration == 120) {       // tune this?
        !           659:             wIteration = 0;
        !           660:             return;
        !           661:         }
        !           662: 
        !           663:         // on the half-poll, we check for responses
        !           664:         if ((wIteration == 2) || (wIteration == 10)) {
        !           665:             return;
        !           666:         }
        !           667: 
        !           668:     }
        !           669: 
        !           670:     if (CheckDrawStatus(hwnd))
        !           671:         SendMessage(hwnd, WM_DOSOMEWORK, 0, 0L);
        !           672: 
        !           673:     return;
        !           674: }
        !           675: 
        !           676: 
        !           677: 
        !           678: /*
        !           679:  *  DrawRect --
        !           680:  *
        !           681:  *  This function draws (or undraws) the zoom rectangle.
        !           682:  */
        !           683: 
        !           684: void
        !           685: DrawRect( HWND      hwnd,
        !           686:           PRECT     prc,
        !           687:           BOOL      fDrawIt,
        !           688:           HDC       hdcBM)
        !           689: {
        !           690: 
        !           691:     HDC hdc;
        !           692:     DWORD   dwRop;
        !           693: 
        !           694:     hdc = GetDC(hwnd);
        !           695: 
        !           696:     if (fDrawIt)
        !           697:         dwRop = NOTSRCCOPY;
        !           698:     else
        !           699:         dwRop = SRCCOPY;
        !           700: 
        !           701: 
        !           702:     // top side
        !           703:     BitBlt(hdc, prc->left, prc->top, (prc->right - prc->left) + 1,
        !           704:                 1, hdcBM, prc->left, prc->top, dwRop);
        !           705: 
        !           706:     // bottom side
        !           707:     BitBlt(hdc, prc->left, prc->bottom, (prc->right - prc->left) + 1,
        !           708:                 1, hdcBM, prc->left, prc->bottom, dwRop);
        !           709: 
        !           710:     // left side
        !           711:     BitBlt(hdc,prc->left, prc->top, 1, (prc->bottom - prc->top) + 1,
        !           712:                 hdcBM, prc->left, prc->top, dwRop);
        !           713: 
        !           714:     // right side
        !           715:     BitBlt(hdc,prc->right, prc->top, 1, (prc->bottom - prc->top) + 1,
        !           716:                 hdcBM, prc->right, prc->top, dwRop);
        !           717: 
        !           718:     ReleaseDC(hwnd, hdc);
        !           719: }
        !           720: 
        !           721: 
        !           722: 
        !           723: /*
        !           724:  *  PaintLine --
        !           725:  *
        !           726:  *  This function paints a buffer of data into the bitmap.
        !           727:  */
        !           728: 
        !           729: void
        !           730: PaintLine(  HWND    hwnd,
        !           731:             svr_table * pst,
        !           732:             HDC     hdcBM,
        !           733:             int     cHeight)
        !           734: {
        !           735: 
        !           736:     PWORD   pwDrawData;
        !           737:     int     y;
        !           738:     int     x;
        !           739:     DWORD   dwThreshold;
        !           740:     RECT    rc;
        !           741:     WORD    lines;
        !           742: 
        !           743:     lines  = (WORD) pst->cLines;
        !           744: 
        !           745:     // picture ID had better match, or else we skip it
        !           746:     if (CheckDrawingID(pst->cPicture))
        !           747:     {
        !           748:         // figure out our threshold
        !           749:         dwThreshold = QueryThreshold();
        !           750: 
        !           751:         // get a pointer to the draw buffer
        !           752:         pwDrawData = (PWORD)GetDrawBuffer();
        !           753:         if (pwDrawData == NULL) {
        !           754:             ReturnDrawBuffer();
        !           755:             return;
        !           756:         }
        !           757: 
        !           758:         // starting x coordinate
        !           759:         x = (int) pst->dwLine;
        !           760: 
        !           761:         // now loop through the rectangle
        !           762:         while (lines-- > 0)
        !           763:         {
        !           764:             // bottom to top, since that's the order of the data in the buffer
        !           765:             y = (int) cHeight-1;
        !           766: 
        !           767: 
        !           768:             while (y >= 0) {
        !           769:                 // draw a pixel
        !           770:                 SetPixel(hdcBM, x,y, MapColor((DWORD)*pwDrawData, dwThreshold));
        !           771:                 if (fContinueZoom == TRUE)
        !           772:                     CalcHistogram(x, y, (DWORD)*pwDrawData, dwThreshold);
        !           773:                 // now increment buffer pointer and y coord
        !           774:                 y--;
        !           775:                 pwDrawData++;
        !           776:             }
        !           777:             x++;        // increment X coordinate
        !           778:         }
        !           779: 
        !           780:         // figure out the rectangle to invalidate
        !           781:         rc.top = 0;
        !           782:         rc.bottom = cHeight;
        !           783:         rc.left = (int)(pst->dwLine);
        !           784:         rc.right = (int)(pst->dwLine) + pst->cLines;
        !           785: 
        !           786:         FreeDrawBuffer();
        !           787: 
        !           788:         // and invalidate it on the screen so we redraw it
        !           789:         InvalidateRect(hwnd, &rc, FALSE);
        !           790:     }
        !           791: 
        !           792:     // free this for someone else to use
        !           793:     ReturnDrawBuffer();
        !           794: 
        !           795:     // and change the pipe state, if necessary
        !           796:     if (pst->iStatus == SS_PAINTING)
        !           797:         pst->iStatus = SS_IDLE;
        !           798: 
        !           799: }
        !           800: 
        !           801: 
        !           802: #define CLR_BLACK       RGB(0,0,0)
        !           803: #define CLR_DARKBLUE    RGB(0,0,127)
        !           804: #define CLR_BLUE        RGB(0,0,255)
        !           805: #define CLR_CYAN        RGB(0,255,255)
        !           806: #define CLR_DARKGREEN   RGB(0,127,0)
        !           807: #define CLR_GREEN       RGB(0,255,0)
        !           808: #define CLR_YELLOW      RGB(255,255,0)
        !           809: #define CLR_RED         RGB(255,0,0)
        !           810: #define CLR_DARKRED     RGB(127,0,0)
        !           811: #define CLR_WHITE       RGB(255,255,255)
        !           812: #define CLR_PALEGRAY    RGB(194,194,194)
        !           813: #define CLR_DARKGRAY    RGB(127,127,127)
        !           814: 
        !           815: 
        !           816: static COLORREF        ColorMapTable[] = {     // size = NCOLORS
        !           817:     CLR_DARKBLUE,
        !           818:     CLR_BLUE,
        !           819:     CLR_CYAN,
        !           820:     CLR_DARKGREEN,
        !           821:     CLR_GREEN,
        !           822:     CLR_YELLOW,
        !           823:     CLR_RED,
        !           824:     CLR_DARKRED,
        !           825:     CLR_WHITE,
        !           826:     CLR_PALEGRAY,
        !           827:     CLR_DARKGRAY};
        !           828: 
        !           829: 
        !           830: /*
        !           831:  *  MapColor --
        !           832:  *
        !           833:  *  This function maps an iteration count into a corresponding RGB color.
        !           834:  */
        !           835: 
        !           836: COLORREF
        !           837: MapColor(DWORD  dwIter,
        !           838:          DWORD  dwThreshold)
        !           839: {
        !           840: 
        !           841:     // if it's beyond the threshold, call it black
        !           842:     if (dwIter >= dwThreshold) {
        !           843:        return CLR_BLACK;
        !           844:     }
        !           845: 
        !           846:     // get a modulus based on the number of colors
        !           847:     dwIter = (dwIter / 3) % NCOLORS; // 11;
        !           848: 
        !           849:     // and return the appropriate color
        !           850:     return ColorMapTable[dwIter];
        !           851: 
        !           852: }
        !           853: /* CalcHistogram
        !           854:  * This function is used to select the region that is the
        !           855:  * most complex and will be used to zoom in for the next picture;
        !           856:  * it contains the most colors.  The number of colors are counted.
        !           857:  */
        !           858: 
        !           859: void
        !           860: CalcHistogram(int  x,
        !           861:          int       y,
        !           862:          DWORD  dwIter,
        !           863:          DWORD  dwThreshold)
        !           864: {
        !           865: 
        !           866:     // if it's beyond the threshold, call it black
        !           867:     if (dwIter >= dwThreshold) {
        !           868:         Histogram[x/(WIDTH/4)][y/(HEIGHT/4)][NCOLORS]++;
        !           869:        return;
        !           870:     }
        !           871:     // get a modulus based on the number of colors
        !           872:     dwIter = (dwIter / 3) % NCOLORS; // 11;
        !           873: 
        !           874:     // and bump the count for the appropriate color
        !           875:     Histogram[x/(WIDTH/4)][y/(HEIGHT/4)][dwIter]++;  // region of map
        !           876: 
        !           877:     return;
        !           878: 
        !           879: }
        !           880: 
        !           881: 
        !           882: /* InitHistogram
        !           883:  * This function initializes the histogram data structures.
        !           884:  */
        !           885: 
        !           886: void InitHistogram(void)
        !           887: {
        !           888:     int i, j, k;
        !           889: 
        !           890:     for (i = 0; i < 4; i++)
        !           891:         for (j = 0; j < 4; j++)
        !           892:             for (k = 0; k <= NCOLORS; k++)
        !           893:                 Histogram[i][j][k] = 0;  /* count of colors */
        !           894: }
        !           895: 
        !           896: /* CountHistogram
        !           897:  * This function determines the number of colors represented
        !           898:  * within a region.  The region with the most colors is
        !           899:  * selected using the maxi and maxj values.  X and Y coordinates
        !           900:  * corresponding to these regions are stored in the HistRegion
        !           901:  * table and are used for the next picture.
        !           902:  */
        !           903: 
        !           904: void CountHistogram(void)
        !           905: {
        !           906:     int i, j, k;
        !           907:     /* count the number of colors in each region */
        !           908:     /* find the color that dominates each region */
        !           909:     for (i = 0; i < 4; i++) {
        !           910:         for (j = 0; j < 4; j++) {
        !           911:             ColorCount[i][j] = 0;
        !           912:             Max[i][j] = 0;
        !           913:             for (k = 0; k <= NCOLORS; k++) {
        !           914:                 if (Histogram[i][j][k] > Max[i][j])
        !           915:                     Max[i][j] = Histogram[i][j][k];
        !           916:                 if (Histogram[i][j][k] != 0)  /* count of colors */
        !           917:                     ColorCount[i][j]++;
        !           918:             }
        !           919: 
        !           920:         }
        !           921:     }
        !           922:     iHistMaxI = 0;
        !           923:     iHistMaxJ = 0;
        !           924:     /* if several regions have the same number of colors, */
        !           925:     /* select the region with the most variety:  the smallest max */
        !           926:     for (i = 0; i < 4; i++) {
        !           927:         for (j = 0; j < 4; j++) {
        !           928:             if ( (ColorCount[i][j] >= ColorCount[iHistMaxI][iHistMaxJ])
        !           929:                 && (Max[i][j] < Max[iHistMaxI][iHistMaxJ]) ) {
        !           930:                 iHistMaxI = i;
        !           931:                 iHistMaxJ = j;
        !           932:             }
        !           933:         }
        !           934:     }
        !           935:     InitHistogram(); /* initialize for next time */
        !           936: 
        !           937: }

unix.superglobalmegacorp.com

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