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 <svl/svdde.hxx>
26 #include <tools/debug.hxx>
27 #include <osl/thread.h>
28 #include <o3tl/sorted_vector.hxx>
41 DdeItemImpData( sal_uLong nH
) : nHCnv( nH
), nCnt( 1 ) {}
44 class DdeItemImp
: public std::vector
<DdeItemImpData
> {};
46 // --- DdeInternat::SvrCallback() ----------------------------------
49 HDDEDATA CALLBACK
DdeInternal::SvrCallback(
50 WORD nCode
, WORD nCbType
, HCONV hConv
, HSZ hText1
, HSZ hText2
,
51 HDDEDATA hData
, DWORD
, DWORD
)
54 HDDEDATA CALLBACK
DdeInternal::SvrCallback(
55 WORD nCode
, WORD nCbType
, HCONV hConv
, HSZ hText1
, HSZ hText2
,
56 HDDEDATA hData
, DWORD
, DWORD
)
58 HDDEDATA CALLBACK _export
DdeInternal::SvrCallback(
59 WORD nCode
, WORD nCbType
, HCONV hConv
, HSZ hText1
, HSZ hText2
,
60 HDDEDATA hData
, DWORD
, DWORD
)
64 DdeServices
& rAll
= DdeService::GetServices();
71 DdeInstData
* pInst
= ImpGetInstData();
72 DBG_ASSERT(pInst
,"SVDDE:No instance data");
76 case XTYP_WILDCONNECT
:
80 TCHAR chTopicBuf
[250];
82 DdeQueryString( pInst
->hDdeInstSvr
, hText1
, chTopicBuf
,
83 sizeof(chTopicBuf
)/sizeof(TCHAR
), CP_WINUNICODE
);
85 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
88 if ( !hText2
|| ( *pService
->pName
== hText2
) )
90 String
sTopics( pService
->Topics() );
98 OUString
s( sTopics
.GetToken( 0, '\t', n
));
99 if( s
== reinterpret_cast<const sal_Unicode
*>(chTopicBuf
) )
104 nTopics
+= comphelper::string::getTokenCount(sTopics
, '\t');
110 return (HDDEDATA
)NULL
;
112 HSZPAIR
* pPairs
= new HSZPAIR
[nTopics
+ 1];
114 return (HDDEDATA
)NULL
;
117 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
120 if ( !hText2
|| (*pService
->pName
== hText2
) )
122 String
sTopics( pService
->Topics() );
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
);
135 q
->hszSvc
= *pService
->pName
;
136 q
->hszTopic
= *pTopic
->pName
;
146 HDDEDATA h
= DdeCreateDataHandle(
147 pInst
->hDdeInstSvr
, (LPBYTE
) pPairs
,
148 sizeof(HSZPAIR
) * (nTopics
+1),
149 0, NULL
, nCbType
, 0);
155 pService
= FindService( hText2
);
157 pTopic
= FindTopic( *pService
, hText1
);
161 return (HDDEDATA
)DDE_FACK
;
163 return (HDDEDATA
) NULL
;
165 case XTYP_CONNECT_CONFIRM
:
166 pService
= FindService( hText2
);
169 pTopic
= FindTopic( *pService
, hText1
);
172 pTopic
->Connect( (long) hConv
);
173 pC
= new Conversation
;
176 pService
->pConv
->push_back( pC
);
179 return (HDDEDATA
)NULL
;
182 for (DdeServices::iterator aI
= rAll
.begin(); aI
!= rAll
.end(); ++aI
)
185 for ( size_t i
= 0, n
= pService
->pConv
->size(); i
< n
; ++i
)
187 pC
= (*pService
->pConv
)[ i
];
188 if ( pC
->hConv
== hConv
)
193 return (HDDEDATA
) DDE_FNOTPROCESSED
;
196 if ( nCode
== XTYP_DISCONNECT
)
198 pC
->pTopic
->_Disconnect( (long) hConv
);
199 for ( ConvList::iterator it
= pService
->pConv
->begin();
200 it
!= pService
->pConv
->end();
206 pService
->pConv
->erase( it
);
210 return (HDDEDATA
)NULL
;
213 sal_Bool bExec
= sal_Bool(nCode
== XTYP_EXECUTE
);
215 if ( pTopic
&& !bExec
)
216 pItem
= FindItem( *pTopic
, hText2
);
220 if ( !bExec
&& !pService
->HasCbFormat( nCbType
) )
222 if ( !pItem
&& !bExec
)
223 return (HDDEDATA
)DDE_FNOTPROCESSED
;
225 pTopic
->aItem
= pItem
->GetName();
227 pTopic
->aItem
= OUString();
229 sal_Bool bRes
= sal_False
;
230 pInst
->hCurConvSvr
= (long)hConv
;
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();
250 aRes
= pService
->SysTopicGet( pTopic
->aItem
);
253 pData
= new DdeData( aRes
);
257 else if( DDEGETPUTITEM
== pItem
->nType
)
258 pData
= ((DdeGetPutItem
*)pItem
)->Get(
259 DdeData::GetInternalFormat( nCbType
) );
261 pData
= pTopic
->Get( DdeData::GetInternalFormat( nCbType
));
264 return DdeCreateDataHandle( pInst
->hDdeInstSvr
,
265 (LPBYTE
)pData
->pImp
->pData
,
268 DdeData::GetExternalFormat(
275 if ( !pTopic
->IsSystemTopic() )
278 d
.pImp
->hData
= hData
;
279 d
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
281 if( DDEGETPUTITEM
== pItem
->nType
)
282 bRes
= ((DdeGetPutItem
*)pItem
)->Put( &d
);
284 bRes
= pTopic
->Put( &d
);
286 pInst
->hCurConvSvr
= 0;
288 return (HDDEDATA
)DDE_FACK
;
290 return (HDDEDATA
) DDE_FNOTPROCESSED
;
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(),
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();
309 if( *(*iter
)->pName
== hText2
)
311 // es wurde tatsaechlich ausgewechselt
319 // es wurde doch nicht ausgewechselt, also wieder rein
320 pTopic
->aItems
.push_back(pItem
);
322 pItem
= iter
!= pTopic
->aItems
.end() ? *iter
: NULL
;
327 pItem
->IncMonitor( (long)hConv
);
328 pInst
->hCurConvSvr
= 0;
331 return (HDDEDATA
)sal_True
;
334 pItem
->DecMonitor( (long)hConv
);
335 if( !pItem
->pImpData
)
336 pTopic
->StopAdviseLoop();
337 pInst
->hCurConvSvr
= 0;
338 return (HDDEDATA
)sal_True
;
343 aExec
.pImp
->hData
= hData
;
344 aExec
.pImp
->nFmt
= DdeData::GetInternalFormat( nCbType
);
348 aName
= (const sal_Unicode
*)aExec
.pImp
->pData
;
350 if( pTopic
->IsSystemTopic() )
351 bRes
= pService
->SysTopicExecute( &aName
);
353 bRes
= pTopic
->Execute( &aName
);
355 pInst
->hCurConvSvr
= 0;
357 return (HDDEDATA
)DDE_FACK
;
359 return (HDDEDATA
)DDE_FNOTPROCESSED
;
362 return (HDDEDATA
)NULL
;
365 // --- DdeInternat::FindService() ----------------------------------
367 DdeService
* DdeInternal::FindService( HSZ hService
)
370 DdeServices
& rSvc
= DdeService::GetServices();
371 for (DdeServices::iterator aI
= rSvc
.begin(); aI
!= rSvc
.end(); ++aI
)
374 if ( *s
->pName
== hService
)
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
)
402 // dann befragen wir doch mal unsere Ableitung:
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
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
)
432 // dann befragen wir doch mal unsere Ableitung:
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
442 // --- DdeService::DdeService() ------------------------------------
444 DdeService::DdeService( const String
& rService
)
446 DdeInstData
* pInst
= ImpGetInstData();
448 pInst
= ImpInitInstData();
450 pInst
->nInstanceSvr
++;
452 if ( !pInst
->hDdeInstSvr
)
454 nStatus
= sal::static_int_cast
< short >(
455 DdeInitialize( &pInst
->hDdeInstSvr
,
456 (PFNCALLBACK
)DdeInternal::SvrCallback
,
458 CBF_SKIP_REGISTRATIONS
|
459 CBF_SKIP_UNREGISTRATIONS
, 0L ) );
460 pInst
->pServicesSvr
= new DdeServices
;
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...
497 // Bei Client/Server werden die Server nicht beendet, wenn mehr
498 // als einer gestartet.
499 // Weil keine System-Messagequeue ?!
504 pInst
->nInstanceSvr
--;
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)
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
) )
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
);
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
)
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
)
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
);
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;
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
)
655 if( DDEGETPUTITEM
== r
.nType
)
656 s
= new DdeGetPutItem( r
);
658 s
= new DdeItem( r
);
661 aItems
.push_back( s
);
667 // --- DdeTopic::InsertItem() -----------------------------------------
669 void DdeTopic::InsertItem( DdeItem
* 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
) )
689 if ( iter
!= aItems
.end() )
691 (*iter
)->pMyTopic
= 0;
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
);
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
);
739 // --- DdeTopic::Get() ---------------------------------------------
741 DdeData
* DdeTopic::Get( sal_uLong nFmt
)
743 if ( aGetLink
.IsSet() )
744 return (DdeData
*)aGetLink
.Call( (void*)nFmt
);
749 // --- DdeTopic::Put() ---------------------------------------------
751 sal_Bool
DdeTopic::Put( const DdeData
* r
)
753 if ( aPutLink
.IsSet() )
754 return (sal_Bool
)aPutLink
.Call( (void*) r
);
759 // --- DdeTopic::Execute() -----------------------------------------
761 sal_Bool
DdeTopic::Execute( const String
* r
)
763 if ( aExecLink
.IsSet() )
764 return (sal_Bool
)aExecLink
.Call( (void*)r
);
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()
785 // --- DdeTopic::StopAdviseLoop() ----------------------------------
787 sal_Bool
DdeTopic::StopAdviseLoop()
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
);
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
);
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() );
828 // --- DdeItem::~DdeItem() -----------------------------------------
833 pMyTopic
->aItems
.erase(std::remove(pMyTopic
->aItems
.begin(),
834 pMyTopic
->aItems
.end(),this));
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
)
864 pImpData
= new DdeItemImp
;
865 if( DDEGETPUTITEM
== nType
)
866 ((DdeGetPutItem
*)this)->AdviseLoop( sal_True
);
870 for( sal_uInt16 n
= pImpData
->size(); n
; )
871 if( (*pImpData
)[ --n
].nHCnv
== nHCnv
)
873 ++(*pImpData
)[ n
].nHCnv
;
878 pImpData
->push_back( DdeItemImpData( nHCnv
) );
881 // --- DdeItem::DecMonitor() ------------------------------------------
883 void DdeItem::DecMonitor( sal_uLong nHCnv
)
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
);
900 delete pImpData
, pImpData
= 0;
901 if( DDEGETPUTITEM
== nType
)
902 ((DdeGetPutItem
*)this)->AdviseLoop( sal_False
);
911 // --- DdeItem::GetLinks() ------------------------------------------
913 short DdeItem::GetLinks()
917 for( sal_uInt16 n
= pImpData
->size(); n
; )
919 nCnt
= nCnt
+ (*pImpData
)[ --n
].nCnt
;
924 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
926 DdeGetPutItem::DdeGetPutItem( const sal_Unicode
* p
)
929 nType
= DDEGETPUTITEM
;
932 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
934 DdeGetPutItem::DdeGetPutItem( const String
& rStr
)
937 nType
= DDEGETPUTITEM
;
940 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------
942 DdeGetPutItem::DdeGetPutItem( const DdeItem
& rItem
)
945 nType
= DDEGETPUTITEM
;
949 // --- DdeGetPutData::Get() ----------------------------------------
951 DdeData
* DdeGetPutItem::Get( sal_uLong
)
956 // --- DdeGetPutData::Put() ----------------------------------------
958 sal_Bool
DdeGetPutItem::Put( const DdeData
* )
963 // --- DdeGetPutData::AdviseLoop() ---------------------------------
965 void DdeGetPutItem::AdviseLoop( sal_Bool
)
970 // --- DdeService::SysItems() --------------------------------------
972 String
DdeService::SysItems()
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
) )
982 for ( iterItem
= (*iter
)->aItems
.begin(); iterItem
!= (*iter
)->aItems
.end(); ++iterItem
, n
++ )
986 s
+= (*iterItem
)->GetName();
988 s
+= OUString("\r\n");
995 // --- DdeService::Topics() ----------------------------------------
997 String
DdeService::Topics()
1000 std::vector
<DdeTopic
*>::iterator iter
;
1003 for ( iter
= aTopics
.begin(); iter
!= aTopics
.end(); ++iter
, n
++ )
1007 s
+= (*iter
)->GetName();
1009 s
+= OUString("\r\n");
1014 // --- DdeService::Formats() ---------------------------------------
1016 String
DdeService::Formats()
1022 for (size_t i
= 0; i
< aFormats
.size(); ++i
, ++n
)
1028 switch( (sal_uInt16
)f
)
1031 s
+= OUString("TEXT");
1034 s
+= OUString("BITMAP");
1039 GetClipboardFormatName( (UINT
)f
, buf
, sizeof(buf
) / sizeof(TCHAR
) );
1040 s
+= OUString(reinterpret_cast<sal_Unicode
*>(buf
));
1046 s
+= OUString("\r\n");
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()
1065 // --- DdeService::GetHelp() ----------------------------------------
1067 String
DdeService::GetHelp()
1072 sal_Bool
DdeTopic::MakeItem( const OUString
& )
1077 sal_Bool
DdeService::MakeTopic( const OUString
& )
1082 String
DdeService::SysTopicGet( const String
& )
1087 sal_Bool
DdeService::SysTopicExecute( const String
* )
1092 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */