Annotation of mstools/samples/rpc/mandel/mandel.c, revision 1.1.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.