bump product version to 4.2.0.1
[LibreOffice.git] / svl / source / svdde / ddesvr.cxx
blobecce24a15644210ecffeab30512ad6cd524a63da
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 <rtl/ustring.hxx>
26 #include <svl/svdde.hxx>
27 #include <tools/debug.hxx>
28 #include <osl/thread.h>
29 #include <o3tl/sorted_vector.hxx>
31 enum DdeItemType
33 DDEITEM,
34 DDEGETPUTITEM
37 struct DdeItemImpData
39 sal_uLong nHCnv;
40 sal_uInt16 nCnt;
42 DdeItemImpData( sal_uLong nH ) : nHCnv( nH ), nCnt( 1 ) {}
45 class DdeItemImp : public std::vector<DdeItemImpData> {};
47 // --- DdeInternat::SvrCallback() ----------------------------------
49 HDDEDATA CALLBACK DdeInternal::SvrCallback(
50 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
51 HDDEDATA hData, DWORD, DWORD )
53 DdeServices& rAll = DdeService::GetServices();
54 DdeService* pService;
55 DdeTopic* pTopic;
56 DdeItem* pItem;
57 DdeData* pData;
58 Conversation* pC;
60 DdeInstData* pInst = ImpGetInstData();
61 DBG_ASSERT(pInst,"SVDDE:No instance data");
63 switch( nCode )
65 case XTYP_WILDCONNECT:
67 int nTopics = 0;
69 TCHAR chTopicBuf[250];
70 if( hText1 )
71 DdeQueryString( pInst->hDdeInstSvr, hText1, chTopicBuf,
72 sizeof(chTopicBuf)/sizeof(TCHAR), CP_WINUNICODE );
74 for (DdeServices::iterator aI = rAll.begin(); aI != rAll.end(); ++aI)
76 pService = *aI;
77 if ( !hText2 || ( *pService->pName == hText2 ) )
79 OUString sTopics( pService->Topics() );
80 if (!sTopics.isEmpty())
82 if( hText1 )
84 sal_Int32 n = 0;
85 while( -1 != n )
87 OUString s( sTopics.getToken( 0, '\t', n ));
88 if( s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
89 ++nTopics;
92 else
93 nTopics += comphelper::string::getTokenCount(sTopics, '\t');
98 if( !nTopics )
99 return (HDDEDATA)NULL;
101 HSZPAIR* pPairs = new HSZPAIR [nTopics + 1];
102 if ( !pPairs )
103 return (HDDEDATA)NULL;
105 HSZPAIR* q = pPairs;
106 for (DdeServices::iterator aI = rAll.begin(); aI != rAll.end(); ++aI)
108 pService = *aI;
109 if ( !hText2 || (*pService->pName == hText2 ) )
111 OUString sTopics( pService->Topics() );
112 sal_Int32 n = 0;
113 while( -1 != n )
115 OUString s( sTopics.getToken( 0, '\t', n ));
116 s = comphelper::string::remove(s, '\n');
117 s = comphelper::string::remove(s, '\r');
118 if( !hText1 || s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
120 DdeString aDStr( pInst->hDdeInstSvr, s );
121 pTopic = FindTopic( *pService, (HSZ)aDStr );
122 if( pTopic )
124 q->hszSvc = *pService->pName;
125 q->hszTopic = *pTopic->pName;
126 q++;
133 q->hszSvc = NULL;
134 q->hszTopic = NULL;
135 HDDEDATA h = DdeCreateDataHandle(
136 pInst->hDdeInstSvr, (LPBYTE) pPairs,
137 sizeof(HSZPAIR) * (nTopics+1),
138 0, NULL, nCbType, 0);
139 delete [] pPairs;
140 return h;
143 case XTYP_CONNECT:
144 pService = FindService( hText2 );
145 if ( pService)
146 pTopic = FindTopic( *pService, hText1 );
147 else
148 pTopic = NULL;
149 if ( pTopic )
150 return (HDDEDATA)DDE_FACK;
151 else
152 return (HDDEDATA) NULL;
154 case XTYP_CONNECT_CONFIRM:
155 pService = FindService( hText2 );
156 if ( pService )
158 pTopic = FindTopic( *pService, hText1 );
159 if ( pTopic )
161 pTopic->Connect( (sal_IntPtr) hConv );
162 pC = new Conversation;
163 pC->hConv = hConv;
164 pC->pTopic = pTopic;
165 pService->pConv->push_back( pC );
168 return (HDDEDATA)NULL;
171 for (DdeServices::iterator aI = rAll.begin(); aI != rAll.end(); ++aI)
173 pService = *aI;
174 for ( size_t i = 0, n = pService->pConv->size(); i < n; ++i )
176 pC = (*pService->pConv)[ i ];
177 if ( pC->hConv == hConv )
178 goto found;
182 return (HDDEDATA) DDE_FNOTPROCESSED;
184 found:
185 if ( nCode == XTYP_DISCONNECT)
187 pC->pTopic->_Disconnect( (sal_IntPtr) hConv );
188 for ( ConvList::iterator it = pService->pConv->begin();
189 it != pService->pConv->end();
190 ++it
192 if ( *it == pC )
194 delete *it;
195 pService->pConv->erase( it );
196 break;
199 return (HDDEDATA)NULL;
202 bool bExec = nCode == XTYP_EXECUTE;
203 pTopic = pC->pTopic;
204 if ( pTopic && !bExec )
205 pItem = FindItem( *pTopic, hText2 );
206 else
207 pItem = NULL;
209 if ( !bExec && !pService->HasCbFormat( nCbType ) )
210 pItem = NULL;
211 if ( !pItem && !bExec )
212 return (HDDEDATA)DDE_FNOTPROCESSED;
213 if ( pItem )
214 pTopic->aItem = pItem->GetName();
215 else
216 pTopic->aItem = OUString();
218 bool bRes = false;
219 pInst->hCurConvSvr = (sal_IntPtr)hConv;
220 switch( nCode )
222 case XTYP_REQUEST:
223 case XTYP_ADVREQ:
225 OUString aRes; // darf erst am Ende freigegeben werden!!
226 if ( pTopic->IsSystemTopic() )
228 if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) )
229 aRes = pService->Topics();
230 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) )
231 aRes = pService->SysItems();
232 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) )
233 aRes = pService->Status();
234 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) )
235 aRes = pService->Formats();
236 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) )
237 aRes = pService->GetHelp();
238 else
239 aRes = pService->SysTopicGet( pTopic->aItem );
241 if ( !aRes.isEmpty() )
242 pData = new DdeData( aRes );
243 else
244 pData = NULL;
246 else if( DDEGETPUTITEM == pItem->nType )
248 pData = ((DdeGetPutItem*)pItem)->Get( DdeData::GetInternalFormat( nCbType ) );
250 else
252 pData = pTopic->Get( DdeData::GetInternalFormat( nCbType ));
255 if ( pData )
257 return DdeCreateDataHandle( pInst->hDdeInstSvr,
258 (LPBYTE)pData->pImp->pData,
259 pData->pImp->nData,
260 0, hText2,
261 DdeData::GetExternalFormat(
262 pData->pImp->nFmt ),
263 0 );
266 break;
268 case XTYP_POKE:
269 if ( !pTopic->IsSystemTopic() )
271 DdeData d;
272 d.pImp->hData = hData;
273 d.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
274 d.Lock();
275 if( DDEGETPUTITEM == pItem->nType )
276 bRes = ((DdeGetPutItem*)pItem)->Put( &d );
277 else
278 bRes = pTopic->Put( &d );
280 pInst->hCurConvSvr = 0;
281 if ( bRes )
282 return (HDDEDATA)DDE_FACK;
283 else
284 return (HDDEDATA) DDE_FNOTPROCESSED;
286 case XTYP_ADVSTART:
288 // wird das Item zum erstenmal ein HotLink ?
289 if( !pItem->pImpData && pTopic->StartAdviseLoop() )
291 // dann wurde das Item ausgewechselt
292 std::vector<DdeItem*>::iterator it(std::find(pTopic->aItems.begin(),
293 pTopic->aItems.end(),
294 pItem));
295 if (it != pTopic->aItems.end())
296 pTopic->aItems.erase(it);
298 std::vector<DdeItem*>::iterator iter;
299 for( iter = pTopic->aItems.begin();
300 iter != pTopic->aItems.end();
301 ++iter )
303 if( *(*iter)->pName == hText2 )
305 // es wurde tatsaechlich ausgewechselt
306 delete pItem;
307 pItem = 0;
308 break;
312 if( pItem )
313 // es wurde doch nicht ausgewechselt, also wieder rein
314 pTopic->aItems.push_back(pItem);
315 else
316 pItem = iter != pTopic->aItems.end() ? *iter : NULL;
319 if (pItem)
321 pItem->IncMonitor( (sal_IntPtr)hConv );
322 pInst->hCurConvSvr = 0;
325 return (HDDEDATA)sal_True;
327 case XTYP_ADVSTOP:
328 pItem->DecMonitor( (sal_IntPtr)hConv );
329 if( !pItem->pImpData )
330 pTopic->StopAdviseLoop();
331 pInst->hCurConvSvr = 0;
332 return (HDDEDATA)sal_True;
334 case XTYP_EXECUTE:
336 DdeData aExec;
337 aExec.pImp->hData = hData;
338 aExec.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
339 aExec.Lock();
340 OUString aName;
342 aName = (const sal_Unicode *)aExec.pImp->pData;
344 if( pTopic->IsSystemTopic() )
345 bRes = pService->SysTopicExecute( &aName );
346 else
347 bRes = pTopic->Execute( &aName );
349 pInst->hCurConvSvr = 0;
350 if ( bRes )
351 return (HDDEDATA)DDE_FACK;
352 else
353 return (HDDEDATA)DDE_FNOTPROCESSED;
356 return (HDDEDATA)NULL;
359 // --- DdeInternat::FindService() ----------------------------------
361 DdeService* DdeInternal::FindService( HSZ hService )
363 DdeService* s;
364 DdeServices& rSvc = DdeService::GetServices();
365 for (DdeServices::iterator aI = rSvc.begin(); aI != rSvc.end(); ++aI)
367 s = *aI;
368 if ( *s->pName == hService )
369 return s;
372 return NULL;
375 // --- DdeInternat::FindTopic() ------------------------------------
377 DdeTopic* DdeInternal::FindTopic( DdeService& rService, HSZ hTopic )
379 std::vector<DdeTopic*>::iterator iter;
380 std::vector<DdeTopic*> &rTopics = rService.aTopics;
381 bool bContinue = false;
382 DdeInstData* pInst = ImpGetInstData();
383 DBG_ASSERT(pInst,"SVDDE:No instance data");
386 { // middle check loop
387 for ( iter = rTopics.begin(); iter != rTopics.end(); ++iter )
389 if ( *(*iter)->pName == hTopic )
390 return *iter;
393 bContinue = !bContinue;
394 if( !bContinue )
395 break;
397 // dann befragen wir doch mal unsere Ableitung:
398 TCHAR chBuf[250];
399 DdeQueryString(pInst->hDdeInstSvr,hTopic,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
400 bContinue = rService.MakeTopic( reinterpret_cast<const sal_Unicode*>(chBuf) );
401 // dann muessen wir noch mal suchen
403 while( bContinue );
405 return 0;
408 // --- DdeInternal::FindItem() -------------------------------------
410 DdeItem* DdeInternal::FindItem( DdeTopic& rTopic, HSZ hItem )
412 std::vector<DdeItem*>::iterator iter;
413 std::vector<DdeItem*> &rItems = rTopic.aItems;
414 DdeInstData* pInst = ImpGetInstData();
415 DBG_ASSERT(pInst,"SVDDE:No instance data");
416 bool bContinue = false;
419 { // middle check loop
421 for ( iter = rItems.begin(); iter != rItems.end(); ++iter )
423 if ( *(*iter)->pName == hItem )
424 return *iter;
426 bContinue = !bContinue;
427 if( !bContinue )
428 break;
430 // dann befragen wir doch mal unsere Ableitung:
431 TCHAR chBuf[250];
432 DdeQueryString(pInst->hDdeInstSvr,hItem,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
433 bContinue = rTopic.MakeItem( reinterpret_cast<const sal_Unicode*>(chBuf) );
434 // dann muessen wir noch mal suchen
436 while( bContinue );
438 return 0;
441 // --- DdeService::DdeService() ------------------------------------
443 DdeService::DdeService( const OUString& rService )
445 DdeInstData* pInst = ImpGetInstData();
446 if( !pInst )
447 pInst = ImpInitInstData();
448 pInst->nRefCount++;
449 pInst->nInstanceSvr++;
451 if ( !pInst->hDdeInstSvr )
453 nStatus = sal::static_int_cast< short >(
454 DdeInitialize( &pInst->hDdeInstSvr,
455 (PFNCALLBACK)DdeInternal::SvrCallback,
456 APPCLASS_STANDARD |
457 CBF_SKIP_REGISTRATIONS |
458 CBF_SKIP_UNREGISTRATIONS, 0L ) );
459 pInst->pServicesSvr = new DdeServices;
461 else
462 nStatus = DMLERR_NO_ERROR;
464 pConv = new ConvList;
466 if ( pInst->pServicesSvr )
467 pInst->pServicesSvr->push_back( this );
469 pName = new DdeString( pInst->hDdeInstSvr, rService );
470 if ( nStatus == DMLERR_NO_ERROR )
472 if ( !DdeNameService( pInst->hDdeInstSvr, *pName, NULL,
473 DNS_REGISTER | DNS_FILTEROFF ) )
475 nStatus = DMLERR_SYS_ERROR;
478 AddFormat( FORMAT_STRING );
479 pSysTopic = new DdeTopic( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) );
480 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) );
481 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) );
482 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) );
483 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) );
484 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) );
485 AddTopic( *pSysTopic );
488 // --- DdeService::~DdeService() -----------------------------------
490 DdeService::~DdeService()
492 DdeInstData* pInst = ImpGetInstData();
493 DBG_ASSERT(pInst,"SVDDE:No instance data");
494 if ( pInst->pServicesSvr )
495 pInst->pServicesSvr->erase(std::remove(pInst->pServicesSvr->begin(), pInst->pServicesSvr->end(), this), pInst->pServicesSvr->end());
497 // MT: Im Auftrage des Herrn (AM) auskommentiert...
498 // Grund:
499 // Bei Client/Server werden die Server nicht beendet, wenn mehr
500 // als einer gestartet.
501 // Weil keine System-Messagequeue ?!
503 delete pSysTopic;
504 delete pName;
506 pInst->nInstanceSvr--;
507 pInst->nRefCount--;
508 if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr )
510 if( DdeUninitialize( pInst->hDdeInstSvr ) )
512 pInst->hDdeInstSvr = 0;
513 delete pInst->pServicesSvr;
514 pInst->pServicesSvr = NULL;
515 if( pInst->nRefCount == 0)
516 ImpDeinitInstData();
519 delete pConv;
522 // --- DdeService::GetName() ---------------------------------------
524 const OUString DdeService::GetName() const
526 return pName->toOUString();
529 // --- DdeService::GetServices() -----------------------------------
531 DdeServices& DdeService::GetServices()
533 DdeInstData* pInst = ImpGetInstData();
534 DBG_ASSERT(pInst,"SVDDE:No instance data");
535 return *(pInst->pServicesSvr);
538 // --- DdeService::AddTopic() --------------------------------------
540 void DdeService::AddTopic( const DdeTopic& rTopic )
542 RemoveTopic( rTopic );
543 aTopics.push_back((DdeTopic *) &rTopic);
546 // --- DdeService::RemoveTopic() -----------------------------------
548 void DdeService::RemoveTopic( const DdeTopic& rTopic )
550 std::vector<DdeTopic*>::iterator iter;
551 for ( iter = aTopics.begin(); iter != aTopics.end(); ++iter )
553 if ( !DdeCmpStringHandles (*(*iter)->pName, *rTopic.pName ) )
555 aTopics.erase(iter);
556 // JP 27.07.95: und alle Conversions loeschen !!!
557 // (sonst wird auf geloeschten Topics gearbeitet!!)
558 for( size_t n = pConv->size(); n; )
560 Conversation* pC = (*pConv)[ --n ];
561 if( pC->pTopic == &rTopic )
563 ConvList::iterator it = pConv->begin();
564 ::std::advance( it, n );
565 delete *it;
566 pConv->erase( it );
569 break;
574 // --- DdeService::HasCbFormat() -----------------------------------
576 bool DdeService::HasCbFormat( sal_uInt16 nFmt )
578 for ( size_t i = 0, n = aFormats.size(); i < n; ++i )
579 if ( aFormats[ i ] == nFmt )
580 return true;
581 return false;
584 // --- DdeService::HasFormat() -------------------------------------
586 bool DdeService::HasFormat( sal_uLong nFmt )
588 return HasCbFormat( (sal_uInt16)DdeData::GetExternalFormat( nFmt ));
591 // --- DdeService::AddFormat() -------------------------------------
593 void DdeService::AddFormat( sal_uLong nFmt )
595 nFmt = DdeData::GetExternalFormat( nFmt );
596 for ( size_t i = 0, n = aFormats.size(); i < n; ++i )
597 if ( (sal_uLong) aFormats[ i ] == nFmt )
598 return;
599 aFormats.push_back( nFmt );
602 // --- DdeService::RemoveFormat() ----------------------------------
604 void DdeService::RemoveFormat( sal_uLong nFmt )
606 nFmt = DdeData::GetExternalFormat( nFmt );
607 for ( DdeFormats::iterator it = aFormats.begin(); it != aFormats.end(); ++it )
609 if ( (sal_uLong) *it == nFmt )
611 aFormats.erase( it );
612 break;
617 // --- DdeTopic::DdeTopic() ----------------------------------------
619 DdeTopic::DdeTopic( const OUString& rName )
621 DdeInstData* pInst = ImpGetInstData();
622 DBG_ASSERT(pInst,"SVDDE:No instance data");
623 pName = new DdeString( pInst->hDdeInstSvr, rName );
626 // --- DdeTopic::~DdeTopic() ---------------------------------------
628 DdeTopic::~DdeTopic()
630 std::vector<DdeItem*>::iterator iter;
631 for (iter = aItems.begin(); iter != aItems.end(); ++iter)
633 (*iter)->pMyTopic = 0;
634 delete *iter;
637 delete pName;
640 // --- DdeTopic::GetName() -----------------------------------------
642 const OUString DdeTopic::GetName() const
644 return pName->toOUString();
647 // --- DdeTopic::IsSystemTopic() -----------------------------------
649 bool DdeTopic::IsSystemTopic()
651 return GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC);
654 // --- DdeTopic::AddItem() -----------------------------------------
656 DdeItem* DdeTopic::AddItem( const DdeItem& r )
658 DdeItem* s;
659 if( DDEGETPUTITEM == r.nType )
660 s = new DdeGetPutItem( r );
661 else
662 s = new DdeItem( r );
664 if ( s )
666 aItems.push_back( s );
667 s->pMyTopic = this;
669 return s;
672 // --- DdeTopic::InsertItem() -----------------------------------------
674 void DdeTopic::InsertItem( DdeItem* pNew )
676 if( pNew )
678 aItems.push_back( pNew );
679 pNew->pMyTopic = this;
683 // --- DdeTopic::RemoveItem() --------------------------------------
685 void DdeTopic::RemoveItem( const DdeItem& r )
687 std::vector<DdeItem*>::iterator iter;
688 for (iter = aItems.begin(); iter != aItems.end(); ++iter)
690 if ( !DdeCmpStringHandles (*(*iter)->pName, *r.pName ) )
691 break;
694 if ( iter != aItems.end() )
696 (*iter)->pMyTopic = 0;
697 delete *iter;
698 aItems.erase(iter);
702 // --- DdeTopic::NotifyClient() ------------------------------------
704 void DdeTopic::NotifyClient( const OUString& rItem )
706 std::vector<DdeItem*>::iterator iter;
707 DdeInstData* pInst = ImpGetInstData();
708 DBG_ASSERT(pInst,"SVDDE:No instance data");
709 for ( iter = aItems.begin(); iter != aItems.end(); ++iter)
711 if ( (*iter)->GetName().equals(rItem) && (*iter)->pImpData)
713 DdePostAdvise( pInst->hDdeInstSvr, *pName, *(*iter)->pName );
714 break;
719 // --- DdeTopic::Connect() -----------------------------------------
721 void DdeTopic::Connect( sal_IntPtr nId )
723 aConnectLink.Call( (void*)nId );
726 // --- DdeTopic::Disconnect() --------------------------------------
728 void DdeTopic::Disconnect( sal_IntPtr nId )
730 aDisconnectLink.Call( (void*)nId );
733 // --- DdeTopic::_Disconnect() --------------------------------------
735 void DdeTopic::_Disconnect( sal_IntPtr nId )
737 std::vector<DdeItem*>::iterator iter;
738 for (iter = aItems.begin(); iter != aItems.end(); ++iter)
739 (*iter)->DecMonitor( nId );
741 Disconnect( nId );
744 // --- DdeTopic::Get() ---------------------------------------------
746 DdeData* DdeTopic::Get( sal_uIntPtr nFmt )
748 if ( aGetLink.IsSet() )
749 return (DdeData*)aGetLink.Call( (void*)nFmt );
750 else
751 return NULL;
754 // --- DdeTopic::Put() ---------------------------------------------
756 bool DdeTopic::Put( const DdeData* r )
758 if ( aPutLink.IsSet() )
759 return aPutLink.Call( (void*) r );
760 else
761 return false;
764 // --- DdeTopic::Execute() -----------------------------------------
766 bool DdeTopic::Execute( const OUString* r )
768 if ( aExecLink.IsSet() )
769 return aExecLink.Call( (void*)r );
770 else
771 return false;
774 // --- DdeTopic::GetConvId() ---------------------------------------
776 long DdeTopic::GetConvId()
778 DdeInstData* pInst = ImpGetInstData();
779 DBG_ASSERT(pInst,"SVDDE:No instance data");
780 return pInst->hCurConvSvr;
783 // --- DdeTopic::StartAdviseLoop() ---------------------------------
785 bool DdeTopic::StartAdviseLoop()
787 return false;
790 // --- DdeTopic::StopAdviseLoop() ----------------------------------
792 bool DdeTopic::StopAdviseLoop()
794 return false;
797 // --- DdeItem::DdeItem() ------------------------------------------
799 DdeItem::DdeItem( const sal_Unicode* p )
801 DdeInstData* pInst = ImpGetInstData();
802 DBG_ASSERT(pInst,"SVDDE:No instance data");
803 pName = new DdeString( pInst->hDdeInstSvr, p );
804 nType = DDEITEM;
805 pMyTopic = 0;
806 pImpData = 0;
809 // --- DdeItem::DdeItem() ------------------------------------------
811 DdeItem::DdeItem( const OUString& r)
813 DdeInstData* pInst = ImpGetInstData();
814 DBG_ASSERT(pInst,"SVDDE:No instance data");
815 pName = new DdeString( pInst->hDdeInstSvr, r );
816 nType = DDEITEM;
817 pMyTopic = 0;
818 pImpData = 0;
821 // --- DdeItem::DdeItem() ------------------------------------------
823 DdeItem::DdeItem( const DdeItem& r)
825 DdeInstData* pInst = ImpGetInstData();
826 DBG_ASSERT(pInst,"SVDDE:No instance data");
827 pName = new DdeString( pInst->hDdeInstSvr, r.pName->toOUString() );
828 nType = DDEITEM;
829 pMyTopic = 0;
830 pImpData = 0;
833 // --- DdeItem::~DdeItem() -----------------------------------------
835 DdeItem::~DdeItem()
837 if( pMyTopic )
838 pMyTopic->aItems.erase(std::remove(pMyTopic->aItems.begin(),
839 pMyTopic->aItems.end(),this));
840 delete pName;
841 delete pImpData;
844 // --- DdeItem::GetName() ------------------------------------------
846 const OUString DdeItem::GetName() const
848 return pName->toOUString();
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( sal_uLong nHCnv )
867 if( !pImpData )
869 pImpData = new DdeItemImp;
870 if( DDEGETPUTITEM == nType )
871 ((DdeGetPutItem*)this)->AdviseLoop( true );
873 else
875 for( sal_uInt16 n = pImpData->size(); n; )
876 if( (*pImpData)[ --n ].nHCnv == nHCnv )
878 ++(*pImpData)[ n ].nHCnv;
879 return ;
883 pImpData->push_back( DdeItemImpData( nHCnv ) );
886 // --- DdeItem::DecMonitor() ------------------------------------------
888 void DdeItem::DecMonitor( sal_uLong nHCnv )
890 if( pImpData )
892 for( sal_uInt16 n = 0; n < pImpData->size(); ++n )
894 DdeItemImpData* pData = &(*pImpData)[n];
895 if( pData->nHCnv == nHCnv )
897 if( !pData->nCnt || !--pData->nCnt )
899 if( 1 < pImpData->size() )
901 pImpData->erase(pImpData->begin() + n);
903 else
905 delete pImpData, pImpData = 0;
906 if( DDEGETPUTITEM == nType )
907 ((DdeGetPutItem*)this)->AdviseLoop( false );
910 return ;
916 // --- DdeItem::GetLinks() ------------------------------------------
918 short DdeItem::GetLinks()
920 short nCnt = 0;
921 if( pImpData )
923 for( sal_uInt16 n = pImpData->size(); n; )
925 nCnt = nCnt + (*pImpData)[ --n ].nCnt;
928 return nCnt;
931 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
933 DdeGetPutItem::DdeGetPutItem( const sal_Unicode* p )
934 : DdeItem( p )
936 nType = DDEGETPUTITEM;
939 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
941 DdeGetPutItem::DdeGetPutItem( const OUString& rStr )
942 : DdeItem( rStr )
944 nType = DDEGETPUTITEM;
947 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
949 DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem )
950 : DdeItem( rItem )
952 nType = DDEGETPUTITEM;
956 // --- DdeGetPutData::Get() ----------------------------------------
958 DdeData* DdeGetPutItem::Get( sal_uLong )
960 return 0;
963 // --- DdeGetPutData::Put() ----------------------------------------
965 bool DdeGetPutItem::Put( const DdeData* )
967 return false;
970 // --- DdeGetPutData::AdviseLoop() ---------------------------------
972 void DdeGetPutItem::AdviseLoop( bool )
977 // --- DdeService::SysItems() --------------------------------------
979 OUString DdeService::SysItems()
981 OUString s;
982 std::vector<DdeTopic*>::iterator iter;
983 std::vector<DdeItem*>::iterator iterItem;
984 for ( iter = aTopics.begin(); iter != aTopics.end(); ++iter )
986 if ( (*iter)->GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) )
988 short n = 0;
989 for ( iterItem = (*iter)->aItems.begin(); iterItem != (*iter)->aItems.end(); ++iterItem, n++ )
991 if ( n )
992 s += "\t";
993 s += (*iterItem)->GetName();
995 s += "\r\n";
999 return s;
1002 // --- DdeService::Topics() ----------------------------------------
1004 OUString DdeService::Topics()
1006 OUString s;
1007 std::vector<DdeTopic*>::iterator iter;
1008 short n = 0;
1010 for ( iter = aTopics.begin(); iter != aTopics.end(); ++iter, n++ )
1012 if ( n )
1013 s += "\t";
1014 s += (*iter)->GetName();
1016 s += "\r\n";
1018 return s;
1021 // --- DdeService::Formats() ---------------------------------------
1023 OUString DdeService::Formats()
1025 OUString s;
1026 long f;
1027 short n = 0;
1029 for (size_t i = 0; i < aFormats.size(); ++i, ++n)
1031 f = aFormats[ i ];
1032 if ( n )
1033 s += "\t";
1035 switch( (sal_uInt16)f )
1037 case CF_TEXT:
1038 s += "TEXT";
1039 break;
1040 case CF_BITMAP:
1041 s += "BITMAP";
1042 break;
1043 default:
1045 TCHAR buf[128];
1046 GetClipboardFormatName( (UINT)f, buf, sizeof(buf) / sizeof(TCHAR) );
1047 s += OUString(reinterpret_cast<sal_Unicode*>(buf));
1049 break;
1053 s += "\r\n";
1055 return s;
1058 // --- DdeService::Status() ----------------------------------------
1060 OUString DdeService::Status()
1062 return IsBusy() ? OUString("Busy\r\n") : OUString("Ready\r\n");
1065 // --- DdeService::IsBusy() ----------------------------------------
1067 bool DdeService::IsBusy()
1069 return false;
1072 // --- DdeService::GetHelp() ----------------------------------------
1074 OUString DdeService::GetHelp()
1076 return OUString();
1079 bool DdeTopic::MakeItem( const OUString& )
1081 return false;
1084 bool DdeService::MakeTopic( const OUString& )
1086 return false;
1089 OUString DdeService::SysTopicGet( const OUString& )
1091 return OUString();
1094 bool DdeService::SysTopicExecute( const OUString* )
1096 return false;
1099 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */