Source file: /~heha/messtech/matdde.zip/source/ddeadv/ddeadv.cpp

//++++++++++++++++++++++++++++++++++
// +++++ DDEAdvise for MATLAB 16bit

#include <windows.h>
#include <ddeml.h>
#include <malloc.h>	//fuer _memmax()
//#include <string.h>	   //fuer memmove()
//#include <stdlib.h>

#define DLLMEX
extern "C"
{
   #include "..\header\mex.h"
   #include "..\header\testargs.h"
}

#include "..\header\fastdde.h"
#include "..\header\i_field.h"	 //Klasse fuer Advise-Tabelle

#pragma hdrstop


#define ARGS_IN_MIN 3
#define ARGS_IN_MAX 6

#define ARG1_IN	     prhs[0]	 //channel
#define ARG2_IN	     prhs[1]	 //item
#define ARG3_IN	     prhs[2]	 //CallBack-Function
#define ARG4_IN	     prhs[3]	 //upmtx UpdateMatrix
#define ARG5_IN	     prhs[4]	 //cbFormat
#define ARG6_IN	     prhs[5]	 //timeout

#define ARG1_OUT  plhs[0]     //return code



//globales (Advise)-Tabellen-Objekt
//speichert alle Advise-Link-spezifischen Informationen (hConv, hsz, Callbackstring, Matrixname)
InfoField AdvTable;



/////////////////////////////////////////////////////////////////////////////////////////////////////
extern "C" void mexFunction(
	int	nlhs,
	Matrix	*plhs[],
	int	nrhs,
	Matrix	*prhs[]
	)

{
   UINT	 n;
   DWORD timeout	= TIMEOUT;  //default
   WORD	 cbFormat    = CF_TEXT;	 //default
   BOOL	 isStringMat	= FALSE; //zweiten Wert im Format-Argument testen
    char*   szDestMatrix   = NULL;
    double  Result	   = 0;

   if (	 TestIOArgs( nrhs, ARGS_IN_MIN, ARGS_IN_MAX ) &&    //alle erforderlichen Parameter angegeben?
	 TestChannelArg( ARG1_IN ) &&		      //Channel-Argument ok?
	 TestItemArg( ARG2_IN ) &&		      //Item-Argument ok?
	 TestCallbackArg( ARG3_IN ) )		      //Callback-Argument ok?
   {
      if ( nrhs >= ARGS_IN_MAX - 2 )			 //4. Parameter (upmtx) angegeben?
      {
	 if ( TestUpmtxArg( ARG4_IN ) )
	 {
	    n = (UINT)mxGetN( ARG4_IN );
	    if ( n > 0 )		     //wenn upmtx ungleich '' -> Hot Link
	    {
	       szDestMatrix = (char*) mxCalloc( n + 1, sizeof(char) );
	       if ( szDestMatrix )
		  mxGetString( ARG4_IN, szDestMatrix, n );
	       else
	       {
		  szDestMatrix = (char*)-1;
		  Result = -1;		     //Memory allocation error!
	       }
	    }

	    if ( nrhs >= ARGS_IN_MAX - 1 )		    //5. Parameter (Clipboard-Format)?
	    {
	       cbFormat = TestFormatArg( ARG5_IN, CHK_STR_FORMAT, &isStringMat );
	       if ( nrhs == ARGS_IN_MAX )		 //6. Parameter (TimeOut)?
		  timeout = TestTimeoutArg( ARG6_IN );
	    }
	 }
	 else
	    szDestMatrix = (char*)-1;
      }
      if (szDestMatrix != (char*)-1 &&
	 cbFormat != (WORD)-1 &&		      //sind bei ungueltigen Argumenten
	 timeout != (DWORD)-1 )			   // -1
      {
	 DWORD hChannel[2];   //2 mal 32 bit
	 char* szCallback = NULL;

	 hmemcpy( (char*)hChannel, (char huge*)mxGetPr(ARG1_IN), sizeof(double) );


	   HCONV  hConv = hChannel[0];
	 DWORD idInst	= hChannel[1];
	   HSZ	  hszItem = 0;

	   n= (UINT)mxGetN(ARG2_IN) + 1;
	 char*	  szItem = (char*) mxCalloc( n, sizeof(char) );
	 if ( szItem )
	 {
	    mxGetString( ARG2_IN, szItem, n );

	    hszItem  = DdeCreateStringHandle( idInst, szItem, CP_WINANSI );

	       mxFree( szItem );

	    if ( mxGetN(ARG3_IN) > 0 )		//wenn Callbackstring ungleich ''
	    {
	       szCallback = (char*) mxCalloc( n= (UINT)mxGetN(ARG3_IN) + 1, sizeof(char) );
	       if ( szCallback )
		  mxGetString( ARG3_IN, szCallback, n );
	       else
		  Result = -1;		     //Memory allocation error!
	    }
	 }
	 else
	    Result = -1;	       //Memory allocation error!

	   if ( hszItem )
	   {
	    if ( Result != -1 )
	    {
		HDDEDATA hTrans;

		//Eintrag in Advise-Link-Tabelle suchen, ggf. erst loeschen und Link abbrechen
		if ( AdvTable.DelEntry( hConv, hszItem, cbFormat ) )
		  hTrans = DdeClientTransaction( (LPBYTE)NULL, (DWORD)0, hConv, hszItem, cbFormat,
					  XTYP_ADVSTOP, timeout, NULL );

	       //Advise-Link-Tabelle aktualisieren
	       AdvTable.AddEntry( hConv, hszItem, cbFormat, szCallback, szDestMatrix, isStringMat );

	       if ( szDestMatrix )  //HotLink
		  hTrans = DdeClientTransaction( (LPBYTE)NULL, (DWORD)0, hConv, hszItem, cbFormat,
					  (XTYP_ADVSTART /*| XTYPF_ACKREQ*/), timeout, NULL );
	       else	      //WarmLink
		  hTrans = DdeClientTransaction( (LPBYTE)NULL, (DWORD)0, hConv, hszItem, cbFormat,
					  (XTYP_ADVSTART | XTYPF_NODATA /*| XTYPF_ACKREQ*/), timeout, NULL );
	    //hTrans = 1, wenn o.k.
	       if ( hTrans )
		  Result = (double)1;
	    }

	    DdeFreeStringHandle ( idInst, hszItem );
	 }
	 else if ( Result != -1 )
	    HandleDdeError(DdeGetLastError(idInst));

	   if ( szCallback )
	    mxFree( szCallback );
      }
      if ( szDestMatrix && szDestMatrix != (char*)-1 )
	 mxFree( szDestMatrix );

      if ( Result == -1 )
      {
	 mexPrintf( "???  Memory allocation error.\r\n" );
	 ErrorBeep();
	 Result = 0;	   //Fehler
      }
   }
   ARG1_OUT = mxCreateFull(1, 1, REAL);
   hmemcpy( (char huge*)mxGetPr(ARG1_OUT), (char*)&Result, sizeof(double) );
}



