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 ) {}
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();
60 DdeInstData
* pInst
= ImpGetInstData();
61 DBG_ASSERT(pInst
,"SVDDE:No instance data");
65 case XTYP_WILDCONNECT
:
69 TCHAR chTopicBuf
[250];
71 DdeQueryString( pInst
->hDdeInstSvr
, hText1
, chTopicBuf
,
72 sizeof(chTopicBuf
)/sizeof(TCHAR
), CP_WINUNICODE
);
74 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
77 if ( !hText2
|| ( *pService
->pName
== hText2
) )
79 OUString
sTopics( pService
->Topics() );
80 if (!sTopics
.isEmpty())
87 OUString
s( sTopics
.getToken( 0, '\t', n
));
88 if( s
== reinterpret_cast<const sal_Unicode
*>(chTopicBuf
) )
93 nTopics
+= comphelper::string::getTokenCount(sTopics
, '\t');
99 return (HDDEDATA
)NULL
;
101 HSZPAIR
* pPairs
= new HSZPAIR
[nTopics
+ 1];
103 return (HDDEDATA
)NULL
;
106 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
109 if ( !hText2
|| (*pService
->pName
== hText2
) )
111 OUString
sTopics( pService
->Topics() );
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
);
124 q
->hszSvc
= *pService
->pName
;
125 q
->hszTopic
= *pTopic
->pName
;
135 HDDEDATA h
= DdeCreateDataHandle(
136 pInst
->hDdeInstSvr
, (LPBYTE
) pPairs
,
137 sizeof(HSZPAIR
) * (nTopics
+1),
138 0, NULL
, nCbType
, 0);
144 pService
= FindService( hText2
);
146 pTopic
= FindTopic( *pService
, hText1
);
150 return (HDDEDATA
)DDE_FACK
;
152 return (HDDEDATA
) NULL
;
154 case XTYP_CONNECT_CONFIRM
:
155 pService
= FindService( hText2
);
158 pTopic
= FindTopic( *pService
, hText1
);
161 pTopic
->Connect( (sal_IntPtr
) hConv
);
162 pC
= new Conversation
;
165 pService
->pConv
->push_back( pC
);
168 return (HDDEDATA
)NULL
;
171 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
174 for ( size_t i
= 0, n
= pService
->pConv
->size(); i
< n
; ++i
)
176 pC
= (*pService
->pConv
)[ i
];
177 if ( pC
->hConv
== hConv
)
182 return (HDDEDATA
) DDE_FNOTPROCESSED
;
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();
195 pService
->pConv
->erase( it
);
199 return (HDDEDATA
)NULL
;
202 bool bExec
= nCode
== XTYP_EXECUTE
;
204 if ( pTopic
&& !bExec
)
205 pItem
= FindItem( *pTopic
, hText2
);
209 if ( !bExec
&& !pService
->HasCbFormat( nCbType
) )
211 if ( !pItem
&& !bExec
)
212 return (HDDEDATA
)DDE_FNOTPROCESSED
;
214 pTopic
->aItem
= pItem
->GetName();
216 pTopic
->aItem
= OUString();
219 pInst
->hCurConvSvr
= (sal_IntPtr
)hConv
;
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();
239 aRes
= pService
->SysTopicGet( pTopic
->aItem
);
241 if ( !aRes
.isEmpty() )
242 pData
= new DdeData( aRes
);
246 else if( DDEGETPUTITEM
== pItem
->nType
)
248 pData
= ((DdeGetPutItem
*)pItem
)->Get( DdeData::GetInternalFormat( nCbType
) );
252 pData
= pTopic
->Get( DdeData::GetInternalFormat( nCbType
));
257 return DdeCreateDataHandle( pInst
->hDdeInstSvr
,
258 (LPBYTE
)pData
->pImp
->pData
,
261 DdeData::GetExternalFormat(
269 if ( !pTopic
->IsSystemTopic() )
272 d
.pImp
->hData
= hData
;
273 d
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
275 if( DDEGETPUTITEM
== pItem
->nType
)
276 bRes
= ((DdeGetPutItem
*)pItem
)->Put( &d
);
278 bRes
= pTopic
->Put( &d
);
280 pInst
->hCurConvSvr
= 0;
282 return (HDDEDATA
)DDE_FACK
;
284 return (HDDEDATA
) DDE_FNOTPROCESSED
;
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(),
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();
303 if( *(*iter
)->pName
== hText2
)
305 // es wurde tatsaechlich ausgewechselt
313 // es wurde doch nicht ausgewechselt, also wieder rein
314 pTopic
->aItems
.push_back(pItem
);
316 pItem
= iter
!= pTopic
->aItems
.end() ? *iter
: NULL
;
321 pItem
->IncMonitor( (sal_IntPtr
)hConv
);
322 pInst
->hCurConvSvr
= 0;
325 return (HDDEDATA
)sal_True
;
328 pItem
->DecMonitor( (sal_IntPtr
)hConv
);
329 if( !pItem
->pImpData
)
330 pTopic
->StopAdviseLoop();
331 pInst
->hCurConvSvr
= 0;
332 return (HDDEDATA
)sal_True
;
337 aExec
.pImp
->hData
= hData
;
338 aExec
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
342 aName
= (const sal_Unicode
*)aExec
.pImp
->pData
;
344 if( pTopic
->IsSystemTopic() )
345 bRes
= pService
->SysTopicExecute( &aName
);
347 bRes
= pTopic
->Execute( &aName
);
349 pInst
->hCurConvSvr
= 0;
351 return (HDDEDATA
)DDE_FACK
;
353 return (HDDEDATA
)DDE_FNOTPROCESSED
;
356 return (HDDEDATA
)NULL
;
359 // --- DdeInternat::FindService() ----------------------------------
361 DdeService
* DdeInternal::FindService( HSZ hService
)
364 DdeServices
& rSvc
= DdeService::GetServices();
365 for (DdeServices::iterator aI
= rSvc
.begin(); aI
!= rSvc
.end(); ++aI
)
368 if ( *s
->pName
== hService
)
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
)
393 bContinue
= !bContinue
;
397 // dann befragen wir doch mal unsere Ableitung:
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
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
)
426 bContinue
= !bContinue
;
430 // dann befragen wir doch mal unsere Ableitung:
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
441 // --- DdeService::DdeService() ------------------------------------
443 DdeService::DdeService( const OUString
& rService
)
445 DdeInstData
* pInst
= ImpGetInstData();
447 pInst
= ImpInitInstData();
449 pInst
->nInstanceSvr
++;
451 if ( !pInst
->hDdeInstSvr
)
453 nStatus
= sal::static_int_cast
< short >(
454 DdeInitialize( &pInst
->hDdeInstSvr
,
455 (PFNCALLBACK
)DdeInternal::SvrCallback
,
457 CBF_SKIP_REGISTRATIONS
|
458 CBF_SKIP_UNREGISTRATIONS
, 0L ) );
459 pInst
->pServicesSvr
= new DdeServices
;
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...
499 // Bei Client/Server werden die Server nicht beendet, wenn mehr
500 // als einer gestartet.
501 // Weil keine System-Messagequeue ?!
506 pInst
->nInstanceSvr
--;
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)
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
) )
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
);
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
)
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
)
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
);
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;
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
)
659 if( DDEGETPUTITEM
== r
.nType
)
660 s
= new DdeGetPutItem( r
);
662 s
= new DdeItem( r
);
666 aItems
.push_back( s
);
672 // --- DdeTopic::InsertItem() -----------------------------------------
674 void DdeTopic::InsertItem( DdeItem
* 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
) )
694 if ( iter
!= aItems
.end() )
696 (*iter
)->pMyTopic
= 0;
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
);
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
);
744 // --- DdeTopic::Get() ---------------------------------------------
746 DdeData
* DdeTopic::Get( sal_uIntPtr nFmt
)
748 if ( aGetLink
.IsSet() )
749 return (DdeData
*)aGetLink
.Call( (void*)nFmt
);
754 // --- DdeTopic::Put() ---------------------------------------------
756 bool DdeTopic::Put( const DdeData
* r
)
758 if ( aPutLink
.IsSet() )
759 return aPutLink
.Call( (void*) r
);
764 // --- DdeTopic::Execute() -----------------------------------------
766 bool DdeTopic::Execute( const OUString
* r
)
768 if ( aExecLink
.IsSet() )
769 return aExecLink
.Call( (void*)r
);
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()
790 // --- DdeTopic::StopAdviseLoop() ----------------------------------
792 bool DdeTopic::StopAdviseLoop()
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
);
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
);
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() );
833 // --- DdeItem::~DdeItem() -----------------------------------------
838 pMyTopic
->aItems
.erase(std::remove(pMyTopic
->aItems
.begin(),
839 pMyTopic
->aItems
.end(),this));
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
)
869 pImpData
= new DdeItemImp
;
870 if( DDEGETPUTITEM
== nType
)
871 ((DdeGetPutItem
*)this)->AdviseLoop( true );
875 for( sal_uInt16 n
= pImpData
->size(); n
; )
876 if( (*pImpData
)[ --n
].nHCnv
== nHCnv
)
878 ++(*pImpData
)[ n
].nHCnv
;
883 pImpData
->push_back( DdeItemImpData( nHCnv
) );
886 // --- DdeItem::DecMonitor() ------------------------------------------
888 void DdeItem::DecMonitor( sal_uLong nHCnv
)
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
);
905 delete pImpData
, pImpData
= 0;
906 if( DDEGETPUTITEM
== nType
)
907 ((DdeGetPutItem
*)this)->AdviseLoop( false );
916 // --- DdeItem::GetLinks() ------------------------------------------
918 short DdeItem::GetLinks()
923 for( sal_uInt16 n
= pImpData
->size(); n
; )
925 nCnt
= nCnt
+ (*pImpData
)[ --n
].nCnt
;
931 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
933 DdeGetPutItem::DdeGetPutItem( const sal_Unicode
* p
)
936 nType
= DDEGETPUTITEM
;
939 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
941 DdeGetPutItem::DdeGetPutItem( const OUString
& rStr
)
944 nType
= DDEGETPUTITEM
;
947 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
949 DdeGetPutItem::DdeGetPutItem( const DdeItem
& rItem
)
952 nType
= DDEGETPUTITEM
;
956 // --- DdeGetPutData::Get() ----------------------------------------
958 DdeData
* DdeGetPutItem::Get( sal_uLong
)
963 // --- DdeGetPutData::Put() ----------------------------------------
965 bool DdeGetPutItem::Put( const DdeData
* )
970 // --- DdeGetPutData::AdviseLoop() ---------------------------------
972 void DdeGetPutItem::AdviseLoop( bool )
977 // --- DdeService::SysItems() --------------------------------------
979 OUString
DdeService::SysItems()
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
) )
989 for ( iterItem
= (*iter
)->aItems
.begin(); iterItem
!= (*iter
)->aItems
.end(); ++iterItem
, n
++ )
993 s
+= (*iterItem
)->GetName();
1002 // --- DdeService::Topics() ----------------------------------------
1004 OUString
DdeService::Topics()
1007 std::vector
<DdeTopic
*>::iterator iter
;
1010 for ( iter
= aTopics
.begin(); iter
!= aTopics
.end(); ++iter
, n
++ )
1014 s
+= (*iter
)->GetName();
1021 // --- DdeService::Formats() ---------------------------------------
1023 OUString
DdeService::Formats()
1029 for (size_t i
= 0; i
< aFormats
.size(); ++i
, ++n
)
1035 switch( (sal_uInt16
)f
)
1046 GetClipboardFormatName( (UINT
)f
, buf
, sizeof(buf
) / sizeof(TCHAR
) );
1047 s
+= OUString(reinterpret_cast<sal_Unicode
*>(buf
));
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()
1072 // --- DdeService::GetHelp() ----------------------------------------
1074 OUString
DdeService::GetHelp()
1079 bool DdeTopic::MakeItem( const OUString
& )
1084 bool DdeService::MakeTopic( const OUString
& )
1089 OUString
DdeService::SysTopicGet( const OUString
& )
1094 bool DdeService::SysTopicExecute( const OUString
* )
1099 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */