bump product version to 4.1.6.2
[LibreOffice.git] / svl / source / svdde / ddesvr.cxx
blob202d26d9f18f33a68bb0ab105582b60aebc53b19
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #define UNICODE
22 #include "ddeimp.hxx"
23 #include <algorithm>
24 #include <comphelper/string.hxx>
25 #include <svl/svdde.hxx>
26 #include <tools/debug.hxx>
27 #include <osl/thread.h>
28 #include <o3tl/sorted_vector.hxx>
30 enum DdeItemType
32 DDEITEM,
33 DDEGETPUTITEM
36 struct DdeItemImpData
38 sal_uLong nHCnv;
39 sal_uInt16 nCnt;
41 DdeItemImpData( sal_uLong nH ) : nHCnv( nH ), nCnt( 1 ) {}
44 class DdeItemImp : public std::vector<DdeItemImpData> {};
46 // --- DdeInternat::SvrCallback() ----------------------------------
48 #ifdef WNT
49 HDDEDATA CALLBACK DdeInternal::SvrCallback(
50 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
51 HDDEDATA hData, DWORD, DWORD )
52 #else
53 #if defined( ICC )
54 HDDEDATA CALLBACK DdeInternal::SvrCallback(
55 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
56 HDDEDATA hData, DWORD, DWORD )
57 #else
58 HDDEDATA CALLBACK _export DdeInternal::SvrCallback(
59 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
60 HDDEDATA hData, DWORD, DWORD )
61 #endif
62 #endif
64 DdeServices& rAll = DdeService::GetServices();
65 DdeService* pService;
66 DdeTopic* pTopic;
67 DdeItem* pItem;
68 DdeData* pData;
69 Conversation* pC;
71 DdeInstData* pInst = ImpGetInstData();
72 DBG_ASSERT(pInst,"SVDDE:No instance data");
74 switch( nCode )
76 case XTYP_WILDCONNECT:
78 int nTopics = 0;
80 TCHAR chTopicBuf[250];
81 if( hText1 )
82 DdeQueryString( pInst->hDdeInstSvr, hText1, chTopicBuf,
83 sizeof(chTopicBuf)/sizeof(TCHAR), CP_WINUNICODE );
85 for (DdeServices::iterator aI = rAll.begin(); aI != rAll.end(); ++aI)
87 pService = *aI;
88 if ( !hText2 || ( *pService->pName == hText2 ) )
90 String sTopics( pService->Topics() );
91 if( sTopics.Len() )
93 if( hText1 )
95 sal_Int32 n = 0;
96 while( -1 != n )
98 OUString s( sTopics.GetToken( 0, '\t', n ));
99 if( s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
100 ++nTopics;
103 else
104 nTopics += comphelper::string::getTokenCount(sTopics, '\t');
109 if( !nTopics )
110 return (HDDEDATA)NULL;
112 HSZPAIR* pPairs = new HSZPAIR [nTopics + 1];
113 if ( !pPairs )
114 return (HDDEDATA)NULL;
116 HSZPAIR* q = pPairs;
117 for (DdeServices::iterator aI = rAll.begin(); aI != rAll.end(); ++aI)
119 pService = *aI;
120 if ( !hText2 || (*pService->pName == hText2 ) )
122 String sTopics( pService->Topics() );
123 sal_Int32 n = 0;
124 while( -1 != n )
126 OUString s( sTopics.GetToken( 0, '\t', n ));
127 s = comphelper::string::remove(s, '\n');
128 s = comphelper::string::remove(s, '\r');
129 if( !hText1 || s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
131 DdeString aDStr( pInst->hDdeInstSvr, s );
132 pTopic = FindTopic( *pService, (HSZ)aDStr );
133 if( pTopic )
135 q->hszSvc = *pService->pName;
136 q->hszTopic = *pTopic->pName;
137 q++;
144 q->hszSvc = NULL;
145 q->hszTopic = NULL;
146 HDDEDATA h = DdeCreateDataHandle(
147 pInst->hDdeInstSvr, (LPBYTE) pPairs,
148 sizeof(HSZPAIR) * (nTopics+1),
149 0, NULL, nCbType, 0);
150 delete [] pPairs;
151 return h;
154 case XTYP_CONNECT:
155 pService = FindService( hText2 );
156 if ( pService)
157 pTopic = FindTopic( *pService, hText1 );
158 else
159 pTopic = NULL;
160 if ( pTopic )
161 return (HDDEDATA)DDE_FACK;
162 else
163 return (HDDEDATA) NULL;
165 case XTYP_CONNECT_CONFIRM:
166 pService = FindService( hText2 );
167 if ( pService )
169 pTopic = FindTopic( *pService, hText1 );
170 if ( pTopic )
172 pTopic->Connect( (long) hConv );
173 pC = new Conversation;
174 pC->hConv = hConv;
175 pC->pTopic = pTopic;
176 pService->pConv->push_back( pC );
179 return (HDDEDATA)NULL;
182 for (DdeServices::iterator aI = rAll.begin(); aI != rAll.end(); ++aI)
184 pService = *aI;
185 for ( size_t i = 0, n = pService->pConv->size(); i < n; ++i )
187 pC = (*pService->pConv)[ i ];
188 if ( pC->hConv == hConv )
189 goto found;
193 return (HDDEDATA) DDE_FNOTPROCESSED;
195 found:
196 if ( nCode == XTYP_DISCONNECT)
198 pC->pTopic->_Disconnect( (long) hConv );
199 for ( ConvList::iterator it = pService->pConv->begin();
200 it != pService->pConv->end();
201 ++it
203 if ( *it == pC )
205 delete *it;
206 pService->pConv->erase( it );
207 break;
210 return (HDDEDATA)NULL;
213 sal_Bool bExec = sal_Bool(nCode == XTYP_EXECUTE);
214 pTopic = pC->pTopic;
215 if ( pTopic && !bExec )
216 pItem = FindItem( *pTopic, hText2 );
217 else
218 pItem = NULL;
220 if ( !bExec && !pService->HasCbFormat( nCbType ) )
221 pItem = NULL;
222 if ( !pItem && !bExec )
223 return (HDDEDATA)DDE_FNOTPROCESSED;
224 if ( pItem )
225 pTopic->aItem = pItem->GetName();
226 else
227 pTopic->aItem = OUString();
229 sal_Bool bRes = sal_False;
230 pInst->hCurConvSvr = (long)hConv;
231 switch( nCode )
233 case XTYP_REQUEST:
234 case XTYP_ADVREQ:
236 String aRes; // darf erst am Ende freigegeben werden!!
237 if ( pTopic->IsSystemTopic() )
239 if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) )
240 aRes = pService->Topics();
241 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) )
242 aRes = pService->SysItems();
243 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) )
244 aRes = pService->Status();
245 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) )
246 aRes = pService->Formats();
247 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) )
248 aRes = pService->GetHelp();
249 else
250 aRes = pService->SysTopicGet( pTopic->aItem );
252 if ( aRes.Len() )
253 pData = new DdeData( aRes );
254 else
255 pData = NULL;
257 else if( DDEGETPUTITEM == pItem->nType )
258 pData = ((DdeGetPutItem*)pItem)->Get(
259 DdeData::GetInternalFormat( nCbType ) );
260 else
261 pData = pTopic->Get( DdeData::GetInternalFormat( nCbType ));
263 if ( pData )
264 return DdeCreateDataHandle( pInst->hDdeInstSvr,
265 (LPBYTE)pData->pImp->pData,
266 pData->pImp->nData,
267 0, hText2,
268 DdeData::GetExternalFormat(
269 pData->pImp->nFmt ),
270 0 );
272 break;
274 case XTYP_POKE:
275 if ( !pTopic->IsSystemTopic() )
277 DdeData d;
278 d.pImp->hData = hData;
279 d.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
280 d.Lock();
281 if( DDEGETPUTITEM == pItem->nType )
282 bRes = ((DdeGetPutItem*)pItem)->Put( &d );
283 else
284 bRes = pTopic->Put( &d );
286 pInst->hCurConvSvr = 0;
287 if ( bRes )
288 return (HDDEDATA)DDE_FACK;
289 else
290 return (HDDEDATA) DDE_FNOTPROCESSED;
292 case XTYP_ADVSTART:
294 // wird das Item zum erstenmal ein HotLink ?
295 if( !pItem->pImpData && pTopic->StartAdviseLoop() )
297 // dann wurde das Item ausgewechselt
298 std::vector<DdeItem*>::iterator it(std::find(pTopic->aItems.begin(),
299 pTopic->aItems.end(),
300 pItem));
301 if (it != pTopic->aItems.end())
302 pTopic->aItems.erase(it);
304 std::vector<DdeItem*>::iterator iter;
305 for( iter = pTopic->aItems.begin();
306 iter != pTopic->aItems.end();
307 ++iter )
309 if( *(*iter)->pName == hText2 )
311 // es wurde tatsaechlich ausgewechselt
312 delete pItem;
313 pItem = 0;
314 break;
318 if( pItem )
319 // es wurde doch nicht ausgewechselt, also wieder rein
320 pTopic->aItems.push_back(pItem);
321 else
322 pItem = iter != pTopic->aItems.end() ? *iter : NULL;
325 if (pItem)
327 pItem->IncMonitor( (long)hConv );
328 pInst->hCurConvSvr = 0;
331 return (HDDEDATA)sal_True;
333 case XTYP_ADVSTOP:
334 pItem->DecMonitor( (long)hConv );
335 if( !pItem->pImpData )
336 pTopic->StopAdviseLoop();
337 pInst->hCurConvSvr = 0;
338 return (HDDEDATA)sal_True;
340 case XTYP_EXECUTE:
342 DdeData aExec;
343 aExec.pImp->hData = hData;
344 aExec.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
345 aExec.Lock();
346 String aName;
348 aName = (const sal_Unicode *)aExec.pImp->pData;
350 if( pTopic->IsSystemTopic() )
351 bRes = pService->SysTopicExecute( &aName );
352 else
353 bRes = pTopic->Execute( &aName );
355 pInst->hCurConvSvr = 0;
356 if ( bRes )
357 return (HDDEDATA)DDE_FACK;
358 else
359 return (HDDEDATA)DDE_FNOTPROCESSED;
362 return (HDDEDATA)NULL;
365 // --- DdeInternat::FindService() ----------------------------------
367 DdeService* DdeInternal::FindService( HSZ hService )
369 DdeService* s;
370 DdeServices& rSvc = DdeService::GetServices();
371 for (DdeServices::iterator aI = rSvc.begin(); aI != rSvc.end(); ++aI)
373 s = *aI;
374 if ( *s->pName == hService )
375 return s;
378 return NULL;
381 // --- DdeInternat::FindTopic() ------------------------------------
383 DdeTopic* DdeInternal::FindTopic( DdeService& rService, HSZ hTopic )
385 std::vector<DdeTopic*>::iterator iter;
386 std::vector<DdeTopic*> &rTopics = rService.aTopics;
387 int bWeiter = sal_False;
388 DdeInstData* pInst = ImpGetInstData();
389 DBG_ASSERT(pInst,"SVDDE:No instance data");
391 do { // middle check loop
392 for ( iter = rTopics.begin(); iter != rTopics.end(); ++iter )
394 if ( *(*iter)->pName == hTopic )
395 return *iter;
398 bWeiter = !bWeiter;
399 if( !bWeiter )
400 break;
402 // dann befragen wir doch mal unsere Ableitung:
403 TCHAR chBuf[250];
404 DdeQueryString(pInst->hDdeInstSvr,hTopic,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
405 bWeiter = rService.MakeTopic( reinterpret_cast<const sal_Unicode*>(chBuf) );
406 // dann muessen wir noch mal suchen
407 } while( bWeiter );
409 return 0;
412 // --- DdeInternal::FindItem() -------------------------------------
414 DdeItem* DdeInternal::FindItem( DdeTopic& rTopic, HSZ hItem )
416 std::vector<DdeItem*>::iterator iter;
417 std::vector<DdeItem*> &rItems = rTopic.aItems;
418 DdeInstData* pInst = ImpGetInstData();
419 DBG_ASSERT(pInst,"SVDDE:No instance data");
420 int bWeiter = sal_False;
422 do { // middle check loop
424 for ( iter = rItems.begin(); iter != rItems.end(); ++iter )
425 if ( *(*iter)->pName == hItem )
426 return *iter;
428 bWeiter = !bWeiter;
429 if( !bWeiter )
430 break;
432 // dann befragen wir doch mal unsere Ableitung:
433 TCHAR chBuf[250];
434 DdeQueryString(pInst->hDdeInstSvr,hItem,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
435 bWeiter = rTopic.MakeItem( reinterpret_cast<const sal_Unicode*>(chBuf) );
436 // dann muessen wir noch mal suchen
437 } while( bWeiter );
439 return 0;
442 // --- DdeService::DdeService() ------------------------------------
444 DdeService::DdeService( const String& rService )
446 DdeInstData* pInst = ImpGetInstData();
447 if( !pInst )
448 pInst = ImpInitInstData();
449 pInst->nRefCount++;
450 pInst->nInstanceSvr++;
452 if ( !pInst->hDdeInstSvr )
454 nStatus = sal::static_int_cast< short >(
455 DdeInitialize( &pInst->hDdeInstSvr,
456 (PFNCALLBACK)DdeInternal::SvrCallback,
457 APPCLASS_STANDARD |
458 CBF_SKIP_REGISTRATIONS |
459 CBF_SKIP_UNREGISTRATIONS, 0L ) );
460 pInst->pServicesSvr = new DdeServices;
462 else
463 nStatus = DMLERR_NO_ERROR;
465 pConv = new ConvList;
467 if ( pInst->pServicesSvr )
468 pInst->pServicesSvr->push_back( this );
470 pName = new DdeString( pInst->hDdeInstSvr, rService );
471 if ( nStatus == DMLERR_NO_ERROR )
472 if ( !DdeNameService( pInst->hDdeInstSvr, *pName, NULL,
473 DNS_REGISTER | DNS_FILTEROFF ) )
474 nStatus = DMLERR_SYS_ERROR;
476 AddFormat( FORMAT_STRING );
477 pSysTopic = new DdeTopic( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) );
478 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) );
479 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) );
480 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) );
481 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) );
482 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) );
483 AddTopic( *pSysTopic );
486 // --- DdeService::~DdeService() -----------------------------------
488 DdeService::~DdeService()
490 DdeInstData* pInst = ImpGetInstData();
491 DBG_ASSERT(pInst,"SVDDE:No instance data");
492 if ( pInst->pServicesSvr )
493 pInst->pServicesSvr->erase(std::remove(pInst->pServicesSvr->begin(), pInst->pServicesSvr->end(), this), pInst->pServicesSvr->end());
495 // MT: Im Auftrage des Herrn (AM) auskommentiert...
496 // Grund:
497 // Bei Client/Server werden die Server nicht beendet, wenn mehr
498 // als einer gestartet.
499 // Weil keine System-Messagequeue ?!
501 delete pSysTopic;
502 delete pName;
504 pInst->nInstanceSvr--;
505 pInst->nRefCount--;
506 if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr )
508 if( DdeUninitialize( pInst->hDdeInstSvr ) )
510 pInst->hDdeInstSvr = 0;
511 delete pInst->pServicesSvr;
512 pInst->pServicesSvr = NULL;
513 if( pInst->nRefCount == 0)
514 ImpDeinitInstData();
517 delete pConv;
520 // --- DdeService::GetName() ---------------------------------------
522 const OUString DdeService::GetName() const
524 return pName->toOUString();
527 // --- DdeService::GetServices() -----------------------------------
529 DdeServices& DdeService::GetServices()
531 DdeInstData* pInst = ImpGetInstData();
532 DBG_ASSERT(pInst,"SVDDE:No instance data");
533 return *(pInst->pServicesSvr);
536 // --- DdeService::AddTopic() --------------------------------------
538 void DdeService::AddTopic( const DdeTopic& rTopic )
540 RemoveTopic( rTopic );
541 aTopics.push_back((DdeTopic *) &rTopic);
544 // --- DdeService::RemoveTopic() -----------------------------------
546 void DdeService::RemoveTopic( const DdeTopic& rTopic )
548 std::vector<DdeTopic*>::iterator iter;
549 for ( iter = aTopics.begin(); iter != aTopics.end(); ++iter )
551 if ( !DdeCmpStringHandles (*(*iter)->pName, *rTopic.pName ) )
553 aTopics.erase(iter);
554 // JP 27.07.95: und alle Conversions loeschen !!!
555 // (sonst wird auf geloeschten Topics gearbeitet!!)
556 for( size_t n = pConv->size(); n; )
558 Conversation* pC = (*pConv)[ --n ];
559 if( pC->pTopic == &rTopic )
561 ConvList::iterator it = pConv->begin();
562 ::std::advance( it, n );
563 delete *it;
564 pConv->erase( it );
567 break;
572 // --- DdeService::HasCbFormat() -----------------------------------
574 sal_Bool DdeService::HasCbFormat( sal_uInt16 nFmt )
576 for ( size_t i = 0, n = aFormats.size(); i < n; ++i )
577 if ( aFormats[ i ] == nFmt )
578 return true;
579 return false;
582 // --- DdeService::HasFormat() -------------------------------------
584 sal_Bool DdeService::HasFormat( sal_uLong nFmt )
586 return HasCbFormat( (sal_uInt16)DdeData::GetExternalFormat( nFmt ));
589 // --- DdeService::AddFormat() -------------------------------------
591 void DdeService::AddFormat( sal_uLong nFmt )
593 nFmt = DdeData::GetExternalFormat( nFmt );
594 for ( size_t i = 0, n = aFormats.size(); i < n; ++i )
595 if ( (sal_uLong) aFormats[ i ] == nFmt )
596 return;
597 aFormats.push_back( nFmt );
600 // --- DdeService::RemoveFormat() ----------------------------------
602 void DdeService::RemoveFormat( sal_uLong nFmt )
604 nFmt = DdeData::GetExternalFormat( nFmt );
605 for ( DdeFormats::iterator it = aFormats.begin(); it != aFormats.end(); ++it ) {
606 if ( (sal_uLong) *it == nFmt ) {
607 aFormats.erase( it );
608 break;
613 // --- DdeTopic::DdeTopic() ----------------------------------------
615 DdeTopic::DdeTopic( const OUString& rName )
617 DdeInstData* pInst = ImpGetInstData();
618 DBG_ASSERT(pInst,"SVDDE:No instance data");
619 pName = new DdeString( pInst->hDdeInstSvr, rName );
622 // --- DdeTopic::~DdeTopic() ---------------------------------------
624 DdeTopic::~DdeTopic()
626 std::vector<DdeItem*>::iterator iter;
627 for (iter = aItems.begin(); iter != aItems.end(); ++iter)
629 (*iter)->pMyTopic = 0;
630 delete *iter;
633 delete pName;
636 // --- DdeTopic::GetName() -----------------------------------------
638 const OUString DdeTopic::GetName() const
640 return pName->toOUString();
643 // --- DdeTopic::IsSystemTopic() -----------------------------------
645 sal_Bool DdeTopic::IsSystemTopic()
647 return sal_Bool (GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC));
650 // --- DdeTopic::AddItem() -----------------------------------------
652 DdeItem* DdeTopic::AddItem( const DdeItem& r )
654 DdeItem* s;
655 if( DDEGETPUTITEM == r.nType )
656 s = new DdeGetPutItem( r );
657 else
658 s = new DdeItem( r );
659 if ( s )
661 aItems.push_back( s );
662 s->pMyTopic = this;
664 return s;
667 // --- DdeTopic::InsertItem() -----------------------------------------
669 void DdeTopic::InsertItem( DdeItem* pNew )
671 if( pNew )
673 aItems.push_back( pNew );
674 pNew->pMyTopic = this;
678 // --- DdeTopic::RemoveItem() --------------------------------------
680 void DdeTopic::RemoveItem( const DdeItem& r )
682 std::vector<DdeItem*>::iterator iter;
683 for (iter = aItems.begin(); iter != aItems.end(); ++iter)
685 if ( !DdeCmpStringHandles (*(*iter)->pName, *r.pName ) )
686 break;
689 if ( iter != aItems.end() )
691 (*iter)->pMyTopic = 0;
692 delete *iter;
693 aItems.erase(iter);
697 // --- DdeTopic::NotifyClient() ------------------------------------
699 void DdeTopic::NotifyClient( const String& rItem )
701 std::vector<DdeItem*>::iterator iter;
702 DdeInstData* pInst = ImpGetInstData();
703 DBG_ASSERT(pInst,"SVDDE:No instance data");
704 for ( iter = aItems.begin(); iter != aItems.end(); ++iter)
706 if ( (*iter)->GetName().equals(rItem) && (*iter)->pImpData)
708 DdePostAdvise( pInst->hDdeInstSvr, *pName, *(*iter)->pName );
709 break;
714 // --- DdeTopic::Connect() -----------------------------------------
716 void DdeTopic::Connect( long nId )
718 aConnectLink.Call( (void*)nId );
721 // --- DdeTopic::Disconnect() --------------------------------------
723 void DdeTopic::Disconnect( long nId )
725 aDisconnectLink.Call( (void*)nId );
728 // --- DdeTopic::_Disconnect() --------------------------------------
730 void DdeTopic::_Disconnect( long nId )
732 std::vector<DdeItem*>::iterator iter;
733 for (iter = aItems.begin(); iter != aItems.end(); ++iter)
734 (*iter)->DecMonitor( nId );
736 Disconnect( nId );
739 // --- DdeTopic::Get() ---------------------------------------------
741 DdeData* DdeTopic::Get( sal_uLong nFmt )
743 if ( aGetLink.IsSet() )
744 return (DdeData*)aGetLink.Call( (void*)nFmt );
745 else
746 return NULL;
749 // --- DdeTopic::Put() ---------------------------------------------
751 sal_Bool DdeTopic::Put( const DdeData* r )
753 if ( aPutLink.IsSet() )
754 return (sal_Bool)aPutLink.Call( (void*) r );
755 else
756 return sal_False;
759 // --- DdeTopic::Execute() -----------------------------------------
761 sal_Bool DdeTopic::Execute( const String* r )
763 if ( aExecLink.IsSet() )
764 return (sal_Bool)aExecLink.Call( (void*)r );
765 else
766 return sal_False;
769 // --- DdeTopic::GetConvId() ---------------------------------------
771 long DdeTopic::GetConvId()
773 DdeInstData* pInst = ImpGetInstData();
774 DBG_ASSERT(pInst,"SVDDE:No instance data");
775 return pInst->hCurConvSvr;
778 // --- DdeTopic::StartAdviseLoop() ---------------------------------
780 sal_Bool DdeTopic::StartAdviseLoop()
782 return sal_False;
785 // --- DdeTopic::StopAdviseLoop() ----------------------------------
787 sal_Bool DdeTopic::StopAdviseLoop()
789 return sal_False;
792 // --- DdeItem::DdeItem() ------------------------------------------
794 DdeItem::DdeItem( const sal_Unicode* p )
796 DdeInstData* pInst = ImpGetInstData();
797 DBG_ASSERT(pInst,"SVDDE:No instance data");
798 pName = new DdeString( pInst->hDdeInstSvr, p );
799 nType = DDEITEM;
800 pMyTopic = 0;
801 pImpData = 0;
804 // --- DdeItem::DdeItem() ------------------------------------------
806 DdeItem::DdeItem( const String& r)
808 DdeInstData* pInst = ImpGetInstData();
809 DBG_ASSERT(pInst,"SVDDE:No instance data");
810 pName = new DdeString( pInst->hDdeInstSvr, r );
811 nType = DDEITEM;
812 pMyTopic = 0;
813 pImpData = 0;
816 // --- DdeItem::DdeItem() ------------------------------------------
818 DdeItem::DdeItem( const DdeItem& r)
820 DdeInstData* pInst = ImpGetInstData();
821 DBG_ASSERT(pInst,"SVDDE:No instance data");
822 pName = new DdeString( pInst->hDdeInstSvr, r.pName->toOUString() );
823 nType = DDEITEM;
824 pMyTopic = 0;
825 pImpData = 0;
828 // --- DdeItem::~DdeItem() -----------------------------------------
830 DdeItem::~DdeItem()
832 if( pMyTopic )
833 pMyTopic->aItems.erase(std::remove(pMyTopic->aItems.begin(),
834 pMyTopic->aItems.end(),this));
835 delete pName;
836 delete pImpData;
839 // --- DdeItem::GetName() ------------------------------------------
841 const OUString DdeItem::GetName() const
843 return pName->toOUString();
846 // --- DdeItem::NotifyClient() ------------------------------------------
848 void DdeItem::NotifyClient()
850 if( pMyTopic && pImpData )
852 DdeInstData* pInst = ImpGetInstData();
853 DBG_ASSERT(pInst,"SVDDE:No instance data");
854 DdePostAdvise( pInst->hDdeInstSvr, *pMyTopic->pName, *pName );
858 // --- DdeItem::IncMonitor() ------------------------------------------
860 void DdeItem::IncMonitor( sal_uLong nHCnv )
862 if( !pImpData )
864 pImpData = new DdeItemImp;
865 if( DDEGETPUTITEM == nType )
866 ((DdeGetPutItem*)this)->AdviseLoop( sal_True );
868 else
870 for( sal_uInt16 n = pImpData->size(); n; )
871 if( (*pImpData)[ --n ].nHCnv == nHCnv )
873 ++(*pImpData)[ n ].nHCnv;
874 return ;
878 pImpData->push_back( DdeItemImpData( nHCnv ) );
881 // --- DdeItem::DecMonitor() ------------------------------------------
883 void DdeItem::DecMonitor( sal_uLong nHCnv )
885 if( pImpData )
887 for( sal_uInt16 n = 0; n < pImpData->size(); ++n )
889 DdeItemImpData* pData = &(*pImpData)[n];
890 if( pData->nHCnv == nHCnv )
892 if( !pData->nCnt || !--pData->nCnt )
894 if( 1 < pImpData->size() )
896 pImpData->erase(pImpData->begin() + n);
898 else
900 delete pImpData, pImpData = 0;
901 if( DDEGETPUTITEM == nType )
902 ((DdeGetPutItem*)this)->AdviseLoop( sal_False );
905 return ;
911 // --- DdeItem::GetLinks() ------------------------------------------
913 short DdeItem::GetLinks()
915 short nCnt = 0;
916 if( pImpData )
917 for( sal_uInt16 n = pImpData->size(); n; )
919 nCnt = nCnt + (*pImpData)[ --n ].nCnt;
921 return nCnt;
924 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
926 DdeGetPutItem::DdeGetPutItem( const sal_Unicode* p )
927 : DdeItem( p )
929 nType = DDEGETPUTITEM;
932 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
934 DdeGetPutItem::DdeGetPutItem( const String& rStr )
935 : DdeItem( rStr )
937 nType = DDEGETPUTITEM;
940 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
942 DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem )
943 : DdeItem( rItem )
945 nType = DDEGETPUTITEM;
949 // --- DdeGetPutData::Get() ----------------------------------------
951 DdeData* DdeGetPutItem::Get( sal_uLong )
953 return 0;
956 // --- DdeGetPutData::Put() ----------------------------------------
958 sal_Bool DdeGetPutItem::Put( const DdeData* )
960 return sal_False;
963 // --- DdeGetPutData::AdviseLoop() ---------------------------------
965 void DdeGetPutItem::AdviseLoop( sal_Bool )
970 // --- DdeService::SysItems() --------------------------------------
972 String DdeService::SysItems()
974 String s;
975 std::vector<DdeTopic*>::iterator iter;
976 std::vector<DdeItem*>::iterator iterItem;
977 for ( iter = aTopics.begin(); iter != aTopics.end(); ++iter )
979 if ( (*iter)->GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) )
981 short n = 0;
982 for ( iterItem = (*iter)->aItems.begin(); iterItem != (*iter)->aItems.end(); ++iterItem, n++ )
984 if ( n )
985 s += '\t';
986 s += (*iterItem)->GetName();
988 s += OUString("\r\n");
992 return s;
995 // --- DdeService::Topics() ----------------------------------------
997 String DdeService::Topics()
999 String s;
1000 std::vector<DdeTopic*>::iterator iter;
1001 short n = 0;
1003 for ( iter = aTopics.begin(); iter != aTopics.end(); ++iter, n++ )
1005 if ( n )
1006 s += '\t';
1007 s += (*iter)->GetName();
1009 s += OUString("\r\n");
1011 return s;
1014 // --- DdeService::Formats() ---------------------------------------
1016 String DdeService::Formats()
1018 String s;
1019 long f;
1020 short n = 0;
1022 for (size_t i = 0; i < aFormats.size(); ++i, ++n)
1024 f = aFormats[ i ];
1025 if ( n )
1026 s += '\t';
1028 switch( (sal_uInt16)f )
1030 case CF_TEXT:
1031 s += OUString("TEXT");
1032 break;
1033 case CF_BITMAP:
1034 s += OUString("BITMAP");
1035 break;
1036 default:
1038 TCHAR buf[128];
1039 GetClipboardFormatName( (UINT)f, buf, sizeof(buf) / sizeof(TCHAR) );
1040 s += OUString(reinterpret_cast<sal_Unicode*>(buf));
1042 break;
1046 s += OUString("\r\n");
1048 return s;
1051 // --- DdeService::Status() ----------------------------------------
1053 String DdeService::Status()
1055 return IsBusy() ? OUString("Busy\r\n") : OUString("Ready\r\n");
1058 // --- DdeService::IsBusy() ----------------------------------------
1060 sal_Bool DdeService::IsBusy()
1062 return sal_False;
1065 // --- DdeService::GetHelp() ----------------------------------------
1067 String DdeService::GetHelp()
1069 return String();
1072 sal_Bool DdeTopic::MakeItem( const OUString& )
1074 return sal_False;
1077 sal_Bool DdeService::MakeTopic( const OUString& )
1079 return sal_False;
1082 String DdeService::SysTopicGet( const String& )
1084 return String();
1087 sal_Bool DdeService::SysTopicExecute( const String* )
1089 return sal_False;
1092 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */