LibreOffice Module svl (master) 1
ddesvr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "ddeimp.hxx"
21#include <algorithm>
22#include <memory>
23#include <comphelper/string.hxx>
24#include <rtl/ustring.hxx>
25#include <svl/svdde.hxx>
26#include <osl/thread.h>
29
30namespace {
31
32enum DdeItemType
33{
34 DDEITEM,
35 DDEGETPUTITEM
36};
37
38}
39
41{
43 sal_uInt16 nCnt;
44
45 explicit DdeItemImpData( HCONV nH ) : nHCnv( nH ), nCnt( 1 ) {}
46};
47
49 UINT nCode, UINT nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
50 HDDEDATA hData, ULONG_PTR, ULONG_PTR )
51{
52 DdeInstData* pInst = ImpGetInstData();
53 assert(pInst);
54
55 switch( nCode )
56 {
57 case XTYP_WILDCONNECT:
58 {
59 std::vector<HSZPAIR> aPairs;
60
61 WCHAR chTopicBuf[256];
62 if( hText1 )
63 DdeQueryStringW( pInst->hDdeInstSvr, hText1, chTopicBuf,
64 SAL_N_ELEMENTS(chTopicBuf), CP_WINUNICODE );
65
66 for (auto& pService : DdeService::GetServices())
67 {
68 if (hText2 && !(*pService->pName == hText2))
69 continue;
70
71 OUString sTopics(pService->Topics().replaceAll("\n", "").replaceAll("\r", ""));
72 if (sTopics.isEmpty())
73 continue;
74
75 for (sal_Int32 n = 0; -1 != n;)
76 {
77 OUString s(sTopics.getToken(0, '\t', n));
78 if (hText1 && s != o3tl::toU(chTopicBuf))
79 continue;
80
81 DdeString aDStr(pInst->hDdeInstSvr, s);
82 if (auto pTopic = FindTopic(*pService, aDStr.getHSZ()))
83 {
84 auto& pair = aPairs.emplace_back();
85 pair.hszSvc = pService->pName->getHSZ();
86 pair.hszTopic = pTopic->pName->getHSZ();
87 }
88 }
89 }
90
91 if (aPairs.empty())
92 return nullptr;
93 aPairs.emplace_back(); // trailing zero
94
95 HDDEDATA h = DdeCreateDataHandle(
96 pInst->hDdeInstSvr,
97 reinterpret_cast<LPBYTE>(aPairs.data()),
98 sizeof(HSZPAIR) * aPairs.size(),
99 0, nullptr, nCbType, 0);
100 return h;
101 }
102
103 case XTYP_CONNECT:
104 if (auto pService = FindService(hText2))
105 if (FindTopic(*pService, hText1))
106 return reinterpret_cast<HDDEDATA>(DDE_FACK);
107 return nullptr;
108
109 case XTYP_CONNECT_CONFIRM:
110 if (auto pService = FindService(hText2))
111 {
112 if (auto pTopic = FindTopic(*pService, hText1))
113 {
114 auto pC = new Conversation;
115 pC->hConv = hConv;
116 pC->pTopic = pTopic;
117 pService->m_vConv.emplace_back( pC );
118 }
119 }
120 return nullptr;
121 }
122
123 DdeService* pService = nullptr;
124 Conversation* pC = nullptr;
125 for (auto& rpService : DdeService::GetServices())
126 {
127 for ( size_t i = 0, n = rpService->m_vConv.size(); i < n; ++i )
128 {
129 pC = rpService->m_vConv[ i ].get();
130 if ( pC->hConv == hConv )
131 pService = rpService;
132 }
133 }
134
135 if (!pService)
136 return reinterpret_cast<HDDEDATA>(DDE_FNOTPROCESSED);
137 assert(pC);
138
139 if ( nCode == XTYP_DISCONNECT)
140 {
141 DisconnectTopic(*pC->pTopic, hConv);
142 auto it = std::find_if(pService->m_vConv.begin(), pService->m_vConv.end(),
143 [&pC](const std::unique_ptr<Conversation>& rxConv) { return rxConv.get() == pC; });
144 if (it != pService->m_vConv.end())
145 pService->m_vConv.erase( it );
146 return nullptr;
147 }
148
149 bool bExec = nCode == XTYP_EXECUTE;
150 DdeTopic* pTopic = pC->pTopic;
151 DdeItem* pItem;
152 if (pTopic && !bExec && pService->HasCbFormat(nCbType))
153 pItem = FindItem( *pTopic, hText2 );
154 else
155 pItem = nullptr;
156
157 if ( !pItem && !bExec )
158 return static_cast<HDDEDATA>(DDE_FNOTPROCESSED);
159 if ( pItem )
160 pTopic->aItem = pItem->GetName();
161 else
162 pTopic->aItem.clear();
163
164 bool bRes = false;
165 switch( nCode )
166 {
167 case XTYP_REQUEST:
168 case XTYP_ADVREQ:
169 {
170 OUString aRes; // Must be free not until the end!
171 DdeData* pData;
172 if ( pTopic->IsSystemTopic() )
173 {
174 if ( pTopic->aItem == SZDDESYS_ITEM_TOPICS )
175 aRes = pService->Topics();
176 else if ( pTopic->aItem == SZDDESYS_ITEM_SYSITEMS )
177 aRes = pService->SysItems();
178 else if ( pTopic->aItem == SZDDESYS_ITEM_STATUS )
179 aRes = pService->Status();
180 else if ( pTopic->aItem == SZDDESYS_ITEM_FORMATS )
181 aRes = pService->Formats();
182 else if ( pTopic->aItem == SZDDESYS_ITEM_HELP )
183 aRes = OUString();
184 else
185 aRes = OUString();
186
187 if ( !aRes.isEmpty() )
188 pData = new DdeData( aRes );
189 else
190 pData = nullptr;
191 }
192 else if( DDEGETPUTITEM == pItem->nType )
193 {
194 pData = static_cast<DdeGetPutItem*>(pItem)->Get( DdeData::GetInternalFormat( nCbType ) );
195 }
196 else
197 {
198 pData = pTopic->Get( DdeData::GetInternalFormat( nCbType ));
199 }
200
201 if ( pData )
202 {
203 return DdeCreateDataHandle( pInst->hDdeInstSvr,
204 static_cast<LPBYTE>(const_cast<void *>(pData->xImp->pData)),
205 pData->xImp->nData,
206 0, hText2,
208 pData->xImp->nFmt ),
209 0 );
210 }
211 }
212 break;
213
214 case XTYP_POKE:
215 if ( !pTopic->IsSystemTopic() )
216 {
217 DdeData d;
218 d.xImp->hData = hData;
219 d.xImp->nFmt = DdeData::GetInternalFormat( nCbType );
220 d.Lock();
221 if( DDEGETPUTITEM == pItem->nType )
222 bRes = static_cast<DdeGetPutItem*>(pItem)->Put( &d );
223 else
224 bRes = pTopic->Put( &d );
225 }
226 if ( bRes )
227 return reinterpret_cast<HDDEDATA>(DDE_FACK);
228 else
229 return reinterpret_cast<HDDEDATA>(DDE_FNOTPROCESSED);
230
231 case XTYP_ADVSTART:
232 {
233 // Is the Item turning into a HotLink for the first time?
234 if( !pItem->pImpData && pTopic->StartAdviseLoop() )
235 {
236 // Then the Item has been exchanged
237 std::vector<DdeItem*>::iterator it(std::find(pTopic->aItems.begin(),
238 pTopic->aItems.end(),
239 pItem));
240 if (it != pTopic->aItems.end())
241 pTopic->aItems.erase(it);
242
243 std::vector<DdeItem*>::iterator iter;
244 iter = std::find_if(pTopic->aItems.begin(), pTopic->aItems.end(),
245 [&hText2](const DdeItem* pDdeItem) { return *pDdeItem->pName == hText2; });
246 if (iter != pTopic->aItems.end())
247 {
248 // It was exchanged indeed
249 delete pItem;
250 pItem = nullptr;
251 }
252
253 if( pItem )
254 // It was not exchange, so back in
255 pTopic->aItems.push_back(pItem);
256 else
257 pItem = iter != pTopic->aItems.end() ? *iter : nullptr;
258 }
259
260 if (pItem)
261 {
262 IncMonitor(pItem, hConv);
263 }
264 }
265 return reinterpret_cast<HDDEDATA>(TRUE);
266
267 case XTYP_ADVSTOP:
268 DecMonitor(pItem, hConv);
269 return reinterpret_cast<HDDEDATA>(TRUE);
270
271 case XTYP_EXECUTE:
272 {
273 DdeData aExec;
274 aExec.xImp->hData = hData;
275 aExec.xImp->nFmt = DdeData::GetInternalFormat( nCbType );
276 aExec.Lock();
277 OUString aName;
278
279 aName = static_cast<const sal_Unicode *>(aExec.xImp->pData);
280
281 if( pTopic->IsSystemTopic() )
282 bRes = false;
283 else
284 bRes = pTopic->Execute( &aName );
285 }
286 if ( bRes )
287 return reinterpret_cast<HDDEDATA>(DDE_FACK);
288 else
289 return reinterpret_cast<HDDEDATA>(DDE_FNOTPROCESSED);
290 }
291
292 return nullptr;
293}
294
296{
298 auto aI = std::find_if(rSvc.begin(), rSvc.end(),
299 [&hService](const DdeService* s) { return *s->pName == hService; });
300 if (aI != rSvc.end())
301 return *aI;
302
303 return nullptr;
304}
305
307{
308 std::vector<DdeTopic*> &rTopics = rService.aTopics;
309
310 auto iter = std::find_if(rTopics.begin(), rTopics.end(),
311 [&hTopic](const DdeTopic* pTopic) { return *pTopic->pName == hTopic; });
312 if (iter != rTopics.end())
313 return *iter;
314
315 return nullptr;
316}
317
319{
320 std::vector<DdeItem*>::iterator iter;
321 std::vector<DdeItem*> &rItems = rTopic.aItems;
322 DdeInstData* pInst = ImpGetInstData();
323 assert(pInst);
324 bool bContinue = false;
325
326 do
327 { // middle check loop
328 iter = std::find_if(rItems.begin(), rItems.end(),
329 [&hItem](const DdeItem* pItem) { return *pItem->pName == hItem; });
330 if (iter != rItems.end())
331 return *iter;
332 bContinue = !bContinue;
333 if( !bContinue )
334 break;
335
336 // Let's query our subclass
337 WCHAR chBuf[250];
338 DdeQueryStringW(pInst->hDdeInstSvr,hItem,chBuf,SAL_N_ELEMENTS(chBuf),CP_WINUNICODE );
339 bContinue = rTopic.MakeItem( OUString(o3tl::toU(chBuf)) );
340 // We need to search again
341 }
342 while( bContinue );
343
344 return nullptr;
345}
346
347DdeService::DdeService( const OUString& rService )
348{
349 DdeInstData* pInst = ImpGetInstData();
350 if( !pInst )
351 pInst = ImpInitInstData();
352 pInst->nRefCount++;
353 pInst->nInstanceSvr++;
354
355 if ( !pInst->hDdeInstSvr )
356 {
357 nStatus = sal::static_int_cast< short >(
358 DdeInitializeW( &pInst->hDdeInstSvr,
360 APPCLASS_STANDARD |
361 CBF_SKIP_REGISTRATIONS |
362 CBF_SKIP_UNREGISTRATIONS, 0 ) );
363 pInst->pServicesSvr = new DdeServices;
364 }
365 else
366 nStatus = DMLERR_NO_ERROR;
367
368 if ( pInst->pServicesSvr )
369 pInst->pServicesSvr->push_back( this );
370
371 pName = new DdeString( pInst->hDdeInstSvr, rService );
372 if ( nStatus == DMLERR_NO_ERROR )
373 {
374 if ( !DdeNameService( pInst->hDdeInstSvr, pName->getHSZ(), nullptr,
375 DNS_REGISTER | DNS_FILTEROFF ) )
376 {
377 nStatus = DMLERR_SYS_ERROR;
378 }
379 }
380 AddFormat( SotClipboardFormatId::STRING );
381 pSysTopic = new DdeTopic( SZDDESYS_TOPIC );
382 pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_TOPICS ) );
383 pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_SYSITEMS ) );
384 pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_STATUS ) );
385 pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_FORMATS ) );
386 pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_HELP ) );
388}
389
391{
392 DdeInstData* pInst = ImpGetInstData();
393 assert(pInst);
394 if ( pInst->pServicesSvr )
395 pInst->pServicesSvr->erase(std::remove(pInst->pServicesSvr->begin(), pInst->pServicesSvr->end(), this), pInst->pServicesSvr->end());
396
397 delete pSysTopic;
398 delete pName;
399
400 pInst->nInstanceSvr--;
401 pInst->nRefCount--;
402 if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr )
403 {
404 if( DdeUninitialize( pInst->hDdeInstSvr ) )
405 {
406 pInst->hDdeInstSvr = 0;
407 delete pInst->pServicesSvr;
408 pInst->pServicesSvr = nullptr;
409 if( pInst->nRefCount == 0)
411 }
412 }
413}
414
415OUString DdeService::GetName() const
416{
417 return pName->toOUString();
418}
419
421{
422 DdeInstData* pInst = ImpGetInstData();
423 assert(pInst);
424 return *(pInst->pServicesSvr);
425}
426
427void DdeService::AddTopic( const DdeTopic& rTopic )
428{
429 RemoveTopic( rTopic );
430 aTopics.push_back(const_cast<DdeTopic *>(&rTopic));
431}
432
434{
435 auto iter = std::find_if(aTopics.begin(), aTopics.end(),
436 [&rTopic](const DdeTopic* pTopic) { return DdeCmpStringHandles(pTopic->pName->getHSZ(), rTopic.pName->getHSZ()) == 0; });
437 if (iter != aTopics.end())
438 {
439 aTopics.erase(iter);
440 // Delete all conversions!
441 // Or else we work on deleted topics!
442 for( size_t n = m_vConv.size(); n; )
443 {
444 auto const& pC = m_vConv[ --n ];
445 if( pC->pTopic == &rTopic )
446 m_vConv.erase( m_vConv.begin() + n );
447 }
448 }
449}
450
451bool DdeService::HasCbFormat( sal_uInt32 nFmt )
452{
453 return std::find(aFormats.begin(), aFormats.end(), nFmt) != aFormats.end();
454}
455
457{
459}
460
462{
463 sal_uInt32 nExternalFmt = DdeData::GetExternalFormat( nFmt );
464 if (HasCbFormat(nExternalFmt))
465 return;
466 aFormats.push_back( nExternalFmt );
467}
468
470{
471 sal_uInt32 nExternalFmt = DdeData::GetExternalFormat( nFmt );
472 auto it = std::find(aFormats.begin(), aFormats.end(), nExternalFmt);
473 if (it != aFormats.end())
474 aFormats.erase( it );
475}
476
477DdeTopic::DdeTopic( const OUString& rName )
478{
479 DdeInstData* pInst = ImpGetInstData();
480 assert(pInst);
481 pName = new DdeString( pInst->hDdeInstSvr, rName );
482}
483
485{
486 for (auto& rpItem : aItems)
487 {
488 rpItem->pMyTopic = nullptr;
489 delete rpItem;
490 }
491
492 delete pName;
493}
494
495OUString DdeTopic::GetName() const
496{
497 return pName->toOUString();
498}
499
501{
502 return GetName() == SZDDESYS_TOPIC;
503}
504
506{
507 DdeItem* s;
508 if( DDEGETPUTITEM == r.nType )
509 s = new DdeGetPutItem( r );
510 else
511 s = new DdeItem( r );
512
513 aItems.push_back( s );
514 s->pMyTopic = this;
515 return s;
516}
517
519{
520 if( pNew )
521 {
522 aItems.push_back( pNew );
523 pNew->pMyTopic = this;
524 }
525}
526
528{
529 auto iter = std::find_if(aItems.begin(), aItems.end(),
530 [&r](const DdeItem* pItem) { return DdeCmpStringHandles(pItem->pName->getHSZ(), r.pName->getHSZ()) == 0; });
531
532 if ( iter != aItems.end() )
533 {
534 (*iter)->pMyTopic = nullptr;
535 delete *iter;
536 aItems.erase(iter);
537 }
538}
539
540void DdeTopic::NotifyClient( const OUString& rItem )
541{
542 DdeInstData* pInst = ImpGetInstData();
543 assert(pInst);
544 auto iter = std::find_if(aItems.begin(), aItems.end(),
545 [&rItem](const DdeItem* pItem) { return pItem->GetName().equals(rItem) && pItem->pImpData; });
546 if (iter != aItems.end())
547 DdePostAdvise( pInst->hDdeInstSvr, pName->getHSZ(), (*iter)->pName->getHSZ() );
548}
549
550void DdeInternal::DisconnectTopic(DdeTopic & rTopic, HCONV nId)
551{
552 for (const auto& rpItem : rTopic.aItems)
553 {
554 DecMonitor(rpItem, nId);
555 }
556}
557
559{
560 return nullptr;
561}
562
563bool DdeTopic::Put( const DdeData* )
564{
565 return false;
566}
567
568bool DdeTopic::Execute( const OUString* )
569{
570 return false;
571}
572
574{
575 return false;
576}
577
579{
580 DdeInstData* pInst = ImpGetInstData();
581 assert(pInst);
582 pName = new DdeString( pInst->hDdeInstSvr, OUString(p) );
583 nType = DDEITEM;
584 pMyTopic = nullptr;
585 pImpData = nullptr;
586}
587
588DdeItem::DdeItem( const OUString& r)
589{
590 DdeInstData* pInst = ImpGetInstData();
591 assert(pInst);
592 pName = new DdeString( pInst->hDdeInstSvr, r );
593 nType = DDEITEM;
594 pMyTopic = nullptr;
595 pImpData = nullptr;
596}
597
599{
600 DdeInstData* pInst = ImpGetInstData();
601 assert(pInst);
602 pName = new DdeString( pInst->hDdeInstSvr, r.pName->toOUString() );
603 nType = DDEITEM;
604 pMyTopic = nullptr;
605 pImpData = nullptr;
606}
607
609{
610 if( pMyTopic )
611 pMyTopic->aItems.erase(std::remove(pMyTopic->aItems.begin(),
612 pMyTopic->aItems.end(),this));
613 delete pName;
614 delete pImpData;
615}
616
617OUString DdeItem::GetName() const
618{
619 return pName->toOUString();
620}
621
623{
624 if( pMyTopic && pImpData )
625 {
626 DdeInstData* pInst = ImpGetInstData();
627 assert(pInst);
628 DdePostAdvise( pInst->hDdeInstSvr, pMyTopic->pName->getHSZ(), pName->getHSZ() );
629 }
630}
631
632void DdeInternal::IncMonitor(DdeItem *const pItem, HCONV nHCnv)
633{
634 if (!pItem->pImpData)
635 {
636 pItem->pImpData = new std::vector<DdeItemImpData>;
637 if (DDEGETPUTITEM == pItem->nType)
638 {
639 static_cast<DdeGetPutItem*>(pItem)->AdviseLoop( true );
640 }
641 }
642 else
643 {
644 for (size_t n = pItem->pImpData->size(); n; )
645 {
646 if ((*pItem->pImpData)[ --n ].nHCnv == nHCnv)
647 {
648 ++(*pItem->pImpData)[ n ].nHCnv;
649 return ;
650 }
651 }
652 }
653
654 pItem->pImpData->push_back( DdeItemImpData( nHCnv ) );
655}
656
657void DdeInternal::DecMonitor(DdeItem *const pItem, HCONV nHCnv)
658{
659 if (pItem->pImpData)
660 {
661 for( size_t n = 0; n < pItem->pImpData->size(); ++n )
662 {
663 DdeItemImpData* pData = &(*pItem->pImpData)[n];
664 if( pData->nHCnv == nHCnv )
665 {
666 if( !pData->nCnt || !--pData->nCnt )
667 {
668 if (1 < pItem->pImpData->size())
669 {
670 pItem->pImpData->erase(pItem->pImpData->begin() + n);
671 }
672 else
673 {
674 delete pItem->pImpData;
675 pItem->pImpData = nullptr;
676 if (DDEGETPUTITEM == pItem->nType)
677 {
678 static_cast<DdeGetPutItem*>(pItem)->AdviseLoop(false);
679 }
680 }
681 }
682 return ;
683 }
684 }
685 }
686}
687
689{
690 short nCnt = 0;
691 if( pImpData )
692 {
693 for (const auto& rData : *pImpData)
694 {
695 nCnt += rData.nCnt;
696 }
697 }
698 return nCnt;
699}
700
702 : DdeItem( p )
703{
704 nType = DDEGETPUTITEM;
705}
706
707DdeGetPutItem::DdeGetPutItem( const OUString& rStr )
708 : DdeItem( rStr )
709{
710 nType = DDEGETPUTITEM;
711}
712
714 : DdeItem( rItem )
715{
716 nType = DDEGETPUTITEM;
717}
718
720{
721 return nullptr;
722}
723
725{
726 return false;
727}
728
730{
731}
732
734{
735 OUString s;
736 for ( const auto& rpTopic : aTopics )
737 {
738 if ( rpTopic->GetName() == SZDDESYS_TOPIC )
739 {
740 short n = 0;
741 for ( const auto& rpItem : rpTopic->aItems )
742 {
743 if ( n )
744 s += "\t";
745 s += rpItem->GetName();
746 n++;
747 }
748 s += "\r\n";
749 }
750 }
751
752 return s;
753}
754
756{
757 OUString s;
758 short n = 0;
759
760 for ( const auto& rpTopic : aTopics )
761 {
762 if ( n )
763 s += "\t";
764 s += rpTopic->GetName();
765 n++;
766 }
767 s += "\r\n";
768
769 return s;
770}
771
773{
774 OUString s;
775 short n = 0;
776
777 for (size_t i = 0; i < aFormats.size(); ++i, ++n)
778 {
779 sal_uInt32 f = aFormats[ i ];
780 if ( n )
781 s += "\t";
782
783 switch( f )
784 {
785 case CF_TEXT:
786 s += "TEXT";
787 break;
788 case CF_BITMAP:
789 s += "BITMAP";
790 break;
791 default:
792 {
793 WCHAR buf[128];
794 GetClipboardFormatNameW( f, buf, SAL_N_ELEMENTS(buf) );
795 s += o3tl::toU(buf);
796 }
797 break;
798 }
799
800 }
801 s += "\r\n";
802
803 return s;
804}
805
807{
808 return "Ready\r\n";
809}
810
811bool DdeTopic::MakeItem( const OUString& )
812{
813 return false;
814}
815
816/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double d
SVL_DLLPRIVATE void Lock()
Definition: ddedata.cxx:81
static SotClipboardFormatId GetInternalFormat(sal_uLong nFmt)
Definition: ddedata.cxx:144
static sal_uInt32 GetExternalFormat(SotClipboardFormatId nFmt)
Definition: ddedata.cxx:124
std::unique_ptr< DdeDataImp > xImp
Definition: svdde.hxx:52
virtual void AdviseLoop(bool)
Definition: ddesvr.cxx:729
DdeGetPutItem(const sal_Unicode *p)
Definition: ddesvr.cxx:701
virtual DdeData * Get(SotClipboardFormatId)
Definition: ddesvr.cxx:719
virtual bool Put(const DdeData *)
Definition: ddesvr.cxx:724
DWORD hDdeInstSvr
Definition: ddeimp.hxx:91
sal_uInt16 nRefCount
Definition: ddeimp.hxx:88
short nInstanceSvr
Definition: ddeimp.hxx:92
DdeServices * pServicesSvr
Definition: ddeimp.hxx:93
static HDDEDATA CALLBACK SvrCallback(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, ULONG_PTR, ULONG_PTR)
Definition: ddesvr.cxx:48
static void DecMonitor(DdeItem *pItem, HCONV)
Definition: ddesvr.cxx:657
static DdeTopic * FindTopic(DdeService &, HSZ)
Definition: ddesvr.cxx:306
static DdeService * FindService(HSZ)
Definition: ddesvr.cxx:295
static void DisconnectTopic(DdeTopic &, HCONV)
Definition: ddesvr.cxx:550
static void IncMonitor(DdeItem *pItem, HCONV)
Definition: ddesvr.cxx:632
static DdeItem * FindItem(DdeTopic &, HSZ)
Definition: ddesvr.cxx:318
virtual ~DdeItem()
Definition: ddesvr.cxx:608
OUString GetName() const
Definition: ddesvr.cxx:617
DdeTopic * pMyTopic
Definition: svdde.hxx:201
std::vector< DdeItemImpData > * pImpData
Definition: svdde.hxx:202
DdeString * pName
Definition: svdde.hxx:200
DdeItem(const sal_Unicode *)
Definition: ddesvr.cxx:578
short GetLinks()
Definition: ddesvr.cxx:688
sal_uInt8 nType
Definition: svdde.hxx:205
void NotifyClient()
Definition: ddesvr.cxx:622
static DdeServices & GetServices()
Definition: ddesvr.cxx:420
std::vector< DdeTopic * > aTopics
Definition: svdde.hxx:288
void RemoveTopic(const DdeTopic &)
Definition: ddesvr.cxx:433
void AddFormat(SotClipboardFormatId)
Definition: ddesvr.cxx:461
OUString GetName() const
Definition: ddesvr.cxx:415
void AddTopic(const DdeTopic &)
Definition: ddesvr.cxx:427
OUString Formats()
Definition: ddesvr.cxx:772
OUString Topics()
Definition: ddesvr.cxx:755
SVL_DLLPRIVATE bool HasCbFormat(sal_uInt32)
Definition: ddesvr.cxx:451
OUString Status()
Definition: ddesvr.cxx:806
short nStatus
Definition: svdde.hxx:294
DdeService(SAL_UNUSED_PARAMETER const OUString &)
bool HasFormat(SotClipboardFormatId)
Definition: ddesvr.cxx:456
std::vector< std::unique_ptr< Conversation > > m_vConv
Definition: svdde.hxx:293
void RemoveFormat(SotClipboardFormatId)
Definition: ddesvr.cxx:469
OUString SysItems()
Definition: ddesvr.cxx:733
virtual ~DdeService()
Definition: ddesvr.cxx:390
std::vector< sal_uInt32 > aFormats
Definition: svdde.hxx:289
DdeString * pName
Definition: svdde.hxx:291
DdeTopic * pSysTopic
Definition: svdde.hxx:290
HSZ getHSZ()
Definition: ddestrg.cxx:42
const OUString & toOUString() const
Definition: ddeimp.hxx:71
void NotifyClient(const OUString &)
Definition: ddesvr.cxx:540
DdeString * pName
Definition: svdde.hxx:251
virtual bool MakeItem(const OUString &rItem)
Definition: ddesvr.cxx:811
std::vector< DdeItem * > aItems
Definition: svdde.hxx:253
OUString aItem
Definition: svdde.hxx:252
void RemoveItem(const DdeItem &)
Definition: ddesvr.cxx:527
virtual bool StartAdviseLoop()
Definition: ddesvr.cxx:573
DdeTopic(SAL_UNUSED_PARAMETER const OUString &)
OUString GetName() const
Definition: ddesvr.cxx:495
bool IsSystemTopic()
Definition: ddesvr.cxx:500
virtual bool Put(const DdeData *)
Definition: ddesvr.cxx:563
virtual bool Execute(const OUString *)
Definition: ddesvr.cxx:568
DdeItem * AddItem(const DdeItem &)
Definition: ddesvr.cxx:505
friend class DdeItem
Definition: svdde.hxx:248
virtual ~DdeTopic()
Definition: ddesvr.cxx:484
virtual DdeData * Get(SotClipboardFormatId)
Definition: ddesvr.cxx:558
void InsertItem(DdeItem *)
Definition: ddesvr.cxx:518
void ImpDeinitInstData()
Definition: ddecli.cxx:45
DdeInstData * ImpInitInstData()
Definition: ddecli.cxx:39
DdeInstData * ImpGetInstData()
Definition: ddecli.cxx:34
SotClipboardFormatId
#define TRUE
OUString aName
void * p
sal_Int64 n
#define SAL_N_ELEMENTS(arr)
std::unique_ptr< sal_Int32[]> pData
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
int i
Put
sal_Int32 h
#define CALLBACK
sal_Int16 nId
#define HCONV(x)
DdeTopic * pTopic
Definition: ddeimp.hxx:37
HCONV hConv
Definition: ddeimp.hxx:36
DdeItemImpData(HCONV nH)
Definition: ddesvr.cxx:45
sal_uInt16 nCnt
Definition: ddesvr.cxx:43
HCONV nHCnv
Definition: ddesvr.cxx:42
::std::vector< DdeService * > DdeServices
Definition: svdde.hxx:41
sal_uInt16 sal_Unicode