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

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

unix.superglobalmegacorp.com

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