REMOTE.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:
Windows编程
开发平台:
Visual C++
- /****************************************************************************
- Microsoft RPC Version 2.0
- Copyright Microsoft Corp. 1992, 1993, 1994- 1996
- mandel Example
- FILE: remote.c
- PURPOSE: Client side of the RPC distributed application Mandel
- COMMENTS: Code to do the remote calculations for the Windows
- Mandelbrot Set distributed drawing program.
- Information coming into this module (via API calls) is
- based on upper-left being (0,0) (the Windows standard).
- We translate that to lower-left is (0,0) before we ship
- it out onto the net, and we do reverse translations
- accordingly.
- The iteration data is passed back to the main window
- procedure (by means of a WM_PAINTLINE message) which
- draws the picture.
- A word about the shared buffer: multiple buffers could
- be used, but a single one is used. The buffer is requested
- in this code, and then released after the data has been
- drawn (in PaintLine() in mandel.c). So long as the painting
- is done quickly, this is efficient.
- ****************************************************************************/
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <windows.h>
- #ifdef RPC
- #include "mdlrpc.h"
- #endif
- #include "mandel.h"
- /*
- * External variables
- */
- extern int fBound;
- extern svr_table SvrTable; // the server table
- extern int iLines;
- extern double dPrec;
- extern int fContinueZoom;
- extern int fZoomIn;
- extern int iHistMaxI;
- extern int iHistMaxJ;
- extern RECT rcZoom;
- extern BOOL fRectDefined;
- /*
- * Picture information
- */
- int cPictureID = 0; // picture id, in case we reset in the middle
- static CPOINT cptLL; // upper-left
- static double dPrecision; // precision of draw
- static LONGRECT rclPicture; // rectangle defining client window
- static DWORD dwCurrentLine; // next line to be drawn
- static DWORD dwThreshold; // threshold for iterations
- /*
- * Function prototypes for local procs
- */
- DWORD CalcThreshold(double);
- /*
- * InitRemote --
- *
- * This function initializes everything for our remote connections.
- * It gets the local wksta name (making sure the wksta is started)
- * and it creates the mailslot with which to collect replies to our poll.
- *
- * RETURNS
- * TRUE - initialization succeeded
- * FALSE - initialization failed, can't go on
- */
- BOOL InitRemote(HWND hWnd)
- {
- #ifndef RPC
- UNREFERENCED_PARAMETER(hWnd);
- #endif
- // set up our local entry
- strcpy(SvrTable.name, "Local machine");
- SvrTable.iStatus = SS_LOCAL;
- // good, we succeeded
- return(TRUE);
- }
- /*
- * CheckDrawStatus --
- *
- * This function does a check of all buffers being drawn.
- *
- * If it finds an idle pipe, and there is work to be done, it assigns
- * a line, and writes out the request.
- * If it finds a read-pending pipe, it checks if the read has completed.
- * If it has, it is read and a message is sent so the read data can
- * be processed.
- *
- * RETURNS
- * TRUE - we did a piece of work
- * FALSE - we could not find any work to do.
- */
- BOOL CheckDrawStatus(HWND hwnd)
- {
- CALCBUF cb;
- LPVOID pbBuf;
- while(TRUE) {
- // Check the status
- switch(SvrTable.iStatus) {
- case SS_PAINTING:
- break;
- case SS_IDLE:
- break;
- case SS_LOCAL:
- // Do a chunk of work locally
- #ifdef RPC
- if (fBound == FALSE)
- break;
- #endif
- if ((long) dwCurrentLine > rclPicture.xRight) {
- if (fContinueZoom == TRUE) {
- if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC))
- fZoomIn = FALSE; // start zooming out
- if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC))
- fZoomIn = TRUE;
- if (fZoomIn) {
- CountHistogram();
- rcZoom.top = iHistMaxJ * (WIDTH/4);
- rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1;
- rcZoom.left = iHistMaxI * (HEIGHT/4);
- rcZoom.right = rcZoom.left + (HEIGHT/4) - 1;
- fRectDefined = TRUE;
- PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L);
- }
- else
- PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L);
- }
- break;
- }
- if (TakeDrawBuffer() == FALSE)
- break;
- pbBuf = LockDrawBuffer();
- cb.rclDraw.xLeft = dwCurrentLine;
- cb.rclDraw.xRight = dwCurrentLine + iLines - 1;
- cb.rclDraw.yTop = rclPicture.yTop;
- cb.rclDraw.yBottom = rclPicture.yBottom;
- RpcTryExcept {
- MandelCalc(&cptLL,
- &(cb.rclDraw),
- dPrecision,
- dwThreshold,
- (LINEBUF *) pbBuf);
- }
- RpcExcept(1) {
- char szFail[MSGLEN];
- sprintf (szFail, "%s (0x%x)n", EXCEPT_MSG, RpcExceptionCode());
- MessageBox(hwnd,
- szFail,
- "Remote Procedure Call",
- MB_ICONINFORMATION);
- KillTimer(hwnd, 1); // stop timer for polls
- EnableMenuItem(GetMenu(hwnd), IDM_GO, MF_ENABLED); // enable GO
- UnlockDrawBuffer();
- ReturnDrawBuffer();
- return(FALSE);
- }
- RpcEndExcept
- UnlockDrawBuffer();
- SvrTable.cPicture = cPictureID;
- SvrTable.dwLine = dwCurrentLine;
- SvrTable.cLines = iLines;
- PostMessage(hwnd, WM_PAINTLINE, 0, 0L);
- dwCurrentLine += iLines;
- return(TRUE);
- }
- return(FALSE);
- }
- }
- /*
- * SetNewCalc --
- *
- * This sets up new information for a drawing and
- * updates the drawing ID so any calculations in progress will not
- * be mixed in.
- */
- void SetNewCalc(CPOINT cptUL, double dPrec, RECT rc)
- {
- // First, translate from upper left to lower left
- cptLL.real = cptUL.real;
- cptLL.imag = cptUL.imag - (dPrec * (rc.bottom - rc.top));
- // Now the precision
- dPrecision = dPrec;
- // The rectangle. Once again, translate.
- rclPicture.xLeft = (long) rc.left;
- rclPicture.xRight = (long) rc.right;
- rclPicture.yBottom = (long) rc.top;
- rclPicture.yTop = (long) rc.bottom;
- // Current line, start of drawing
- dwCurrentLine = rclPicture.xLeft;
- dwThreshold = CalcThreshold(dPrecision);
- }
- void IncPictureID(void)
- {
- cPictureID++;
- }
- void ResetPictureID(void)
- {
- cPictureID = 0;
- }
- /*
- * CheckDrawing --
- *
- * Just a sanity check here -- a function to check to make sure that we're
- * on the right drawing
- */
- BOOL CheckDrawingID(int id)
- {
- return((id == cPictureID) ? TRUE : FALSE);
- }
- /*
- * TakeDrawBuffer ensures only one pipe read at a time.
- * LockDrawBuffer locks the handle and returns a pointer.
- * UnlockDrawBuffer unlocks the handle.
- * ReturnDrawBuffer lets another pipe read go.
- * FreeDrawBuffer ensures the allocated buffer is freed upon exit.
- */
- static BOOL fBufferTaken = FALSE;
- static HANDLE hSharedBuf = (HANDLE) NULL;
- BOOL TakeDrawBuffer(void)
- {
- if (fBufferTaken) {
- return(FALSE);
- }
- if (hSharedBuf == (HANDLE) NULL) {
- hSharedBuf = LocalAlloc(LMEM_MOVEABLE, MAX_BUFSIZE);
- if (hSharedBuf == (HANDLE) NULL)
- return(FALSE);
- }
- fBufferTaken = TRUE;
- return(TRUE);
- }
- LPVOID LockDrawBuffer(void)
- {
- if (hSharedBuf == (HANDLE) NULL)
- return(NULL);
- return(LocalLock(hSharedBuf));
- }
- void UnlockDrawBuffer(void)
- {
- LocalUnlock(hSharedBuf);
- }
- void ReturnDrawBuffer(void)
- {
- fBufferTaken = FALSE;
- }
- void FreeDrawBuffer(void)
- {
- if (hSharedBuf != (HANDLE) NULL)
- LocalFree(hSharedBuf);
- }
- /*
- * CalcThreshold --
- *
- * We need an iteration threshold beyond which we give up. We want it to
- * increase the farther we zoom in. This code generates a threshold value
- * based on the precision of drawing.
- *
- * RETURNS
- * threshold calculated based on precision
- */
- DWORD CalcThreshold(double precision)
- {
- DWORD thres = 25;
- double multiplier = (double) 100.0;
- /* for every 100, multiply by 2 */
- while ((precision *= multiplier) < (double)1.0)
- thres *= 2;
- return(thres);
- }
- /*
- * QueryThreshold --
- *
- * Callback for finding out what the current drawing's threshold is.
- */
- DWORD QueryThreshold(void)
- {
- return(dwThreshold);
- }