/////////////////////////////////////////////////////////////////////////////////////////////////////
// DDEAdvise wird in der DDECallback-Funktion (in DDEInit bei DDEML angemeldet) bei einer
// XTYP_ADVDATA- Transaktion aufgerufen.

extern "C" void FAR PASCAL __export DDEAdvise( HCONV hConv, HSZ hszItem, HDDEDATA hData, WORD cbFormat )
{

   if ( hData )	  //sind Daten enthalten
   {
      BOOL result = FALSE;
       Matrix* DestMatrix;

      //MATLAB-Matrix erzeugen
      if ( cbFormat == CF_TEXT )
      {
	 if ( AdvTable.IsStringMatrix(hConv, hszItem, cbFormat) )
	    result = CFTextStringReq( hData, &DestMatrix );
	    else
	    result = CFTextReq( hData, &DestMatrix );
      }
      else  //Excel Format
	 result = FastDDEReq( hData, &DestMatrix );

      if (result)
      {
	 mxSetName( DestMatrix, AdvTable.GetDestMatrix(hConv, hszItem, cbFormat) );
	 mexPutMatrix( DestMatrix );
	 mxFreeMatrix( DestMatrix );
      }
   }

   //MATLAB-Befehl ausfuehren (Warm- und HotLink)
   char* szCallbackStr;

   if ( hszItem == (HSZ)NULL )	    //falls hszItem = NULL, werden alle AdviseLinks,
   {			   //die hConv entsprechen, bearbeitet.
      int index = 0;

      do
      {
	 szCallbackStr = AdvTable.exGetCallback( hConv, &index );
	 if ( szCallbackStr && szCallbackStr != (char*)-1 )
	    mexEvalString( szCallbackStr );
      }
      while ( szCallbackStr != (char*)-1 );
   }
   else			   //nur AdviseLink zu hszItem bearbeiten
   {
      szCallbackStr = AdvTable.GetCallback( hConv, hszItem, cbFormat );
      if ( szCallbackStr )
	 mexEvalString( szCallbackStr );
   }
}



/////////////////////////////////////////////////////////////////////////////////////////////////////
extern "C" BOOL FAR PASCAL __export DDEUnadvise( HCONV hConv, HSZ hszItem, WORD cbFormat )
{

   return AdvTable.DelEntry( hConv, hszItem, cbFormat );

}

Detected encoding: ASCII (7 bit)2