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

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

unix.superglobalmegacorp.com

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