home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************
- * DDECLI.CXX
- * (c) 1992-1994 STAR DIVISION
- *******************************************************************/
-
- #include "ddeimp.hxx"
- #include "svdde.hxx"
-
- static DWORD hDdeInst = NULL;
- static short nInstance = 0;
-
- DdeConnections* DdeConnection::pConnections = NULL;
-
- struct DdeImp
- {
- HCONV hConv;
- long nStatus;
- };
-
- // --- DdeInternat::CliCallback() ----------------------------------
-
- #ifdef WNT
- HDDEDATA CALLBACK DdeInternal::CliCallback(
- WORD nCode, WORD nCbType, HCONV hConv, HSZ, HSZ hText2,
- HDDEDATA hData, DWORD, DWORD nInfo2 )
- #else
- HDDEDATA CALLBACK _export DdeInternal::CliCallback(
- WORD nCode, WORD nCbType, HCONV hConv, HSZ, HSZ hText2,
- HDDEDATA hData, DWORD, DWORD nInfo2 )
- #endif
- {
- DdeConnections& rAll = (DdeConnections&)DdeConnection::GetConnections();
- DdeConnection* self = NULL;
-
- for ( self = rAll.First(); self; self = rAll.Next() )
- {
- if ( self->pImp->hConv == hConv )
- break;
- }
- if ( !self )
- return (HDDEDATA)DDE_FNOTPROCESSED;
-
- DdeTransaction* t;
- BOOL bFound = FALSE;
- for ( t = self->aTransactions.First(); t && bFound;
- t = self->aTransactions.Next() )
- {
- switch( nCode )
- {
- case XTYP_XACT_COMPLETE:
- bFound = BOOL((DWORD)t->nId == nInfo2);
- if ( bFound )
- {
- nCode = t->nType & (XCLASS_MASK | XTYP_MASK);
- t->bBusy = FALSE;
- t->Done();
- }
- break;
- case XTYP_DISCONNECT:
- self->pImp->hConv = DdeReconnect( hConv );
- self->pImp->nStatus = DdeGetLastError( hDdeInst );
- return 0L;
- case XTYP_ADVDATA:
- bFound = BOOL( *t->pName == hText2 );
- break;
- }
- }
-
- if ( !t )
- return (HDDEDATA)DDE_FNOTPROCESSED;
-
- switch( nCode )
- {
- case XTYP_ADVDATA:
- if ( !hData )
- {
- ((DdeLink*) t)->Notify();
- return (HDDEDATA) DDE_FACK;
- }
- case XTYP_REQUEST:
- DdeData d;
- d.pImp->hData = hData;
- d.pImp->nFmt = nCbType;
- d.Lock();
- t->Data( &d );
- return (HDDEDATA) DDE_FACK;
- }
-
- return (HDDEDATA) DDE_FNOTPROCESSED;
- }
-
- // --- DdeConnection::DdeConnection() ------------------------------
-
- DdeConnection::DdeConnection( const String& rService, const String& rTopic )
- {
- pImp = new DdeImp;
- pImp->nStatus = DMLERR_NO_ERROR;
- pImp->hConv = NULL;
-
- if ( !nInstance++ )
- {
- pImp->nStatus = DdeInitialize( &hDdeInst, (PFNCALLBACK)DdeInternal::CliCallback,
- APPCLASS_STANDARD | APPCMD_CLIENTONLY |
- CBF_FAIL_ALLSVRXACTIONS |
- CBF_SKIP_REGISTRATIONS |
- CBF_SKIP_UNREGISTRATIONS, 0L );
- pConnections = new DdeConnections;
- }
-
- pService = new DdeString( hDdeInst, rService );
- pTopic = new DdeString( hDdeInst, rTopic );
-
- if ( pImp->nStatus == DMLERR_NO_ERROR )
- {
- pImp->hConv = DdeConnect( hDdeInst, *pService, *pTopic, NULL );
- pImp->nStatus = DdeGetLastError( hDdeInst );
- }
-
- if ( pConnections )
- pConnections->Insert( this );
- }
-
- // --- DdeConnection::~DdeConnection() -----------------------------
-
- DdeConnection::~DdeConnection()
- {
- if ( pImp->hConv )
- DdeDisconnect( pImp->hConv );
-
- delete pService;
- delete pTopic;
-
- if ( pConnections )
- pConnections->Remove( this );
-
- if ( !--nInstance && hDdeInst )
- {
- DdeUninitialize( hDdeInst );
- hDdeInst = NULL;
- delete pConnections;
- pConnections = NULL;
- }
-
- delete pImp;
- }
-
- // --- DdeConnection::IsConnected() --------------------------------
-
- BOOL DdeConnection::IsConnected()
- {
- CONVINFO c;
- if ( DdeQueryConvInfo( pImp->hConv, QID_SYNC, &c ) )
- return TRUE;
- else
- {
- pImp->hConv = DdeReconnect( pImp->hConv );
- pImp->nStatus = DdeGetLastError( hDdeInst );
- return BOOL( pImp->nStatus == DMLERR_NO_ERROR );
- }
- }
-
- // --- DdeConnection::GetServiceName() -----------------------------
-
- const String& DdeConnection::GetServiceName()
- {
- return (const String&)*pService;
- }
-
- // --- DdeConnection::GetTopicName() -------------------------------
-
- const String& DdeConnection::GetTopicName()
- {
- return (const String&)*pTopic;
- }
-
- // --- DdeConnection::GetConvId() ----------------------------------
-
- long DdeConnection::GetConvId()
- {
- return (long)pImp->hConv;
- }
-
- // --- DdeTransaction::DdeTransaction() ----------------------------
-
- DdeTransaction::DdeTransaction( DdeConnection& d, const String& rItemName,
- long n ) :
- rDde( d )
- {
- pName = new DdeString( hDdeInst, rItemName );
- nTime = n;
- nId = 0;
- nType = 0;
- bBusy = FALSE;
-
- rDde.aTransactions.Insert( this );
- }
-
- // --- DdeTransaction::~DdeTransaction() ---------------------------
-
- DdeTransaction::~DdeTransaction()
- {
- if ( nId && rDde.pImp->hConv )
- DdeAbandonTransaction( hDdeInst, rDde.pImp->hConv, nId );
-
- delete pName;
- rDde.aTransactions.Remove( this );
- }
-
- // --- DdeTransaction::Execute() -----------------------------------
-
- void DdeTransaction::Execute()
- {
- HSZ hItem = *pName;
- void* pData = (void*)(const char*)aDdeData;
- DWORD nData = (DWORD)(long)aDdeData;
- UINT nFmt = (UINT)aDdeData.GetFormat();
-
- if ( nType == XTYP_EXECUTE )
- hItem = NULL;
- if ( nType != XTYP_EXECUTE && nType != XTYP_POKE )
- {
- pData = NULL;
- nData = 0L;
- }
- if ( nTime )
- {
- HDDEDATA hData = DdeClientTransaction( (unsigned char*)pData, nData, rDde.pImp->hConv,
- hItem, nFmt, (UINT)nType,
- (DWORD)nTime, (DWORD FAR*)NULL );
-
- if ( hData && nType == XTYP_REQUEST )
- {
- {
- DdeData d;
- d.pImp->hData = hData;
- d.pImp->nFmt = (short)aDdeData.GetFormat();
- d.Lock();
- Data( &d );
- }
- DdeFreeDataHandle( hData );
- }
- }
- else
- {
- if ( nId && rDde.pImp->hConv )
- DdeAbandonTransaction( hDdeInst, rDde.pImp->hConv, nId );
- nId = 0;
- bBusy = TRUE;
- DdeClientTransaction( (unsigned char*)pData, nData, rDde.pImp->hConv, hItem, nFmt,
- (UINT)nType, TIMEOUT_ASYNC,
- (DWORD FAR *) ((long*) &nId) );
- }
-
- rDde.pImp->nStatus = DdeGetLastError( hDdeInst );
- }
-
- // --- DdeTransaction::GetName() -----------------------------------
-
- const String& DdeTransaction::GetName()
- {
- return (const String&)*pName;
- }
-
- // --- DdeTransaction::Data() --------------------------------------
-
- void DdeTransaction::Data( const DdeData* p )
- {
- aData.Call( (void*)p );
- }
-
- // --- DdeTransaction::Done() --------------------------------------
-
- void DdeTransaction::Done()
- {
- aDone.Call( NULL );
- }
-
- // --- DdeLink::DdeLink() ------------------------------------------
-
- DdeLink::DdeLink( DdeConnection& d, const String& aItemName, long n ) :
- DdeTransaction (d, aItemName, n)
- {
- }
-
- // --- DdeLink::~DdeLink() -----------------------------------------
-
- DdeLink::~DdeLink()
- {
- nType = XTYP_ADVSTOP;
- nTime = 0;
- }
-
- // --- DdeLink::Notify() -----------------------------------------
-
- void DdeLink::Notify()
- {
- aNotify.Call( NULL );
- }
-
- // --- DdeRequest::DdeRequest() ------------------------------------
-
- DdeRequest::DdeRequest( DdeConnection& d, const String& i, long n ) :
- DdeTransaction( d, i, n )
- {
- nType = XTYP_REQUEST;
- }
-
- // --- DdeWarmLink::DdeWarmLink() ----------------------------------
-
- DdeWarmLink::DdeWarmLink( DdeConnection& d, const String& i, long n ) :
- DdeLink( d, i, n )
- {
- nType = XTYP_ADVSTART | XTYPF_NODATA;
- }
-
- // --- DdeHotLink::DdeHotLink() ------------------------------------
-
- DdeHotLink::DdeHotLink( DdeConnection& d, const String& i, long n ) :
- DdeLink( d, i, n )
- {
- nType = XTYP_ADVSTART;
- }
-
- // --- DdePoke::DdePoke() ------------------------------------------
-
- DdePoke::DdePoke( DdeConnection& d, const String& i, const char* p,
- long l, ULONG f, long n ) :
- DdeTransaction( d, i, n )
- {
- aDdeData = DdeData( p, l, f );
- nType = XTYP_POKE;
- }
-
- // --- DdePoke::DdePoke() ------------------------------------------
-
- DdePoke::DdePoke( DdeConnection& d, const String& i, const String& rData,
- long n ) :
- DdeTransaction( d, i, n )
- {
- const char* p = rData;
- aDdeData = DdeData( (char*) p, rData.Len(), CF_TEXT );
- nType = XTYP_POKE;
- }
-
- // --- DdePoke::DdePoke() ------------------------------------------
-
- DdePoke::DdePoke( DdeConnection& d, const String& i, const DdeData& rData,
- long n ) :
- DdeTransaction( d, i, n )
- {
- aDdeData = rData;
- nType = XTYP_POKE;
- }
-
- // --- DdeExecute::DdeExecute() ------------------------------------
-
- DdeExecute::DdeExecute( DdeConnection& d, const String& rData, long n ) :
- DdeTransaction( d, String(""), n )
- {
- const char* p = rData;
- aDdeData = DdeData( (char*) p, rData.Len() + 1, CF_TEXT );
- nType = XTYP_EXECUTE;
- }
-
- // --- DdeConnection::GetError() -----------------------------------
-
- long DdeConnection::GetError()
- {
- return pImp->nStatus;
- }
-