//+++++++++++++++++++++++++++++++
// +++++ DDEInit for MATLAB 16bit
#include <windows.h>
#include <ddeml.h>
#define DLLMEX
extern "C"
{
#include "..\header\mex.h" //alle Standard-MATLAB mex/mx-Funktionen
#include "..\header\testargs.h"
}
#include "..\header\fastdde.h"
#pragma hdrstop
#define ARGS_IN_MIN 2 //ARGS_IN_MIN Argumente muessen mind. angegeben sein
#define ARGS_IN_MAX 2 //ARGS_IN_MAX Argumente muessen max. angegeben sein
#define ARG1_IN prhs[0] //Service
#define ARG2_IN prhs[1] //Topic
#define ARG1_OUT plhs[0] //DDE Channel
//Prototypes
BOOL RegisterDDECallback( void ); //Instanzierung der DDE-Callback-Funktion
void ExitFunction(); //deinstalliert DDEML beim Beenden von MATLAB
void DisconnectMsgBox( HCONV ); //Anzeige der MessageBox bei DDE-Disconnect
//Globale Variablen
static DWORD idInst = (DWORD)0; //Instance of app for DDEML
static BOOL FirstStart = TRUE; //s. RegisterDDECallback()
void (*lpfnExitFcn)() = ExitFunction; //Zeiger auf ExitFunction
HDDEDATA CALLBACK _loadds DDECallback ( WORD wType, WORD cbFormat, HCONV hConv, HSZ, HSZ hszItem, HDDEDATA hData, DWORD, DWORD)
{
void (FAR PASCAL *lpfnDDEAdvise)( HCONV, HSZ, HDDEDATA, WORD ); //Zeiger auf DDEAdvise() in Modul ddeadv.dll
switch ( wType )
{
case XTYP_DISCONNECT:
DisconnectMsgBox( hConv );
return (HDDEDATA) NULL;
case XTYP_ADVDATA:
{
HMODULE hModule = GetModuleHandle( (LPCSTR) "ddeadv.dll" );
if ( hModule )
{
lpfnDDEAdvise = (void (FAR PASCAL*) (HCONV, HSZ, HDDEDATA, WORD)) GetProcAddress( (HINSTANCE)hModule,
(LPCSTR) "DDEAdvise" );
if ( lpfnDDEAdvise )
{
(*lpfnDDEAdvise)( hConv, hszItem, hData, cbFormat ); //Absprung in die Funktion DDEAdvise()
return (HDDEDATA) DDE_FACK;
}
}
return (HDDEDATA) DDE_FNOTPROCESSED;
}
default:
return (HDDEDATA) NULL;
}
}
void DisconnectMsgBox( HCONV hConv )
{
CONVINFO ci;
HLOCAL hLocalSvc;
HLOCAL hLocalTopic;
HLOCAL hLocalBuffer;
char* szSvcPartner;
char* szTopic;
char* szBuffer;
ci.cb = sizeof(CONVINFO);
DdeQueryConvInfo( hConv, (DWORD)QID_SYNC, &ci);
int cbPartner = (int)DdeQueryString( idInst, ci.hszSvcPartner, (LPSTR) NULL, 0, 0);
hLocalSvc = LocalAlloc( LPTR, cbPartner + 2 );
szSvcPartner = (char*) LocalLock( hLocalSvc );
DdeQueryString( idInst, ci.hszSvcPartner, (LPSTR)szSvcPartner, cbPartner + 1, CP_WINANSI);
int cbTopic = (int)DdeQueryString( idInst, ci.hszTopic, (LPSTR) NULL, 0, 0);
hLocalTopic = LocalAlloc( LPTR, cbTopic + 2 );
szTopic = (char*) LocalLock( hLocalTopic );
DdeQueryString( idInst, ci.hszTopic, (LPSTR)szTopic, cbTopic + 1, CP_WINANSI);
hLocalBuffer = LocalAlloc( LPTR, cbPartner + cbTopic + 65 /* <- restlicher Text*/ );
szBuffer = (char*) LocalLock( hLocalBuffer );
wsprintf( szBuffer, "Disconnect request from ...\r\n\r\nServer: %s\r\nTopic: %s", szSvcPartner, szTopic );
MessageBox( hWndMATLABCmd, szBuffer, "MATLAB DDE - Toolbox", (MB_APPLMODAL | MB_ICONINFORMATION | MB_OK) );
LocalUnlock( hLocalSvc );
LocalUnlock( hLocalTopic );
LocalUnlock( hLocalBuffer );
}
extern "C" void mexFunction(
int nlhs, //number of output matrizes
Matrix *plhs[],
int nrhs, //number of input matrizes
Matrix *prhs[]
)
{
unsigned long hChannel[] = {0, 0}; //2 mal 32 bit (ChannelHandle, was zurueckgegeben wird)
if ( TestIOArgs( nrhs, ARGS_IN_MIN, ARGS_IN_MAX ) && //alle erforderlichen Parameter angegeben?
TestServiceArg( ARG1_IN ) && //Service-Argument ok?
TestTopicArg( ARG2_IN ) && //Topic-Argument ok?
RegisterDDECallback() ) //Instanzieren der DDE-Callback-Funktion
//nur beim ersten Aufruf von ddeinit
{
HCONV hConv = 0; //Conversation handle
HSZ hszService;
HSZ hszTopic;
char* szService;
char* szTopic;
int m,n;
//szService und szTopic aus uebergebenen Parametern festlegen
szService = (char*) mxCalloc( m= (int)mxGetN(ARG1_IN) + 1, sizeof(char) );
szTopic = (char*) mxCalloc( n= (int)mxGetN(ARG2_IN) + 1, sizeof(char) );
if ( szService != 0 && szTopic != 0 )
{
mxGetString( ARG1_IN, szService, m );
mxGetString( ARG2_IN, szTopic, n );
//StringHandles erzeugen
hszService = DdeCreateStringHandle ( idInst, szService, CP_WINANSI );
hszTopic = DdeCreateStringHandle ( idInst, szTopic, CP_WINANSI );
if ( hszService != 0 && hszTopic != 0 )
{
//DDE-Verbindung herstellen
hConv = DdeConnect ( idInst, hszService, hszTopic, (PCONVCONTEXT) NULL );
if ( hConv )
{
hChannel[0] = hConv; //bit 0-31
hChannel[1] = idInst; //bit 32-63
}
}
else HandleDdeError(DdeGetLastError(idInst));
if ( hszService ) DdeFreeStringHandle ( idInst, hszService );
if ( hszTopic ) DdeFreeStringHandle ( idInst, hszTopic );
}
else
{
mexPrintf( "??? Memory allocation error.\r\n" );
ErrorBeep();
}
if ( szService ) mxFree( szService );
if ( szTopic ) mxFree( szTopic );
}
ARG1_OUT = mxCreateFull(1, 1, REAL);
hmemcpy( (char huge*)mxGetPr(ARG1_OUT), (char*)hChannel, sizeof(double) );
}
BOOL RegisterDDECallback()
{
if ( FirstStart ) //beim 1. Aufruf von DDEINIT
{
//DDE initialisieren (Windows DDEML.DLL)
UINT DDEInitResult = DdeInitialize ( (LPDWORD)&idInst, (PFNCALLBACK)DDECallback,
APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0L );
if ( DDEInitResult != DMLERR_NO_ERROR )
{
HandleDdeError(DDEInitResult);
return FALSE;
}
mexAtExit ( (*lpfnExitFcn) ); //fuer DdeUninitialize(..)
FirstStart = FALSE;
}
return TRUE;
}
void ExitFunction()
{
if ( idInst != (DWORD)0 )
DdeUninitialize ( idInst );
}
Detected encoding: ASCII (7 bit) | 2
|