This project is read-only.

Porting C poke command to NDde

Sep 2, 2009 at 12:36 PM

Hello everybody,

first I'd like to thank the guy who developed this library for his great work - it really saved me!

But now I have a problem with porting a poke command from c to c# (sorry for the long code block):

(you can find the whole c file under http://www.zemax.com/kb/articles/90/6/How-Do-I-Write-an-Extension-in-C/Page6.html in the attachements)

 

// structures

typedef struct
	{
   double x, y, z, l, m, n, opd, intensity;
	double Exr, Exi, Eyr, Eyi, Ezr, Ezi;
	int wave, error, vigcode, want_opd;
	}DDERAYDATA;

DDERAYDATA *rdpGRD = NULL;

// the c function that has to be ported to c#
int PostArrayTraceMessage(char *szBuffer, DDERAYDATA *RD)
{
ATOM aItem;
HGLOBAL hPokeData;
DDEPOKE * lpPokeData;
long numbytes;
int numrays;


if (RD[0].opd > 4)
	{
	/* NSC Rays */
	numrays = (int)RD[0].opd - 5;
	}
else
	{
	/* sequential rays */
	numrays = RD[0].error;
	}

/* point to where the data is */
rdpGRD = RD;
ngNumRays = numrays;

numbytes = (1+numrays)*sizeof(DDERAYDATA);
hPokeData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (LONG) sizeof(DDEPOKE) + numbytes);
lpPokeData = (DDEPOKE *) GlobalLock(hPokeData);
lpPokeData->fRelease = TRUE;
lpPokeData->cfFormat = CF_TEXT;
memcpy(lpPokeData->Value, RD, numbytes);

/* clear the buffers */
szGlobalBuffer[0] = '\0';
szBuffer[0] = '\0';

aItem = GlobalAddAtom("RayArrayData");
GlobalUnlock(hPokeData);

GotData = 0;

if (!PostMessage(hwndServer, WM_DDE_POKE, (WPARAM) hwndClient, PackDDElParam(WM_DDE_POKE, (UINT) hPokeData, aItem)))
	{
   MessageBox (hwndClient, "Cannot communicate with ZEMAX!", "Hello?", MB_ICONEXCLAMATION | MB_OK);
   GlobalDeleteAtom(aItem);
	GlobalFree(hPokeData);
   return -1;
   }
GlobalDeleteAtom(aItem);

WaitForData(hwndClient);  // waits until the server sent back data, code snippet below

strcpy(szBuffer, szGlobalBuffer);

/* clear the pointer */
rdpGRD = NULL;

if (GotData) return 0;
else return -1;
}






// snippet in the wndproc that checks for data

   case WM_DDE_DATA :
   	/* here comes the data! */
      // wParam -- sending window handle
      // lParam -- DDEDATA memory handle & item atom
      UnpackDDElParam(WM_DDE_DATA, lParam, &uiLow, &uiHi);
      FreeDDElParam(WM_DDE_DATA, lParam);
		hDdeData  = (GLOBALHANDLE) uiLow;
      pDdeData = (DDEDATA *) GlobalLock (hDdeData);
      aItem     = (ATOM) uiHi;

      // Initialize DdeAck structure
      DdeAck.bAppReturnCode = 0;
      DdeAck.reserved       = 0;
      DdeAck.fBusy          = FALSE;
      DdeAck.fAck           = FALSE;


      // Check for matching format, put the data in the buffer
      if (pDdeData->cfFormat == CF_TEXT)
      	{       
         /* get the data back into RD */
			if (rdpGRD) memcpy(rdpGRD, (DDERAYDATA *) pDdeData->Value, (ngNumRays+1)*sizeof(DDERAYDATA));
			else strcpy(szGlobalBuffer, (char *) pDdeData->Value);
         }

      GotData = 1;
		GlobalDeleteAtom (aItem);

      // Acknowledge if necessary
      if (pDdeData->fAckReq == TRUE)
      	{
         wStatus = *((WORD *) &DdeAck);
         if (!PostMessage ((HWND) wParam, WM_DDE_ACK, (WPARAM) hwnd, PackDDElParam (WM_DDE_ACK, wStatus, aItem)))
         	{
				if (hDdeData)
					{
					GlobalUnlock (hDdeData);
					GlobalFree (hDdeData);
					}
            return 0;
            }
         }

      // Clean up
		GlobalUnlock (hDdeData);
      if (pDdeData->fRelease == TRUE || DdeAck.fAck == FALSE) GlobalFree (hDdeData);
      return 0;

 

Now the questions is, how can I allocate the memory in C# and create the parameters for NDde's poke command? I would really appreciate if someone could give me a hint.

Thanks and cheers,

Alex