//++++++++++++++++++++++++++++++++++
// +++++ 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
|