[ Home | Syllabus |Course Notes]
MIDL File
[
uuid (87654321-4321-1234-4321-987654321CBA),
version(1.0),
endpoint ("ncacn_np:[\\pipe\\ccrpc]")
]
interface calcclr
{
typedef struct
{
double real;
double imag;
} complex;
short CalcColor([in] complex k);
}
// And the ACF file
[
implicit_handle(handle_t calcclrHandle)
]
interface calcclr
{
}
// mandels.cpp
#include <windows.h>
#include <iostream.h>
#include <rpc.h>
#include "ccrpc.h"
#include "memstub"
INT main(VOID)
{
// use the protocols specified in
// the IDL file for this interface
if (RpcServerUseAllProtseqsIf(1,
calcclr_v1_0_s_ifspec,
NULL))
// register the interface
if (RpcServerRegisterIf(calcclr_v1_0_s_ifspec,
NULL, NULL))
// listen for and service RPC requests
if (RpcServerListen(1, 5, FALSE))
return(0);
}
// mandelc.cpp
const double left = -1.0;
const double right = 1.0;
const double top = -1.0;
const double bottom = 1.0;
DWORD colors[64];
typedef struct
{
WORD height;
WORD width;
} mandelParams;
// Define the application object class
class CManApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// Define the edit window class
class CManWindow : public CFrameWnd
{
private:
HANDLE threadHandle;
BOOL running;
BOOL initialized;
mandelParams params;
public:
CManWindow();
void RunMandel();
void SetPix(int x, int y, WORD iter);
afx_msg void OnPaint();
afx_msg void OnStartStop();
afx_msg void OnExit();
DECLARE_MESSAGE_MAP()
};
// Create an instance of the application object
CManApp manApp;
// member function used to set pixel colors
// in the window
void CManWindow::SetPix(int x, int y, WORD iter)
{
CClientDC dc(this);
dc.SetPixel(x, y, colors[iter]);
}
// the thread function which does the drawing // WHY in a thread?
DWORD MandelThread(mandelParams *params)
{
double xstep, ystep;
double x, y;
int i,j;
WORD iter;
complex k;
ystep = (double) (bottom - top) /
params->height;
xstep = (double) (right - left) /
params->width;
for (y=top, j=0; y <= bottom; y += ystep, j++)
{
for (x=left, i=0; x<=right; x += xstep, i++)
{
k.real = x;
k.imag = y;
RpcTryExcept
{
iter=CalcColor(k); // RPC
}
RpcExcept(1)
{
MessageBox(NULL,
"Unable to call CalcColor( ).\n\Click OK and then Exit.",
"ERROR", MB_SETFOREGROUND |
MB_OK | MB_ICONSTOP);
ExitThread(1);
}
RpcEndExcept;
((CManWindow *)manApp.m_pMainWnd)->
SetPix(i, j, iter);
}
}
return(0);
}
// member function used to instigate the
// drawing thread
void CManWindow::RunMandel()
{
DWORD threadID;
CRect r;
GetClientRect(&r);
params.height=r.Height();
params.width=r.Width();
threadHandle=CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) MandelThread,
¶ms, 0, &threadID);
running=TRUE;
}
// The message map
BEGIN_MESSAGE_MAP(CManWindow, CFrameWnd)
ON_WM_PAINT()
ON_COMMAND(IDM_STARTSTOP, OnStartStop)
ON_COMMAND(IDM_EXIT, OnExit)
END_MESSAGE_MAP()
// Handler for the Start/Stop menu option
void CManWindow::OnStartStop()
{
if(running)
SuspendThread(threadHandle);
else
ResumeThread(threadHandle);
running=!running;
}
// Handler for WM_PAINT messages
void CManWindow::OnPaint()
{
ValidateRect(NULL);
if (!initialized)
{
initialized=TRUE;
RunMandel();
}
else
if (running)
{
// stop the existing thread
TerminateThread(threadHandle, 0);
CloseHandle(threadHandle);
// clear the window
CClientDC dc(this);
CRect r;
GetClientRect(&r);
dc.PatBlt(0, 0, r.Width(), r.Height(),
WHITENESS);
// start over again
RunMandel();
}
}
// Handler for the Exit menu option
void CManWindow::OnExit()
{
SuspendThread(threadHandle);
CloseHandle(threadHandle);
RpcBindingFree(&calcclrHandle);
DestroyWindow();
}
// CManWindow constructor
CManWindow::CManWindow()
{
WORD x;
BYTE red=0, green=0, blue=0;
UCHAR *stringBinding;
CHAR serverName[MAX_PATH];
BOOL test = Create( NULL, "RPC Mandel Example",
WS_OVERLAPPEDWINDOW,
CRect(0,0,150,150), NULL, "MainMenu" );
// Set up a set of colors
for (x=0; x<64; x++)
{
colors[x] = RGB(red, green, blue);
if (!(red += 64))
if (!(green += 64))
blue += 64;
}
colors[63] = RGB(255,255,255);
if (strlen(manApp.m_lpCmdLine))
strcpy(serverName, manApp.m_lpCmdLine);
else
strcpy(serverName, "\\\\.");
RpcStringBindingCompose(NULL,
(UCHAR *) "ncacn_np", (UCHAR *) serverName,
(UCHAR *) "\\pipe\\ccrpc", NULL,
&stringBinding);
RpcBindingFromStringBinding(stringBinding,
&calcclrHandle);
RpcStringFree(&stringBinding);
initialized=FALSE;
}
// Initialize the CManApp m_pMainWnd data member
BOOL CManApp::InitInstance()
{
m_pMainWnd = new CManWindow();
m_pMainWnd -> ShowWindow( m_nCmdShow );
m_pMainWnd -> UpdateWindow();
return TRUE;
}
void __RPC_FAR * __RPC_API
midl_user_allocate(size_t len)
{
return(new(unsigned char [len]));
}
void __RPC_API midl_user_free(void __RPC_FAR * ptr)
{
delete(ptr);
}
[
uuid (87654329-4321-1234-4321-987654321CBA),
version(1.0),
endpoint ("ncacn_np:[\\pipe\\ccrpc2]")
]
interface calcline
{
typedef struct
{
double real;
double imag;
} complex;
void CalcLine([in] double left,
[in] double right,
[in] double y, [in] long width,
[out, size_is(width)] short line[]);
}