1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
42 DdeItemImpData( sal_uLong nH
) : nHCnv( nH
), nCnt( 1 ) {}
47 DdeItemImp() : mvData() {}
49 size_t size() const { return mvData
.size(); }
51 std::vector
<DdeItemImpData
>::iterator
begin() { return mvData
.begin(); }
53 void erase(std::vector
<DdeItemImpData
>::iterator it
) { mvData
.erase(it
); }
55 void push_back(const DdeItemImpData
& rData
) { mvData
.push_back(rData
); }
57 DdeItemImpData
& operator[](size_t i
) { return mvData
[i
]; }
60 std::vector
<DdeItemImpData
> mvData
;
63 HDDEDATA CALLBACK
DdeInternal::SvrCallback(
64 WORD nCode
, WORD nCbType
, HCONV hConv
, HSZ hText1
, HSZ hText2
,
65 HDDEDATA hData
, DWORD
, DWORD
)
67 DdeServices
& rAll
= DdeService::GetServices();
74 DdeInstData
* pInst
= ImpGetInstData();
75 DBG_ASSERT(pInst
,"SVDDE:No instance data");
79 case XTYP_WILDCONNECT
:
83 TCHAR chTopicBuf
[250];
85 DdeQueryString( pInst
->hDdeInstSvr
, hText1
, chTopicBuf
,
86 sizeof(chTopicBuf
)/sizeof(TCHAR
), CP_WINUNICODE
);
88 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
91 if ( !hText2
|| ( *pService
->pName
== hText2
) )
93 OUString
sTopics( pService
->Topics() );
94 if (!sTopics
.isEmpty())
101 OUString
s( sTopics
.getToken( 0, '\t', n
));
102 if( s
== reinterpret_cast<const sal_Unicode
*>(chTopicBuf
) )
107 nTopics
+= comphelper::string::getTokenCount(sTopics
, '\t');
113 return (HDDEDATA
)NULL
;
115 HSZPAIR
* pPairs
= new HSZPAIR
[nTopics
+ 1];
118 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
121 if ( !hText2
|| (*pService
->pName
== hText2
) )
123 OUString
sTopics( pService
->Topics() );
127 OUString
s( sTopics
.getToken( 0, '\t', n
));
128 s
= comphelper::string::remove(s
, '\n');
129 s
= comphelper::string::remove(s
, '\r');
130 if( !hText1
|| s
== reinterpret_cast<const sal_Unicode
*>(chTopicBuf
) )
132 DdeString
aDStr( pInst
->hDdeInstSvr
, s
);
133 pTopic
= FindTopic( *pService
, (HSZ
)aDStr
);
136 q
->hszSvc
= *pService
->pName
;
137 q
->hszTopic
= *pTopic
->pName
;
147 HDDEDATA h
= DdeCreateDataHandle(
148 pInst
->hDdeInstSvr
, (LPBYTE
) pPairs
,
149 sizeof(HSZPAIR
) * (nTopics
+1),
150 0, NULL
, nCbType
, 0);
156 pService
= FindService( hText2
);
158 pTopic
= FindTopic( *pService
, hText1
);
162 return (HDDEDATA
)DDE_FACK
;
164 return (HDDEDATA
) NULL
;
166 case XTYP_CONNECT_CONFIRM
:
167 pService
= FindService( hText2
);
170 pTopic
= FindTopic( *pService
, hText1
);
173 pTopic
->Connect( (sal_IntPtr
) hConv
);
174 pC
= new Conversation
;
177 pService
->pConv
->push_back( pC
);
180 return (HDDEDATA
)NULL
;
183 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
186 for ( size_t i
= 0, n
= pService
->pConv
->size(); i
< n
; ++i
)
188 pC
= (*pService
->pConv
)[ i
];
189 if ( pC
->hConv
== hConv
)
194 return (HDDEDATA
) DDE_FNOTPROCESSED
;
197 if ( nCode
== XTYP_DISCONNECT
)
199 pC
->pTopic
->_Disconnect( (sal_IntPtr
) hConv
);
200 for ( ConvList::iterator it
= pService
->pConv
->begin();
201 it
!= pService
->pConv
->end();
207 pService
->pConv
->erase( it
);
211 return (HDDEDATA
)NULL
;
214 bool bExec
= nCode
== XTYP_EXECUTE
;
216 if ( pTopic
&& !bExec
)
217 pItem
= FindItem( *pTopic
, hText2
);
221 if ( !bExec
&& !pService
->HasCbFormat( nCbType
) )
223 if ( !pItem
&& !bExec
)
224 return (HDDEDATA
)DDE_FNOTPROCESSED
;
226 pTopic
->aItem
= pItem
->GetName();
228 (pTopic
->aItem
).clear();
231 pInst
->hCurConvSvr
= (sal_IntPtr
)hConv
;
237 OUString aRes
; // Must be free not until the end!
238 if ( pTopic
->IsSystemTopic() )
240 if ( pTopic
->aItem
== reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_TOPICS
) )
241 aRes
= pService
->Topics();
242 else if ( pTopic
->aItem
== reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_SYSITEMS
) )
243 aRes
= pService
->SysItems();
244 else if ( pTopic
->aItem
== reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_STATUS
) )
245 aRes
= pService
->Status();
246 else if ( pTopic
->aItem
== reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_FORMATS
) )
247 aRes
= pService
->Formats();
248 else if ( pTopic
->aItem
== reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_HELP
) )
249 aRes
= pService
->GetHelp();
251 aRes
= pService
->SysTopicGet( pTopic
->aItem
);
253 if ( !aRes
.isEmpty() )
254 pData
= new DdeData( aRes
);
258 else if( DDEGETPUTITEM
== pItem
->nType
)
260 pData
= ((DdeGetPutItem
*)pItem
)->Get( DdeData::GetInternalFormat( nCbType
) );
264 pData
= pTopic
->Get( DdeData::GetInternalFormat( nCbType
));
269 return DdeCreateDataHandle( pInst
->hDdeInstSvr
,
270 (LPBYTE
)pData
->pImp
->pData
,
273 DdeData::GetExternalFormat(
281 if ( !pTopic
->IsSystemTopic() )
284 d
.pImp
->hData
= hData
;
285 d
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
287 if( DDEGETPUTITEM
== pItem
->nType
)
288 bRes
= ((DdeGetPutItem
*)pItem
)->Put( &d
);
290 bRes
= pTopic
->Put( &d
);
292 pInst
->hCurConvSvr
= 0;
294 return (HDDEDATA
)DDE_FACK
;
296 return (HDDEDATA
) DDE_FNOTPROCESSED
;
300 // Is the Item turning into a HotLink for the first time?
301 if( !pItem
->pImpData
&& pTopic
->StartAdviseLoop() )
303 // Then the Item has been exchanged
304 std::vector
<DdeItem
*>::iterator
it(std::find(pTopic
->aItems
.begin(),
305 pTopic
->aItems
.end(),
307 if (it
!= pTopic
->aItems
.end())
308 pTopic
->aItems
.erase(it
);
310 std::vector
<DdeItem
*>::iterator iter
;
311 for( iter
= pTopic
->aItems
.begin();
312 iter
!= pTopic
->aItems
.end();
315 if( *(*iter
)->pName
== hText2
)
317 // It was exchanged indeed
325 // It was not exchange, so back in
326 pTopic
->aItems
.push_back(pItem
);
328 pItem
= iter
!= pTopic
->aItems
.end() ? *iter
: NULL
;
333 pItem
->IncMonitor( (sal_IntPtr
)hConv
);
334 pInst
->hCurConvSvr
= 0;
337 return (HDDEDATA
)sal_True
;
340 pItem
->DecMonitor( (sal_IntPtr
)hConv
);
341 if( !pItem
->pImpData
)
342 pTopic
->StopAdviseLoop();
343 pInst
->hCurConvSvr
= 0;
344 return (HDDEDATA
)sal_True
;
349 aExec
.pImp
->hData
= hData
;
350 aExec
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
354 aName
= (const sal_Unicode
*)aExec
.pImp
->pData
;
356 if( pTopic
->IsSystemTopic() )
357 bRes
= pService
->SysTopicExecute( &aName
);
359 bRes
= pTopic
->Execute( &aName
);
361 pInst
->hCurConvSvr
= 0;
363 return (HDDEDATA
)DDE_FACK
;
365 return (HDDEDATA
)DDE_FNOTPROCESSED
;
368 return (HDDEDATA
)NULL
;
371 DdeService
* DdeInternal::FindService( HSZ hService
)
373 DdeServices
& rSvc
= DdeService::GetServices();
374 for (DdeServices::iterator aI
= rSvc
.begin(); aI
!= rSvc
.end(); ++aI
)
377 if ( *s
->pName
== hService
)
384 DdeTopic
* DdeInternal::FindTopic( DdeService
& rService
, HSZ hTopic
)
386 std::vector
<DdeTopic
*>::iterator iter
;
387 std::vector
<DdeTopic
*> &rTopics
= rService
.aTopics
;
388 bool bContinue
= false;
389 DdeInstData
* pInst
= ImpGetInstData();
390 DBG_ASSERT(pInst
,"SVDDE:No instance data");
393 { // middle check loop
394 for ( iter
= rTopics
.begin(); iter
!= rTopics
.end(); ++iter
)
396 if ( *(*iter
)->pName
== hTopic
)
400 bContinue
= !bContinue
;
404 // Let's query our subclass
406 DdeQueryString(pInst
->hDdeInstSvr
,hTopic
,chBuf
,sizeof(chBuf
)/sizeof(TCHAR
),CP_WINUNICODE
);
407 bContinue
= rService
.MakeTopic( reinterpret_cast<const sal_Unicode
*>(chBuf
) );
408 // We need to search again
415 DdeItem
* DdeInternal::FindItem( DdeTopic
& rTopic
, HSZ hItem
)
417 std::vector
<DdeItem
*>::iterator iter
;
418 std::vector
<DdeItem
*> &rItems
= rTopic
.aItems
;
419 DdeInstData
* pInst
= ImpGetInstData();
420 DBG_ASSERT(pInst
,"SVDDE:No instance data");
421 bool bContinue
= false;
424 { // middle check loop
425 for ( iter
= rItems
.begin(); iter
!= rItems
.end(); ++iter
)
427 if ( *(*iter
)->pName
== hItem
)
430 bContinue
= !bContinue
;
434 // Let's query our subclass
436 DdeQueryString(pInst
->hDdeInstSvr
,hItem
,chBuf
,sizeof(chBuf
)/sizeof(TCHAR
),CP_WINUNICODE
);
437 bContinue
= rTopic
.MakeItem( reinterpret_cast<const sal_Unicode
*>(chBuf
) );
438 // We need to search again
445 DdeService::DdeService( const OUString
& rService
)
447 DdeInstData
* pInst
= ImpGetInstData();
449 pInst
= ImpInitInstData();
451 pInst
->nInstanceSvr
++;
453 if ( !pInst
->hDdeInstSvr
)
455 nStatus
= sal::static_int_cast
< short >(
456 DdeInitialize( &pInst
->hDdeInstSvr
,
457 (PFNCALLBACK
)DdeInternal::SvrCallback
,
459 CBF_SKIP_REGISTRATIONS
|
460 CBF_SKIP_UNREGISTRATIONS
, 0L ) );
461 pInst
->pServicesSvr
= new DdeServices
;
464 nStatus
= DMLERR_NO_ERROR
;
466 pConv
= new ConvList
;
468 if ( pInst
->pServicesSvr
)
469 pInst
->pServicesSvr
->push_back( this );
471 pName
= new DdeString( pInst
->hDdeInstSvr
, rService
);
472 if ( nStatus
== DMLERR_NO_ERROR
)
474 if ( !DdeNameService( pInst
->hDdeInstSvr
, *pName
, NULL
,
475 DNS_REGISTER
| DNS_FILTEROFF
) )
477 nStatus
= DMLERR_SYS_ERROR
;
480 AddFormat( SotClipboardFormatId::STRING
);
481 pSysTopic
= new DdeTopic( reinterpret_cast<const sal_Unicode
*>(SZDDESYS_TOPIC
) );
482 pSysTopic
->AddItem( DdeItem( reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_TOPICS
) ) );
483 pSysTopic
->AddItem( DdeItem( reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_SYSITEMS
) ) );
484 pSysTopic
->AddItem( DdeItem( reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_STATUS
) ) );
485 pSysTopic
->AddItem( DdeItem( reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_FORMATS
) ) );
486 pSysTopic
->AddItem( DdeItem( reinterpret_cast<const sal_Unicode
*>(SZDDESYS_ITEM_HELP
) ) );
487 AddTopic( *pSysTopic
);
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());
500 pInst
->nInstanceSvr
--;
502 if ( !pInst
->nInstanceSvr
&& pInst
->hDdeInstSvr
)
504 if( DdeUninitialize( pInst
->hDdeInstSvr
) )
506 pInst
->hDdeInstSvr
= 0;
507 delete pInst
->pServicesSvr
;
508 pInst
->pServicesSvr
= NULL
;
509 if( pInst
->nRefCount
== 0)
516 const OUString
DdeService::GetName() const
518 return pName
->toOUString();
521 DdeServices
& DdeService::GetServices()
523 DdeInstData
* pInst
= ImpGetInstData();
524 DBG_ASSERT(pInst
,"SVDDE:No instance data");
525 return *(pInst
->pServicesSvr
);
528 void DdeService::AddTopic( const DdeTopic
& rTopic
)
530 RemoveTopic( rTopic
);
531 aTopics
.push_back((DdeTopic
*) &rTopic
);
534 void DdeService::RemoveTopic( const DdeTopic
& rTopic
)
536 std::vector
<DdeTopic
*>::iterator iter
;
537 for ( iter
= aTopics
.begin(); iter
!= aTopics
.end(); ++iter
)
539 if ( !DdeCmpStringHandles (*(*iter
)->pName
, *rTopic
.pName
) )
542 // Delete all conversions!
543 // Or else we work on deleted topics!
544 for( size_t n
= pConv
->size(); n
; )
546 Conversation
* pC
= (*pConv
)[ --n
];
547 if( pC
->pTopic
== &rTopic
)
549 ConvList::iterator it
= pConv
->begin();
550 ::std::advance( it
, n
);
560 bool DdeService::HasCbFormat( sal_uInt16 nFmt
)
562 for ( size_t i
= 0, n
= aFormats
.size(); i
< n
; ++i
)
563 if ( aFormats
[ i
] == nFmt
)
568 bool DdeService::HasFormat(SotClipboardFormatId nFmt
)
570 return HasCbFormat( (sal_uInt16
)DdeData::GetExternalFormat( nFmt
));
573 void DdeService::AddFormat(SotClipboardFormatId nFmt
)
575 sal_uLong nExternalFmt
= DdeData::GetExternalFormat( nFmt
);
576 for ( size_t i
= 0, n
= aFormats
.size(); i
< n
; ++i
)
577 if ( (sal_uLong
) aFormats
[ i
] == nExternalFmt
)
579 aFormats
.push_back( nExternalFmt
);
582 void DdeService::RemoveFormat(SotClipboardFormatId nFmt
)
584 sal_uLong nExternalFmt
= DdeData::GetExternalFormat( nFmt
);
585 for ( DdeFormats::iterator it
= aFormats
.begin(); it
!= aFormats
.end(); ++it
)
587 if ( (sal_uLong
) *it
== nExternalFmt
)
589 aFormats
.erase( it
);
595 DdeTopic::DdeTopic( const OUString
& rName
)
597 DdeInstData
* pInst
= ImpGetInstData();
598 DBG_ASSERT(pInst
,"SVDDE:No instance data");
599 pName
= new DdeString( pInst
->hDdeInstSvr
, rName
);
602 DdeTopic::~DdeTopic()
604 std::vector
<DdeItem
*>::iterator iter
;
605 for (iter
= aItems
.begin(); iter
!= aItems
.end(); ++iter
)
607 (*iter
)->pMyTopic
= 0;
614 const OUString
DdeTopic::GetName() const
616 return pName
->toOUString();
619 bool DdeTopic::IsSystemTopic()
621 return GetName() == reinterpret_cast<const sal_Unicode
*>(SZDDESYS_TOPIC
);
624 DdeItem
* DdeTopic::AddItem( const DdeItem
& r
)
627 if( DDEGETPUTITEM
== r
.nType
)
628 s
= new DdeGetPutItem( r
);
630 s
= new DdeItem( r
);
634 aItems
.push_back( s
);
640 void DdeTopic::InsertItem( DdeItem
* pNew
)
644 aItems
.push_back( pNew
);
645 pNew
->pMyTopic
= this;
649 void DdeTopic::RemoveItem( const DdeItem
& r
)
651 std::vector
<DdeItem
*>::iterator iter
;
652 for (iter
= aItems
.begin(); iter
!= aItems
.end(); ++iter
)
654 if ( !DdeCmpStringHandles (*(*iter
)->pName
, *r
.pName
) )
658 if ( iter
!= aItems
.end() )
660 (*iter
)->pMyTopic
= 0;
666 void DdeTopic::NotifyClient( const OUString
& rItem
)
668 std::vector
<DdeItem
*>::iterator iter
;
669 DdeInstData
* pInst
= ImpGetInstData();
670 DBG_ASSERT(pInst
,"SVDDE:No instance data");
671 for ( iter
= aItems
.begin(); iter
!= aItems
.end(); ++iter
)
673 if ( (*iter
)->GetName().equals(rItem
) && (*iter
)->pImpData
)
675 DdePostAdvise( pInst
->hDdeInstSvr
, *pName
, *(*iter
)->pName
);
681 void DdeTopic::Connect( sal_IntPtr nId
)
683 aConnectLink
.Call( (void*)nId
);
686 void DdeTopic::Disconnect( sal_IntPtr nId
)
688 aDisconnectLink
.Call( (void*)nId
);
691 void DdeTopic::_Disconnect( sal_IntPtr nId
)
693 std::vector
<DdeItem
*>::iterator iter
;
694 for (iter
= aItems
.begin(); iter
!= aItems
.end(); ++iter
)
695 (*iter
)->DecMonitor( nId
);
700 DdeData
* DdeTopic::Get(SotClipboardFormatId nFmt
)
702 if ( aGetLink
.IsSet() )
703 return (DdeData
*)aGetLink
.Call( (void*)nFmt
);
708 bool DdeTopic::Put( const DdeData
* r
)
710 if ( aPutLink
.IsSet() )
711 return aPutLink
.Call( (void*) r
);
716 bool DdeTopic::Execute( const OUString
* r
)
718 if ( aExecLink
.IsSet() )
719 return aExecLink
.Call( (void*)r
);
724 long DdeTopic::GetConvId()
726 DdeInstData
* pInst
= ImpGetInstData();
727 DBG_ASSERT(pInst
,"SVDDE:No instance data");
728 return pInst
->hCurConvSvr
;
731 bool DdeTopic::StartAdviseLoop()
736 bool DdeTopic::StopAdviseLoop()
741 DdeItem::DdeItem( const sal_Unicode
* p
)
743 DdeInstData
* pInst
= ImpGetInstData();
744 DBG_ASSERT(pInst
,"SVDDE:No instance data");
745 pName
= new DdeString( pInst
->hDdeInstSvr
, p
);
751 DdeItem::DdeItem( const OUString
& r
)
753 DdeInstData
* pInst
= ImpGetInstData();
754 DBG_ASSERT(pInst
,"SVDDE:No instance data");
755 pName
= new DdeString( pInst
->hDdeInstSvr
, r
);
761 DdeItem::DdeItem( const DdeItem
& r
)
763 DdeInstData
* pInst
= ImpGetInstData();
764 DBG_ASSERT(pInst
,"SVDDE:No instance data");
765 pName
= new DdeString( pInst
->hDdeInstSvr
, r
.pName
->toOUString() );
774 pMyTopic
->aItems
.erase(std::remove(pMyTopic
->aItems
.begin(),
775 pMyTopic
->aItems
.end(),this));
780 const OUString
DdeItem::GetName() const
782 return pName
->toOUString();
785 void DdeItem::NotifyClient()
787 if( pMyTopic
&& pImpData
)
789 DdeInstData
* pInst
= ImpGetInstData();
790 DBG_ASSERT(pInst
,"SVDDE:No instance data");
791 DdePostAdvise( pInst
->hDdeInstSvr
, *pMyTopic
->pName
, *pName
);
795 void DdeItem::IncMonitor( sal_uLong nHCnv
)
799 pImpData
= new DdeItemImp
;
800 if( DDEGETPUTITEM
== nType
)
801 ((DdeGetPutItem
*)this)->AdviseLoop( true );
805 for( sal_uInt16 n
= pImpData
->size(); n
; )
806 if( (*pImpData
)[ --n
].nHCnv
== nHCnv
)
808 ++(*pImpData
)[ n
].nHCnv
;
813 pImpData
->push_back( DdeItemImpData( nHCnv
) );
816 void DdeItem::DecMonitor( sal_uLong nHCnv
)
820 for( sal_uInt16 n
= 0; n
< pImpData
->size(); ++n
)
822 DdeItemImpData
* pData
= &(*pImpData
)[n
];
823 if( pData
->nHCnv
== nHCnv
)
825 if( !pData
->nCnt
|| !--pData
->nCnt
)
827 if( 1 < pImpData
->size() )
829 pImpData
->erase(pImpData
->begin() + n
);
833 delete pImpData
, pImpData
= 0;
834 if( DDEGETPUTITEM
== nType
)
835 ((DdeGetPutItem
*)this)->AdviseLoop( false );
844 short DdeItem::GetLinks()
849 for( sal_uInt16 n
= pImpData
->size(); n
; )
851 nCnt
= nCnt
+ (*pImpData
)[ --n
].nCnt
;
857 DdeGetPutItem::DdeGetPutItem( const sal_Unicode
* p
)
860 nType
= DDEGETPUTITEM
;
863 DdeGetPutItem::DdeGetPutItem( const OUString
& rStr
)
866 nType
= DDEGETPUTITEM
;
869 DdeGetPutItem::DdeGetPutItem( const DdeItem
& rItem
)
872 nType
= DDEGETPUTITEM
;
875 DdeData
* DdeGetPutItem::Get(SotClipboardFormatId
)
880 bool DdeGetPutItem::Put( const DdeData
* )
885 void DdeGetPutItem::AdviseLoop( bool )
889 OUString
DdeService::SysItems()
892 std::vector
<DdeTopic
*>::iterator iter
;
893 std::vector
<DdeItem
*>::iterator iterItem
;
894 for ( iter
= aTopics
.begin(); iter
!= aTopics
.end(); ++iter
)
896 if ( (*iter
)->GetName() == reinterpret_cast<const sal_Unicode
*>(SZDDESYS_TOPIC
) )
899 for ( iterItem
= (*iter
)->aItems
.begin(); iterItem
!= (*iter
)->aItems
.end(); ++iterItem
, n
++ )
903 s
+= (*iterItem
)->GetName();
912 OUString
DdeService::Topics()
915 std::vector
<DdeTopic
*>::iterator iter
;
918 for ( iter
= aTopics
.begin(); iter
!= aTopics
.end(); ++iter
, n
++ )
922 s
+= (*iter
)->GetName();
929 OUString
DdeService::Formats()
934 for (size_t i
= 0; i
< aFormats
.size(); ++i
, ++n
)
936 long f
= aFormats
[ i
];
940 switch( (sal_uInt16
)f
)
951 GetClipboardFormatName( (UINT
)f
, buf
, sizeof(buf
) / sizeof(TCHAR
) );
952 s
+= OUString(reinterpret_cast<sal_Unicode
*>(buf
));
963 OUString
DdeService::Status()
965 return IsBusy() ? OUString("Busy\r\n") : OUString("Ready\r\n");
968 bool DdeService::IsBusy()
973 OUString
DdeService::GetHelp()
978 bool DdeTopic::MakeItem( const OUString
& )
983 bool DdeService::MakeTopic( const OUString
& )
988 OUString
DdeService::SysTopicGet( const OUString
& )
993 bool DdeService::SysTopicExecute( const OUString
* )
998 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */