merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / svdde / ddesvr.cxx
blob81cf7101a0df4d8f8baa10e7be653ae98ca89729
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ddesvr.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #define UNICODE
35 #include "ddeimp.hxx"
36 #include <svtools/svdde.hxx>
37 #include <svtools/svarray.hxx>
38 #include <tools/debug.hxx>
39 #include <osl/thread.h>
41 //static long hCurConv = 0;
42 //static DWORD hDdeInst = NULL;
43 //static short nInstance = 0;
44 //static DdeServices* pServices;
46 enum DdeItemType
48 DDEITEM,
49 DDEGETPUTITEM
52 struct DdeItemImpData
54 ULONG nHCnv;
55 USHORT nCnt;
57 DdeItemImpData( ULONG nH ) : nHCnv( nH ), nCnt( 1 ) {}
60 SV_DECL_VARARR( DdeItemImp, DdeItemImpData, 1, 1 )
61 SV_IMPL_VARARR( DdeItemImp, DdeItemImpData )
63 // --- DdeInternat::SvrCallback() ----------------------------------
65 #ifdef WNT
66 HDDEDATA CALLBACK DdeInternal::SvrCallback(
67 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
68 HDDEDATA hData, DWORD, DWORD )
69 #else
70 #if defined ( MTW ) || ( defined ( GCC ) && defined ( OS2 )) || defined( ICC )
71 HDDEDATA CALLBACK __EXPORT DdeInternal::SvrCallback(
72 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
73 HDDEDATA hData, DWORD, DWORD )
74 #else
75 HDDEDATA CALLBACK _export DdeInternal::SvrCallback(
76 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
77 HDDEDATA hData, DWORD, DWORD )
78 #endif
79 #endif
81 DdeServices& rAll = DdeService::GetServices();
82 DdeService* pService;
83 DdeTopic* pTopic;
84 DdeItem* pItem;
85 DdeData* pData;
86 Conversation* pC;
88 DdeInstData* pInst = ImpGetInstData();
89 DBG_ASSERT(pInst,"SVDDE:No instance data");
91 switch( nCode )
93 case XTYP_WILDCONNECT:
95 int nTopics = 0;
97 #if 1
98 TCHAR chTopicBuf[250];
99 if( hText1 )
100 DdeQueryString( pInst->hDdeInstSvr, hText1, chTopicBuf,
101 sizeof(chTopicBuf)/sizeof(TCHAR), CP_WINUNICODE );
103 for( pService = rAll.First();pService;pService = rAll.Next() )
105 if ( !hText2 || ( *pService->pName == hText2 ) )
107 String sTopics( pService->Topics() );
108 if( sTopics.Len() )
110 if( hText1 )
112 USHORT n = 0;
113 while( STRING_NOTFOUND != n )
115 String s( sTopics.GetToken( 0, '\t', n ));
116 if( s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
117 ++nTopics;
120 else
121 nTopics += sTopics.GetTokenCount( '\t' );
126 #else
127 for( pService = rAll.First();pService;pService = rAll.Next() )
129 if ( !hText2 || ( *pService->pName == hText2 ) )
131 for( pTopic = pService->aTopics.First(); pTopic;
132 pTopic = pService->aTopics.Next() )
134 if ( !hText1 || (*pTopic->pName == hText1) )
135 nTopics++;
139 #endif
140 if( !nTopics )
141 return (HDDEDATA)NULL;
143 HSZPAIR* pPairs = new HSZPAIR [nTopics + 1];
144 if ( !pPairs )
145 return (HDDEDATA)NULL;
147 HSZPAIR* q = pPairs;
148 for( pService = rAll.First(); pService; pService = rAll.Next() )
150 if ( !hText2 || (*pService->pName == hText2 ) )
152 #if 0
153 for ( pTopic = pService->aTopics.First(); pTopic;
154 pTopic = pService->aTopics.Next() )
156 if ( !hText1 || (*pTopic->pName == hText1) )
158 q->hszSvc = *pService->pName;
159 q->hszTopic = *pTopic->pName;
160 q++;
163 #else
164 String sTopics( pService->Topics() );
165 USHORT n = 0;
166 while( STRING_NOTFOUND != n )
168 String s( sTopics.GetToken( 0, '\t', n ));
169 s.EraseAllChars( '\n' ).EraseAllChars( '\r' );
170 if( !hText1 || s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
172 DdeString aDStr( pInst->hDdeInstSvr, s );
173 pTopic = FindTopic( *pService, (HSZ)aDStr );
174 if( pTopic )
176 q->hszSvc = *pService->pName;
177 q->hszTopic = *pTopic->pName;
178 q++;
183 #endif
187 q->hszSvc = NULL;
188 q->hszTopic = NULL;
189 HDDEDATA h = DdeCreateDataHandle(
190 pInst->hDdeInstSvr, (LPBYTE) pPairs,
191 sizeof(HSZPAIR) * (nTopics+1),
192 0, NULL, nCbType, 0);
193 delete pPairs;
194 return h;
197 case XTYP_CONNECT:
198 pService = FindService( hText2 );
199 if ( pService)
200 pTopic = FindTopic( *pService, hText1 );
201 else
202 pTopic = NULL;
203 if ( pTopic )
204 return (HDDEDATA)DDE_FACK;
205 else
206 return (HDDEDATA) NULL;
208 case XTYP_CONNECT_CONFIRM:
209 pService = FindService( hText2 );
210 if ( pService )
212 pTopic = FindTopic( *pService, hText1 );
213 if ( pTopic )
215 pTopic->Connect( (long) hConv );
216 pC = new Conversation;
217 pC->hConv = hConv;
218 pC->pTopic = pTopic;
219 pService->pConv->Insert( pC );
222 return (HDDEDATA)NULL;
225 for ( pService = rAll.First(); pService; pService = rAll.Next() )
227 for( pC = pService->pConv->First(); pC;
228 pC = pService->pConv->Next() )
230 if ( pC->hConv == hConv )
231 goto found;
235 return (HDDEDATA) DDE_FNOTPROCESSED;
237 found:
238 if ( nCode == XTYP_DISCONNECT)
240 pC->pTopic->_Disconnect( (long) hConv );
241 pService->pConv->Remove( pC );
242 delete pC;
243 return (HDDEDATA)NULL;
246 BOOL bExec = BOOL(nCode == XTYP_EXECUTE);
247 pTopic = pC->pTopic;
248 if ( pTopic && !bExec )
249 pItem = FindItem( *pTopic, hText2 );
250 else
251 pItem = NULL;
253 if ( !bExec && !pService->HasCbFormat( nCbType ) )
254 pItem = NULL;
255 if ( !pItem && !bExec )
256 return (HDDEDATA)DDE_FNOTPROCESSED;
257 if ( pItem )
258 pTopic->aItem = pItem->GetName();
259 else
260 pTopic->aItem.Erase();
262 BOOL bRes = FALSE;
263 pInst->hCurConvSvr = (long)hConv;
264 switch( nCode )
266 case XTYP_REQUEST:
267 case XTYP_ADVREQ:
269 String aRes; // darf erst am Ende freigegeben werden!!
270 if ( pTopic->IsSystemTopic() )
272 if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) )
273 aRes = pService->Topics();
274 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) )
275 aRes = pService->SysItems();
276 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) )
277 aRes = pService->Status();
278 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) )
279 aRes = pService->Formats();
280 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) )
281 aRes = pService->GetHelp();
282 else
283 aRes = pService->SysTopicGet( pTopic->aItem );
285 if ( aRes.Len() )
286 pData = new DdeData( aRes );
287 else
288 pData = NULL;
290 else if( DDEGETPUTITEM == pItem->nType )
291 pData = ((DdeGetPutItem*)pItem)->Get(
292 DdeData::GetInternalFormat( nCbType ) );
293 else
294 pData = pTopic->Get( DdeData::GetInternalFormat( nCbType ));
296 if ( pData )
297 return DdeCreateDataHandle( pInst->hDdeInstSvr,
298 (LPBYTE)pData->pImp->pData,
299 pData->pImp->nData,
300 0, hText2,
301 DdeData::GetExternalFormat(
302 pData->pImp->nFmt ),
303 0 );
305 break;
307 case XTYP_POKE:
308 if ( !pTopic->IsSystemTopic() )
310 DdeData d;
311 d.pImp->hData = hData;
312 d.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
313 d.Lock();
314 if( DDEGETPUTITEM == pItem->nType )
315 bRes = ((DdeGetPutItem*)pItem)->Put( &d );
316 else
317 bRes = pTopic->Put( &d );
319 pInst->hCurConvSvr = NULL;
320 if ( bRes )
321 return (HDDEDATA)DDE_FACK;
322 else
323 return (HDDEDATA) DDE_FNOTPROCESSED;
325 case XTYP_ADVSTART:
327 // wird das Item zum erstenmal ein HotLink ?
328 if( !pItem->pImpData && pTopic->StartAdviseLoop() )
330 // dann wurde das Item ausgewechselt
331 pTopic->aItems.Remove( pItem );
332 DdeItem* pTmp;
333 for( pTmp = pTopic->aItems.First(); pTmp;
334 pTmp = pTopic->aItems.Next() )
335 if( *pTmp->pName == hText2 )
337 // es wurde tatsaechlich ausgewechselt
338 delete pItem;
339 pItem = 0;
340 break;
342 if( pItem )
343 // es wurde doch nicht ausgewechselt, also wieder rein
344 pTopic->aItems.Insert( pItem );
345 else
346 pItem = pTmp;
348 pItem->IncMonitor( (long)hConv );
349 pInst->hCurConvSvr = NULL;
351 return (HDDEDATA)TRUE;
353 case XTYP_ADVSTOP:
354 pItem->DecMonitor( (long)hConv );
355 if( !pItem->pImpData )
356 pTopic->StopAdviseLoop();
357 pInst->hCurConvSvr = NULL;
358 return (HDDEDATA)TRUE;
360 case XTYP_EXECUTE:
362 DdeData aExec;
363 aExec.pImp->hData = hData;
364 aExec.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
365 aExec.Lock();
366 String aName;
368 aName = (const sal_Unicode *)aExec.pImp->pData;
370 if( pTopic->IsSystemTopic() )
371 bRes = pService->SysTopicExecute( &aName );
372 else
373 bRes = pTopic->Execute( &aName );
375 pInst->hCurConvSvr = NULL;
376 if ( bRes )
377 return (HDDEDATA)DDE_FACK;
378 else
379 return (HDDEDATA)DDE_FNOTPROCESSED;
382 return (HDDEDATA)NULL;
385 // --- DdeInternat::FindService() ----------------------------------
387 DdeService* DdeInternal::FindService( HSZ hService )
389 DdeService* s;
390 DdeServices& rSvc = DdeService::GetServices();
391 for ( s = rSvc.First(); s; s = rSvc.Next() )
393 if ( *s->pName == hService )
394 return s;
397 return NULL;
400 // --- DdeInternat::FindTopic() ------------------------------------
402 DdeTopic* DdeInternal::FindTopic( DdeService& rService, HSZ hTopic )
404 DdeTopic* s;
405 DdeTopics& rTopics = rService.aTopics;
406 int bWeiter = FALSE;
407 DdeInstData* pInst = ImpGetInstData();
408 DBG_ASSERT(pInst,"SVDDE:No instance data");
410 do { // middle check loop
411 for ( s = rTopics.First(); s; s = rTopics.Next() )
413 if ( *s->pName == hTopic )
414 return s;
417 bWeiter = !bWeiter;
418 if( !bWeiter )
419 break;
421 // dann befragen wir doch mal unsere Ableitung:
422 TCHAR chBuf[250];
423 DdeQueryString(pInst->hDdeInstSvr,hTopic,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
424 bWeiter = rService.MakeTopic( reinterpret_cast<const sal_Unicode*>(chBuf) );
425 // dann muessen wir noch mal suchen
426 } while( bWeiter );
428 return 0;
431 // --- DdeInternal::FindItem() -------------------------------------
433 DdeItem* DdeInternal::FindItem( DdeTopic& rTopic, HSZ hItem )
435 DdeItem* s;
436 DdeItems& rItems = rTopic.aItems;
437 DdeInstData* pInst = ImpGetInstData();
438 DBG_ASSERT(pInst,"SVDDE:No instance data");
439 int bWeiter = FALSE;
441 do { // middle check loop
443 for ( s = rItems.First(); s; s = rItems.Next() )
444 if ( *s->pName == hItem )
445 return s;
447 bWeiter = !bWeiter;
448 if( !bWeiter )
449 break;
451 // dann befragen wir doch mal unsere Ableitung:
452 TCHAR chBuf[250];
453 DdeQueryString(pInst->hDdeInstSvr,hItem,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
454 bWeiter = rTopic.MakeItem( reinterpret_cast<const sal_Unicode*>(chBuf) );
455 // dann muessen wir noch mal suchen
456 } while( bWeiter );
458 return 0;
461 // --- DdeService::DdeService() ------------------------------------
463 DdeService::DdeService( const String& rService )
465 DdeInstData* pInst = ImpGetInstData();
466 if( !pInst )
467 pInst = ImpInitInstData();
468 pInst->nRefCount++;
469 pInst->nInstanceSvr++;
471 if ( !pInst->hDdeInstSvr )
473 nStatus = sal::static_int_cast< short >(
474 DdeInitialize( &pInst->hDdeInstSvr,
475 (PFNCALLBACK)DdeInternal::SvrCallback,
476 APPCLASS_STANDARD |
477 CBF_SKIP_REGISTRATIONS |
478 CBF_SKIP_UNREGISTRATIONS, 0L ) );
479 pInst->pServicesSvr = new DdeServices;
481 else
482 nStatus = DMLERR_NO_ERROR;
484 pConv = new ConvList;
486 if ( pInst->pServicesSvr )
487 pInst->pServicesSvr->Insert( this );
489 pName = new DdeString( pInst->hDdeInstSvr, rService );
490 if ( nStatus == DMLERR_NO_ERROR )
491 if ( !DdeNameService( pInst->hDdeInstSvr, *pName, NULL,
492 DNS_REGISTER | DNS_FILTEROFF ) )
493 nStatus = DMLERR_SYS_ERROR;
495 AddFormat( FORMAT_STRING );
496 pSysTopic = new DdeTopic( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) );
497 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) );
498 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) );
499 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) );
500 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) );
501 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) );
502 AddTopic( *pSysTopic );
505 // --- DdeService::~DdeService() -----------------------------------
507 DdeService::~DdeService()
509 DdeInstData* pInst = ImpGetInstData();
510 DBG_ASSERT(pInst,"SVDDE:No instance data");
511 if ( pInst->pServicesSvr )
512 pInst->pServicesSvr->Remove( this );
514 // MT: Im Auftrage des Herrn (AM) auskommentiert...
515 // Grund:
516 // Bei Client/Server werden die Server nicht beendet, wenn mehr
517 // als einer gestartet.
518 // Weil keine System-Messagequeue ?!
520 delete pSysTopic;
521 delete pName;
523 pInst->nInstanceSvr--;
524 pInst->nRefCount--;
525 if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr )
527 if( DdeUninitialize( pInst->hDdeInstSvr ) )
529 pInst->hDdeInstSvr = NULL;
530 delete pInst->pServicesSvr;
531 pInst->pServicesSvr = NULL;
532 if( pInst->nRefCount == 0)
533 ImpDeinitInstData();
536 delete pConv;
539 // --- DdeService::GetName() ---------------------------------------
541 const String& DdeService::GetName() const
543 return *pName;
546 // --- DdeService::GetServices() -----------------------------------
548 DdeServices& DdeService::GetServices()
550 DdeInstData* pInst = ImpGetInstData();
551 DBG_ASSERT(pInst,"SVDDE:No instance data");
552 return *(pInst->pServicesSvr);
555 // --- DdeService::AddTopic() --------------------------------------
557 void DdeService::AddTopic( const DdeTopic& rTopic )
559 RemoveTopic( rTopic );
560 aTopics.Insert( (DdeTopic*) &rTopic );
563 // --- DdeService::RemoveTopic() -----------------------------------
565 void DdeService::RemoveTopic( const DdeTopic& rTopic )
567 DdeTopic* t;
568 for ( t = aTopics.First(); t; t = aTopics.Next() )
570 if ( !DdeCmpStringHandles (*t->pName, *rTopic.pName ) )
572 aTopics.Remove( t );
573 // JP 27.07.95: und alle Conversions loeschen !!!
574 // (sonst wird auf geloeschten Topics gearbeitet!!)
575 for( ULONG n = pConv->Count(); n; )
577 Conversation* pC = pConv->GetObject( --n );
578 if( pC->pTopic == &rTopic )
580 pConv->Remove( pC );
581 delete pC;
584 break;
589 // --- DdeService::HasCbFormat() -----------------------------------
591 BOOL DdeService::HasCbFormat( USHORT nFmt )
593 return BOOL( aFormats.GetPos( nFmt ) != LIST_ENTRY_NOTFOUND );
596 // --- DdeService::HasFormat() -------------------------------------
598 BOOL DdeService::HasFormat( ULONG nFmt )
600 return HasCbFormat( (USHORT)DdeData::GetExternalFormat( nFmt ));
603 // --- DdeService::AddFormat() -------------------------------------
605 void DdeService::AddFormat( ULONG nFmt )
607 nFmt = DdeData::GetExternalFormat( nFmt );
608 aFormats.Remove( nFmt );
609 aFormats.Insert( nFmt );
612 // --- DdeService::RemoveFormat() ----------------------------------
614 void DdeService::RemoveFormat( ULONG nFmt )
616 aFormats.Remove( DdeData::GetExternalFormat( nFmt ) );
619 // --- DdeTopic::DdeTopic() ----------------------------------------
621 DdeTopic::DdeTopic( const String& rName )
623 DdeInstData* pInst = ImpGetInstData();
624 DBG_ASSERT(pInst,"SVDDE:No instance data");
625 pName = new DdeString( pInst->hDdeInstSvr, rName );
628 // --- DdeTopic::~DdeTopic() ---------------------------------------
630 DdeTopic::~DdeTopic()
632 DdeItem* t;
633 while( ( t = aItems.First() ) != NULL )
635 aItems.Remove( t );
636 t->pMyTopic = 0;
637 delete t;
639 delete pName;
642 // --- DdeTopic::GetName() -----------------------------------------
644 const String& DdeTopic::GetName() const
646 return *pName;
649 // --- DdeTopic::IsSystemTopic() -----------------------------------
651 BOOL DdeTopic::IsSystemTopic()
653 return BOOL (GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC));
656 // --- DdeTopic::AddItem() -----------------------------------------
658 DdeItem* DdeTopic::AddItem( const DdeItem& r )
660 DdeItem* s;
661 if( DDEGETPUTITEM == r.nType )
662 s = new DdeGetPutItem( r );
663 else
664 s = new DdeItem( r );
665 if ( s )
667 aItems.Insert( s );
668 s->pMyTopic = this;
670 return s;
673 // --- DdeTopic::InsertItem() -----------------------------------------
675 void DdeTopic::InsertItem( DdeItem* pNew )
677 if( pNew )
679 aItems.Insert( pNew );
680 pNew->pMyTopic = this;
684 // --- DdeTopic::RemoveItem() --------------------------------------
686 void DdeTopic::RemoveItem( const DdeItem& r )
688 DdeItem* s;
689 for ( s = aItems.First(); s; s = aItems.Next() )
691 if ( !DdeCmpStringHandles (*s->pName, *r.pName ) )
692 break;
695 if ( s )
697 aItems.Remove( s );
698 s->pMyTopic = 0;
699 delete s;
703 // --- DdeTopic::NotifyClient() ------------------------------------
705 void DdeTopic::NotifyClient( const String& rItem )
707 DdeItem* pItem;
708 DdeInstData* pInst = ImpGetInstData();
709 DBG_ASSERT(pInst,"SVDDE:No instance data");
710 for ( pItem = aItems.First(); pItem; pItem = aItems.Next() )
712 if ( pItem->GetName() == rItem )
714 if ( pItem->pImpData )
715 DdePostAdvise( pInst->hDdeInstSvr, *pName, *pItem->pName );
717 break;
721 // --- DdeTopic::Connect() -----------------------------------------
723 void __EXPORT DdeTopic::Connect( long nId )
725 aConnectLink.Call( (void*)nId );
728 // --- DdeTopic::Disconnect() --------------------------------------
730 void __EXPORT DdeTopic::Disconnect( long nId )
732 aDisconnectLink.Call( (void*)nId );
735 // --- DdeTopic::_Disconnect() --------------------------------------
737 void __EXPORT DdeTopic::_Disconnect( long nId )
739 for( DdeItem* pItem = aItems.First(); pItem; pItem = aItems.Next() )
740 pItem->DecMonitor( nId );
742 Disconnect( nId );
745 // --- DdeTopic::Get() ---------------------------------------------
747 DdeData* __EXPORT DdeTopic::Get( ULONG nFmt )
749 if ( aGetLink.IsSet() )
750 return (DdeData*)aGetLink.Call( (void*)nFmt );
751 else
752 return NULL;
755 // --- DdeTopic::Put() ---------------------------------------------
757 BOOL __EXPORT DdeTopic::Put( const DdeData* r )
759 if ( aPutLink.IsSet() )
760 return (BOOL)aPutLink.Call( (void*) r );
761 else
762 return FALSE;
765 // --- DdeTopic::Execute() -----------------------------------------
767 BOOL __EXPORT DdeTopic::Execute( const String* r )
769 if ( aExecLink.IsSet() )
770 return (BOOL)aExecLink.Call( (void*)r );
771 else
772 return FALSE;
775 // --- DdeTopic::GetConvId() ---------------------------------------
777 long DdeTopic::GetConvId()
779 DdeInstData* pInst = ImpGetInstData();
780 DBG_ASSERT(pInst,"SVDDE:No instance data");
781 return pInst->hCurConvSvr;
784 // --- DdeTopic::StartAdviseLoop() ---------------------------------
786 BOOL DdeTopic::StartAdviseLoop()
788 return FALSE;
791 // --- DdeTopic::StopAdviseLoop() ----------------------------------
793 BOOL DdeTopic::StopAdviseLoop()
795 return FALSE;
798 // --- DdeItem::DdeItem() ------------------------------------------
800 DdeItem::DdeItem( const sal_Unicode* p )
802 DdeInstData* pInst = ImpGetInstData();
803 DBG_ASSERT(pInst,"SVDDE:No instance data");
804 pName = new DdeString( pInst->hDdeInstSvr, p );
805 nType = DDEITEM;
806 pMyTopic = 0;
807 pImpData = 0;
810 // --- DdeItem::DdeItem() ------------------------------------------
812 DdeItem::DdeItem( const String& r)
814 DdeInstData* pInst = ImpGetInstData();
815 DBG_ASSERT(pInst,"SVDDE:No instance data");
816 pName = new DdeString( pInst->hDdeInstSvr, r );
817 nType = DDEITEM;
818 pMyTopic = 0;
819 pImpData = 0;
822 // --- DdeItem::DdeItem() ------------------------------------------
824 DdeItem::DdeItem( const DdeItem& r)
826 DdeInstData* pInst = ImpGetInstData();
827 DBG_ASSERT(pInst,"SVDDE:No instance data");
828 pName = new DdeString( pInst->hDdeInstSvr, *r.pName );
829 nType = DDEITEM;
830 pMyTopic = 0;
831 pImpData = 0;
834 // --- DdeItem::~DdeItem() -----------------------------------------
836 DdeItem::~DdeItem()
838 if( pMyTopic )
839 pMyTopic->aItems.Remove( this );
840 delete pName;
841 delete pImpData;
844 // --- DdeItem::GetName() ------------------------------------------
846 const String& DdeItem::GetName() const
848 return *pName;
851 // --- DdeItem::NotifyClient() ------------------------------------------
853 void DdeItem::NotifyClient()
855 if( pMyTopic && pImpData )
857 DdeInstData* pInst = ImpGetInstData();
858 DBG_ASSERT(pInst,"SVDDE:No instance data");
859 DdePostAdvise( pInst->hDdeInstSvr, *pMyTopic->pName, *pName );
863 // --- DdeItem::IncMonitor() ------------------------------------------
865 void DdeItem::IncMonitor( ULONG nHCnv )
867 if( !pImpData )
869 pImpData = new DdeItemImp;
870 if( DDEGETPUTITEM == nType )
871 ((DdeGetPutItem*)this)->AdviseLoop( TRUE );
873 else
875 for( USHORT n = pImpData->Count(); n; )
876 if( (*pImpData)[ --n ].nHCnv == nHCnv )
878 ++(*pImpData)[ n ].nHCnv;
879 return ;
883 pImpData->Insert( DdeItemImpData( nHCnv ), pImpData->Count() );
886 // --- DdeItem::DecMonitor() ------------------------------------------
888 void DdeItem::DecMonitor( ULONG nHCnv )
890 if( pImpData )
892 DdeItemImpData* pData = (DdeItemImpData*)pImpData->GetData();
893 for( USHORT n = pImpData->Count(); n; --n, ++pData )
894 if( pData->nHCnv == nHCnv )
896 if( !pData->nCnt || !--pData->nCnt )
898 if( 1 < pImpData->Count() )
899 pImpData->Remove( pImpData->Count() - n );
900 else
902 delete pImpData, pImpData = 0;
903 if( DDEGETPUTITEM == nType )
904 ((DdeGetPutItem*)this)->AdviseLoop( FALSE );
907 return ;
912 // --- DdeItem::GetLinks() ------------------------------------------
914 short DdeItem::GetLinks()
916 short nCnt = 0;
917 if( pImpData )
918 for( USHORT n = pImpData->Count(); n; )
919 nCnt = nCnt + (*pImpData)[ --n ].nCnt;
920 return nCnt;
923 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
925 DdeGetPutItem::DdeGetPutItem( const sal_Unicode* p )
926 : DdeItem( p )
928 nType = DDEGETPUTITEM;
931 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
933 DdeGetPutItem::DdeGetPutItem( const String& rStr )
934 : DdeItem( rStr )
936 nType = DDEGETPUTITEM;
939 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
941 DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem )
942 : DdeItem( rItem )
944 nType = DDEGETPUTITEM;
948 // --- DdeGetPutData::Get() ----------------------------------------
950 DdeData* DdeGetPutItem::Get( ULONG )
952 return 0;
955 // --- DdeGetPutData::Put() ----------------------------------------
957 BOOL DdeGetPutItem::Put( const DdeData* )
959 return FALSE;
962 // --- DdeGetPutData::AdviseLoop() ---------------------------------
964 void DdeGetPutItem::AdviseLoop( BOOL )
969 // --- DdeService::SysItems() --------------------------------------
971 String DdeService::SysItems()
973 String s;
974 DdeTopic* t;
975 for ( t = aTopics.First(); t; t = aTopics.Next() )
977 if ( t->GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) )
979 short n = 0;
980 DdeItem* pi;
981 for ( pi = t->aItems.First(); pi; pi = t->aItems.Next(), n++ )
983 if ( n )
984 s += '\t';
985 s += pi->GetName();
987 s += String::CreateFromAscii("\r\n");
991 return s;
994 // --- DdeService::Topics() ----------------------------------------
996 String DdeService::Topics()
998 String s;
999 DdeTopic* t;
1000 short n = 0;
1002 for ( t = aTopics.First(); t; t = aTopics.Next(), n++ )
1004 if ( n )
1005 s += '\t';
1006 s += t->GetName();
1008 s += String::CreateFromAscii("\r\n");
1010 return s;
1013 // --- DdeService::Formats() ---------------------------------------
1015 String DdeService::Formats()
1017 String s;
1018 long f;
1019 TCHAR buf[128];
1020 LPCTSTR p;
1021 short n = 0;
1023 for ( f = aFormats.First(); f; f = aFormats.Next(), n++ )
1025 if ( n )
1026 s += '\t';
1027 p = buf;
1029 switch( (USHORT)f )
1031 case CF_TEXT:
1032 p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("TEXT").GetBuffer());
1033 break;
1034 case CF_BITMAP:
1035 p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("BITMAP").GetBuffer());
1036 break;
1037 #ifdef OS2
1038 case CF_DSPTEXT:
1039 p = String::CreateFromAscii("TEXT").GetBuffer();
1040 break;
1041 case CF_DSPBITMAP:
1042 p = String::CreateFromAscii("BITMAP").GetBuffer();
1043 break;
1044 case CF_METAFILE:
1045 p = String::CreateFromAscii("METAFILE").GetBuffer();
1046 break;
1047 case CF_DSPMETAFILE:
1048 p = String::CreateFromAscii("METAFILE").GetBuffer();
1049 break;
1050 case CF_PALETTE:
1051 p = String::CreateFromAscii("PALETTE").GetBuffer();
1052 break;
1053 default:
1054 p= String::CreateFromAscii("PRIVATE").GetBuffer();
1055 #else
1056 default:
1057 GetClipboardFormatName( (UINT)f, buf, sizeof(buf) / sizeof(TCHAR) );
1058 #endif
1060 s += String( reinterpret_cast<const sal_Unicode*>(p) );
1062 s += String::CreateFromAscii("\r\n");
1064 return s;
1067 // --- DdeService::Status() ----------------------------------------
1069 String DdeService::Status()
1071 return IsBusy() ? String::CreateFromAscii("Busy\r\n") : String::CreateFromAscii("Ready\r\n");
1074 // --- DdeService::IsBusy() ----------------------------------------
1076 BOOL __EXPORT DdeService::IsBusy()
1078 return FALSE;
1081 // --- DdeService::GetHelp() ----------------------------------------
1083 String __EXPORT DdeService::GetHelp()
1085 return String();
1088 BOOL DdeTopic::MakeItem( const String& )
1090 return FALSE;
1093 BOOL DdeService::MakeTopic( const String& )
1095 return FALSE;
1098 String DdeService::SysTopicGet( const String& )
1100 return String();
1103 BOOL DdeService::SysTopicExecute( const String* )
1105 return FALSE;