home *** CD-ROM | disk | FTP | other *** search
/ PC Direkt 1995 March / PCD_395.iso / starview / winblci / german / ddecli.cx_ / DDECLI.CXX
Encoding:
C/C++ Source or Header  |  1994-01-21  |  9.9 KB  |  371 lines

  1. /*******************************************************************
  2. *  DDECLI.CXX
  3. *  (c) 1992-1994 STAR DIVISION
  4. *******************************************************************/
  5.  
  6. #include "ddeimp.hxx"
  7. #include "svdde.hxx"
  8.  
  9. static DWORD        hDdeInst  = NULL;
  10. static short        nInstance = 0;
  11.  
  12. DdeConnections*     DdeConnection::pConnections = NULL;
  13.  
  14. struct DdeImp
  15. {
  16.     HCONV   hConv;
  17.     long    nStatus;
  18. };
  19.  
  20. // --- DdeInternat::CliCallback() ----------------------------------
  21.  
  22. #ifdef WNT
  23. HDDEDATA CALLBACK DdeInternal::CliCallback(
  24.             WORD nCode, WORD nCbType, HCONV hConv, HSZ, HSZ hText2,
  25.             HDDEDATA hData, DWORD, DWORD nInfo2 )
  26. #else
  27. HDDEDATA CALLBACK _export DdeInternal::CliCallback(
  28.             WORD nCode, WORD nCbType, HCONV hConv, HSZ, HSZ hText2,
  29.             HDDEDATA hData, DWORD, DWORD nInfo2 )
  30. #endif
  31. {
  32.     DdeConnections&     rAll = (DdeConnections&)DdeConnection::GetConnections();
  33.     DdeConnection*      self = NULL;
  34.  
  35.     for ( self = rAll.First(); self; self = rAll.Next() )
  36.     {
  37.         if ( self->pImp->hConv == hConv )
  38.             break;
  39.     }
  40.     if ( !self )
  41.         return (HDDEDATA)DDE_FNOTPROCESSED;
  42.  
  43.     DdeTransaction* t;
  44.     BOOL            bFound = FALSE;
  45.     for ( t = self->aTransactions.First(); t && bFound;
  46.           t = self->aTransactions.Next() )
  47.     {
  48.         switch( nCode )
  49.         {
  50.             case XTYP_XACT_COMPLETE:
  51.                 bFound = BOOL((DWORD)t->nId == nInfo2);
  52.                 if ( bFound )
  53.                 {
  54.                     nCode = t->nType & (XCLASS_MASK | XTYP_MASK);
  55.                     t->bBusy = FALSE;
  56.                     t->Done();
  57.                 }
  58.                 break;
  59.             case XTYP_DISCONNECT:
  60.                 self->pImp->hConv = DdeReconnect( hConv );
  61.                 self->pImp->nStatus = DdeGetLastError( hDdeInst );
  62.                 return 0L;
  63.             case XTYP_ADVDATA:
  64.                 bFound = BOOL( *t->pName == hText2 );
  65.                 break;
  66.         }
  67.     }
  68.  
  69.     if ( !t )
  70.         return (HDDEDATA)DDE_FNOTPROCESSED;
  71.  
  72.     switch( nCode )
  73.     {
  74.         case XTYP_ADVDATA:
  75.             if ( !hData )
  76.             {
  77.                 ((DdeLink*) t)->Notify();
  78.                 return (HDDEDATA) DDE_FACK;
  79.             }
  80.         case XTYP_REQUEST:
  81.             DdeData d;
  82.             d.pImp->hData = hData;
  83.             d.pImp->nFmt  = nCbType;
  84.             d.Lock();
  85.             t->Data( &d );
  86.             return (HDDEDATA) DDE_FACK;
  87.     }
  88.  
  89.     return (HDDEDATA) DDE_FNOTPROCESSED;
  90. }
  91.  
  92. // --- DdeConnection::DdeConnection() ------------------------------
  93.  
  94. DdeConnection::DdeConnection( const String& rService, const String& rTopic )
  95. {
  96.     pImp = new DdeImp;
  97.     pImp->nStatus  = DMLERR_NO_ERROR;
  98.     pImp->hConv    = NULL;
  99.  
  100.     if ( !nInstance++ )
  101.     {
  102.         pImp->nStatus = DdeInitialize( &hDdeInst, (PFNCALLBACK)DdeInternal::CliCallback,
  103.                                        APPCLASS_STANDARD | APPCMD_CLIENTONLY |
  104.                                        CBF_FAIL_ALLSVRXACTIONS |
  105.                                        CBF_SKIP_REGISTRATIONS  |
  106.                                        CBF_SKIP_UNREGISTRATIONS, 0L );
  107.         pConnections = new DdeConnections;
  108.     }
  109.  
  110.     pService = new DdeString( hDdeInst, rService );
  111.     pTopic   = new DdeString( hDdeInst, rTopic );
  112.  
  113.     if ( pImp->nStatus == DMLERR_NO_ERROR )
  114.     {
  115.         pImp->hConv = DdeConnect( hDdeInst, *pService, *pTopic, NULL );
  116.         pImp->nStatus = DdeGetLastError( hDdeInst );
  117.     }
  118.  
  119.     if ( pConnections )
  120.         pConnections->Insert( this );
  121. }
  122.  
  123. // --- DdeConnection::~DdeConnection() -----------------------------
  124.  
  125. DdeConnection::~DdeConnection()
  126. {
  127.     if ( pImp->hConv )
  128.         DdeDisconnect( pImp->hConv );
  129.  
  130.     delete pService;
  131.     delete pTopic;
  132.  
  133.     if ( pConnections )
  134.         pConnections->Remove( this );
  135.  
  136.     if ( !--nInstance && hDdeInst )
  137.     {
  138.         DdeUninitialize( hDdeInst );
  139.         hDdeInst = NULL;
  140.         delete pConnections;
  141.         pConnections = NULL;
  142.     }
  143.  
  144.     delete pImp;
  145. }
  146.  
  147. // --- DdeConnection::IsConnected() --------------------------------
  148.  
  149. BOOL DdeConnection::IsConnected()
  150. {
  151.     CONVINFO c;
  152.     if ( DdeQueryConvInfo( pImp->hConv, QID_SYNC, &c ) )
  153.         return TRUE;
  154.     else
  155.     {
  156.         pImp->hConv = DdeReconnect( pImp->hConv );
  157.         pImp->nStatus = DdeGetLastError( hDdeInst );
  158.         return BOOL( pImp->nStatus == DMLERR_NO_ERROR );
  159.     }
  160. }
  161.  
  162. // --- DdeConnection::GetServiceName() -----------------------------
  163.  
  164. const String& DdeConnection::GetServiceName()
  165. {
  166.     return (const String&)*pService;
  167. }
  168.  
  169. // --- DdeConnection::GetTopicName() -------------------------------
  170.  
  171. const String& DdeConnection::GetTopicName()
  172. {
  173.     return (const String&)*pTopic;
  174. }
  175.  
  176. // --- DdeConnection::GetConvId() ----------------------------------
  177.  
  178. long DdeConnection::GetConvId()
  179. {
  180.     return (long)pImp->hConv;
  181. }
  182.  
  183. // --- DdeTransaction::DdeTransaction() ----------------------------
  184.  
  185. DdeTransaction::DdeTransaction( DdeConnection& d, const String& rItemName,
  186.                                 long n ) :
  187.                     rDde( d )
  188. {
  189.     pName = new DdeString( hDdeInst, rItemName );
  190.     nTime = n;
  191.     nId   = 0;
  192.     nType = 0;
  193.     bBusy = FALSE;
  194.  
  195.     rDde.aTransactions.Insert( this );
  196. }
  197.  
  198. // --- DdeTransaction::~DdeTransaction() ---------------------------
  199.  
  200. DdeTransaction::~DdeTransaction()
  201. {
  202.     if ( nId && rDde.pImp->hConv )
  203.         DdeAbandonTransaction( hDdeInst, rDde.pImp->hConv, nId );
  204.  
  205.     delete pName;
  206.     rDde.aTransactions.Remove( this );
  207. }
  208.  
  209. // --- DdeTransaction::Execute() -----------------------------------
  210.  
  211. void DdeTransaction::Execute()
  212. {
  213.     HSZ     hItem = *pName;
  214.     void*   pData = (void*)(const char*)aDdeData;
  215.     DWORD   nData = (DWORD)(long)aDdeData;
  216.     UINT    nFmt  = (UINT)aDdeData.GetFormat();
  217.  
  218.     if ( nType == XTYP_EXECUTE )
  219.         hItem = NULL;
  220.     if ( nType != XTYP_EXECUTE && nType != XTYP_POKE )
  221.     {
  222.         pData = NULL;
  223.         nData = 0L;
  224.     }
  225.     if ( nTime )
  226.     {
  227.         HDDEDATA hData = DdeClientTransaction( (unsigned char*)pData, nData, rDde.pImp->hConv,
  228.                                                hItem, nFmt, (UINT)nType,
  229.                                                (DWORD)nTime, (DWORD FAR*)NULL );
  230.  
  231.         if ( hData && nType == XTYP_REQUEST )
  232.         {
  233.             {
  234.                 DdeData d;
  235.                 d.pImp->hData = hData;
  236.                 d.pImp->nFmt  = (short)aDdeData.GetFormat();
  237.                 d.Lock();
  238.                 Data( &d );
  239.             }
  240.             DdeFreeDataHandle( hData );
  241.         }
  242.     }
  243.     else
  244.     {
  245.         if ( nId && rDde.pImp->hConv )
  246.             DdeAbandonTransaction( hDdeInst, rDde.pImp->hConv, nId );
  247.         nId = 0;
  248.         bBusy = TRUE;
  249.         DdeClientTransaction( (unsigned char*)pData, nData, rDde.pImp->hConv, hItem, nFmt,
  250.                               (UINT)nType, TIMEOUT_ASYNC,
  251.                               (DWORD FAR *) ((long*) &nId) );
  252.     }
  253.  
  254.     rDde.pImp->nStatus = DdeGetLastError( hDdeInst );
  255. }
  256.  
  257. // --- DdeTransaction::GetName() -----------------------------------
  258.  
  259. const String& DdeTransaction::GetName()
  260. {
  261.     return (const String&)*pName;
  262. }
  263.  
  264. // --- DdeTransaction::Data() --------------------------------------
  265.  
  266. void DdeTransaction::Data( const DdeData* p )
  267. {
  268.     aData.Call( (void*)p );
  269. }
  270.  
  271. // --- DdeTransaction::Done() --------------------------------------
  272.  
  273. void DdeTransaction::Done()
  274. {
  275.     aDone.Call( NULL );
  276. }
  277.  
  278. // --- DdeLink::DdeLink() ------------------------------------------
  279.  
  280. DdeLink::DdeLink( DdeConnection& d, const String& aItemName, long n ) :
  281.             DdeTransaction (d, aItemName, n)
  282. {
  283. }
  284.  
  285. // --- DdeLink::~DdeLink() -----------------------------------------
  286.  
  287. DdeLink::~DdeLink()
  288. {
  289.     nType = XTYP_ADVSTOP;
  290.     nTime = 0;
  291. }
  292.  
  293. // --- DdeLink::Notify() -----------------------------------------
  294.  
  295. void DdeLink::Notify()
  296. {
  297.     aNotify.Call( NULL );
  298. }
  299.  
  300. // --- DdeRequest::DdeRequest() ------------------------------------
  301.  
  302. DdeRequest::DdeRequest( DdeConnection& d, const String& i, long n ) :
  303.                 DdeTransaction( d, i, n )
  304. {
  305.     nType = XTYP_REQUEST;
  306. }
  307.  
  308. // --- DdeWarmLink::DdeWarmLink() ----------------------------------
  309.  
  310. DdeWarmLink::DdeWarmLink( DdeConnection& d, const String& i, long n ) :
  311.                 DdeLink( d, i, n )
  312. {
  313.     nType = XTYP_ADVSTART | XTYPF_NODATA;
  314. }
  315.  
  316. // --- DdeHotLink::DdeHotLink() ------------------------------------
  317.  
  318. DdeHotLink::DdeHotLink( DdeConnection& d, const String& i, long n ) :
  319.                 DdeLink( d, i, n )
  320. {
  321.     nType = XTYP_ADVSTART;
  322. }
  323.  
  324. // --- DdePoke::DdePoke() ------------------------------------------
  325.  
  326. DdePoke::DdePoke( DdeConnection& d, const String& i, const char* p,
  327.                   long l, ULONG f, long n ) :
  328.             DdeTransaction( d, i, n )
  329. {
  330.     aDdeData = DdeData( p, l, f );
  331.     nType = XTYP_POKE;
  332. }
  333.  
  334. // --- DdePoke::DdePoke() ------------------------------------------
  335.  
  336. DdePoke::DdePoke( DdeConnection& d, const String& i, const String& rData,
  337.                   long n ) :
  338.             DdeTransaction( d, i, n )
  339. {
  340.     const char* p = rData;
  341.     aDdeData = DdeData( (char*) p, rData.Len(), CF_TEXT );
  342.     nType = XTYP_POKE;
  343. }
  344.  
  345. // --- DdePoke::DdePoke() ------------------------------------------
  346.  
  347. DdePoke::DdePoke( DdeConnection& d, const String& i, const DdeData& rData,
  348.                   long n ) :
  349.             DdeTransaction( d, i, n )
  350. {
  351.     aDdeData = rData;
  352.     nType = XTYP_POKE;
  353. }
  354.  
  355. // --- DdeExecute::DdeExecute() ------------------------------------
  356.  
  357. DdeExecute::DdeExecute( DdeConnection& d, const String& rData, long n ) :
  358.                 DdeTransaction( d, String(""), n )
  359. {
  360.     const char* p = rData;
  361.     aDdeData = DdeData( (char*) p, rData.Len() + 1, CF_TEXT );
  362.     nType = XTYP_EXECUTE;
  363. }
  364.  
  365. // --- DdeConnection::GetError() -----------------------------------
  366.  
  367. long DdeConnection::GetError()
  368. {
  369.     return pImp->nStatus;
  370. }
  371.