1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svl.hxx" 30 31 #define UNICODE 32 #include "ddeimp.hxx" 33 #include <svl/svdde.hxx> 34 #include <svl/svarray.hxx> 35 #include <tools/debug.hxx> 36 #include <osl/thread.h> 37 38 //static long hCurConv = 0; 39 //static DWORD hDdeInst = NULL; 40 //static short nInstance = 0; 41 //static DdeServices* pServices; 42 43 enum DdeItemType 44 { 45 DDEITEM, 46 DDEGETPUTITEM 47 }; 48 49 struct DdeItemImpData 50 { 51 sal_uLong nHCnv; 52 sal_uInt16 nCnt; 53 54 DdeItemImpData( sal_uLong nH ) : nHCnv( nH ), nCnt( 1 ) {} 55 }; 56 57 SV_DECL_VARARR( DdeItemImp, DdeItemImpData, 1, 1 ) 58 SV_IMPL_VARARR( DdeItemImp, DdeItemImpData ) 59 60 // --- DdeInternat::SvrCallback() ---------------------------------- 61 62 #ifdef WNT 63 HDDEDATA CALLBACK DdeInternal::SvrCallback( 64 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2, 65 HDDEDATA hData, DWORD, DWORD ) 66 #else 67 #if defined ( MTW ) || ( defined ( GCC ) && defined ( OS2 )) || defined( ICC ) 68 HDDEDATA CALLBACK __EXPORT DdeInternal::SvrCallback( 69 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2, 70 HDDEDATA hData, DWORD, DWORD ) 71 #else 72 HDDEDATA CALLBACK _export DdeInternal::SvrCallback( 73 WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2, 74 HDDEDATA hData, DWORD, DWORD ) 75 #endif 76 #endif 77 { 78 DdeServices& rAll = DdeService::GetServices(); 79 DdeService* pService; 80 DdeTopic* pTopic; 81 DdeItem* pItem; 82 DdeData* pData; 83 Conversation* pC; 84 85 DdeInstData* pInst = ImpGetInstData(); 86 DBG_ASSERT(pInst,"SVDDE:No instance data"); 87 88 switch( nCode ) 89 { 90 case XTYP_WILDCONNECT: 91 { 92 int nTopics = 0; 93 94 #if 1 95 TCHAR chTopicBuf[250]; 96 if( hText1 ) 97 DdeQueryString( pInst->hDdeInstSvr, hText1, chTopicBuf, 98 sizeof(chTopicBuf)/sizeof(TCHAR), CP_WINUNICODE ); 99 100 for( pService = rAll.First();pService;pService = rAll.Next() ) 101 { 102 if ( !hText2 || ( *pService->pName == hText2 ) ) 103 { 104 String sTopics( pService->Topics() ); 105 if( sTopics.Len() ) 106 { 107 if( hText1 ) 108 { 109 sal_uInt16 n = 0; 110 while( STRING_NOTFOUND != n ) 111 { 112 String s( sTopics.GetToken( 0, '\t', n )); 113 if( s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) ) 114 ++nTopics; 115 } 116 } 117 else 118 nTopics += sTopics.GetTokenCount( '\t' ); 119 } 120 } 121 } 122 123 #else 124 for( pService = rAll.First();pService;pService = rAll.Next() ) 125 { 126 if ( !hText2 || ( *pService->pName == hText2 ) ) 127 { 128 for( pTopic = pService->aTopics.First(); pTopic; 129 pTopic = pService->aTopics.Next() ) 130 { 131 if ( !hText1 || (*pTopic->pName == hText1) ) 132 nTopics++; 133 } 134 } 135 } 136 #endif 137 if( !nTopics ) 138 return (HDDEDATA)NULL; 139 140 HSZPAIR* pPairs = new HSZPAIR [nTopics + 1]; 141 if ( !pPairs ) 142 return (HDDEDATA)NULL; 143 144 HSZPAIR* q = pPairs; 145 for( pService = rAll.First(); pService; pService = rAll.Next() ) 146 { 147 if ( !hText2 || (*pService->pName == hText2 ) ) 148 { 149 #if 0 150 for ( pTopic = pService->aTopics.First(); pTopic; 151 pTopic = pService->aTopics.Next() ) 152 { 153 if ( !hText1 || (*pTopic->pName == hText1) ) 154 { 155 q->hszSvc = *pService->pName; 156 q->hszTopic = *pTopic->pName; 157 q++; 158 } 159 } 160 #else 161 String sTopics( pService->Topics() ); 162 sal_uInt16 n = 0; 163 while( STRING_NOTFOUND != n ) 164 { 165 String s( sTopics.GetToken( 0, '\t', n )); 166 s.EraseAllChars( '\n' ).EraseAllChars( '\r' ); 167 if( !hText1 || s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) ) 168 { 169 DdeString aDStr( pInst->hDdeInstSvr, s ); 170 pTopic = FindTopic( *pService, (HSZ)aDStr ); 171 if( pTopic ) 172 { 173 q->hszSvc = *pService->pName; 174 q->hszTopic = *pTopic->pName; 175 q++; 176 } 177 } 178 } 179 180 #endif 181 } 182 } 183 184 q->hszSvc = NULL; 185 q->hszTopic = NULL; 186 HDDEDATA h = DdeCreateDataHandle( 187 pInst->hDdeInstSvr, (LPBYTE) pPairs, 188 sizeof(HSZPAIR) * (nTopics+1), 189 0, NULL, nCbType, 0); 190 delete [] pPairs; 191 return h; 192 } 193 194 case XTYP_CONNECT: 195 pService = FindService( hText2 ); 196 if ( pService) 197 pTopic = FindTopic( *pService, hText1 ); 198 else 199 pTopic = NULL; 200 if ( pTopic ) 201 return (HDDEDATA)DDE_FACK; 202 else 203 return (HDDEDATA) NULL; 204 205 case XTYP_CONNECT_CONFIRM: 206 pService = FindService( hText2 ); 207 if ( pService ) 208 { 209 pTopic = FindTopic( *pService, hText1 ); 210 if ( pTopic ) 211 { 212 pTopic->Connect( (long) hConv ); 213 pC = new Conversation; 214 pC->hConv = hConv; 215 pC->pTopic = pTopic; 216 pService->pConv->Insert( pC ); 217 } 218 } 219 return (HDDEDATA)NULL; 220 } 221 222 for ( pService = rAll.First(); pService; pService = rAll.Next() ) 223 { 224 for( pC = pService->pConv->First(); pC; 225 pC = pService->pConv->Next() ) 226 { 227 if ( pC->hConv == hConv ) 228 goto found; 229 } 230 } 231 232 return (HDDEDATA) DDE_FNOTPROCESSED; 233 234 found: 235 if ( nCode == XTYP_DISCONNECT) 236 { 237 pC->pTopic->_Disconnect( (long) hConv ); 238 pService->pConv->Remove( pC ); 239 delete pC; 240 return (HDDEDATA)NULL; 241 } 242 243 sal_Bool bExec = sal_Bool(nCode == XTYP_EXECUTE); 244 pTopic = pC->pTopic; 245 if ( pTopic && !bExec ) 246 pItem = FindItem( *pTopic, hText2 ); 247 else 248 pItem = NULL; 249 250 if ( !bExec && !pService->HasCbFormat( nCbType ) ) 251 pItem = NULL; 252 if ( !pItem && !bExec ) 253 return (HDDEDATA)DDE_FNOTPROCESSED; 254 if ( pItem ) 255 pTopic->aItem = pItem->GetName(); 256 else 257 pTopic->aItem.Erase(); 258 259 sal_Bool bRes = sal_False; 260 pInst->hCurConvSvr = (long)hConv; 261 switch( nCode ) 262 { 263 case XTYP_REQUEST: 264 case XTYP_ADVREQ: 265 { 266 String aRes; // darf erst am Ende freigegeben werden!! 267 if ( pTopic->IsSystemTopic() ) 268 { 269 if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) 270 aRes = pService->Topics(); 271 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) 272 aRes = pService->SysItems(); 273 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) 274 aRes = pService->Status(); 275 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) 276 aRes = pService->Formats(); 277 else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) 278 aRes = pService->GetHelp(); 279 else 280 aRes = pService->SysTopicGet( pTopic->aItem ); 281 282 if ( aRes.Len() ) 283 pData = new DdeData( aRes ); 284 else 285 pData = NULL; 286 } 287 else if( DDEGETPUTITEM == pItem->nType ) 288 pData = ((DdeGetPutItem*)pItem)->Get( 289 DdeData::GetInternalFormat( nCbType ) ); 290 else 291 pData = pTopic->Get( DdeData::GetInternalFormat( nCbType )); 292 293 if ( pData ) 294 return DdeCreateDataHandle( pInst->hDdeInstSvr, 295 (LPBYTE)pData->pImp->pData, 296 pData->pImp->nData, 297 0, hText2, 298 DdeData::GetExternalFormat( 299 pData->pImp->nFmt ), 300 0 ); 301 } 302 break; 303 304 case XTYP_POKE: 305 if ( !pTopic->IsSystemTopic() ) 306 { 307 DdeData d; 308 d.pImp->hData = hData; 309 d.pImp->nFmt = DdeData::GetInternalFormat( nCbType ); 310 d.Lock(); 311 if( DDEGETPUTITEM == pItem->nType ) 312 bRes = ((DdeGetPutItem*)pItem)->Put( &d ); 313 else 314 bRes = pTopic->Put( &d ); 315 } 316 pInst->hCurConvSvr = NULL; 317 if ( bRes ) 318 return (HDDEDATA)DDE_FACK; 319 else 320 return (HDDEDATA) DDE_FNOTPROCESSED; 321 322 case XTYP_ADVSTART: 323 { 324 // wird das Item zum erstenmal ein HotLink ? 325 if( !pItem->pImpData && pTopic->StartAdviseLoop() ) 326 { 327 // dann wurde das Item ausgewechselt 328 pTopic->aItems.Remove( pItem ); 329 DdeItem* pTmp; 330 for( pTmp = pTopic->aItems.First(); pTmp; 331 pTmp = pTopic->aItems.Next() ) 332 if( *pTmp->pName == hText2 ) 333 { 334 // es wurde tatsaechlich ausgewechselt 335 delete pItem; 336 pItem = 0; 337 break; 338 } 339 if( pItem ) 340 // es wurde doch nicht ausgewechselt, also wieder rein 341 pTopic->aItems.Insert( pItem ); 342 else 343 pItem = pTmp; 344 } 345 pItem->IncMonitor( (long)hConv ); 346 pInst->hCurConvSvr = NULL; 347 } 348 return (HDDEDATA)sal_True; 349 350 case XTYP_ADVSTOP: 351 pItem->DecMonitor( (long)hConv ); 352 if( !pItem->pImpData ) 353 pTopic->StopAdviseLoop(); 354 pInst->hCurConvSvr = NULL; 355 return (HDDEDATA)sal_True; 356 357 case XTYP_EXECUTE: 358 { 359 DdeData aExec; 360 aExec.pImp->hData = hData; 361 aExec.pImp->nFmt = DdeData::GetInternalFormat( nCbType ); 362 aExec.Lock(); 363 String aName; 364 365 aName = (const sal_Unicode *)aExec.pImp->pData; 366 367 if( pTopic->IsSystemTopic() ) 368 bRes = pService->SysTopicExecute( &aName ); 369 else 370 bRes = pTopic->Execute( &aName ); 371 } 372 pInst->hCurConvSvr = NULL; 373 if ( bRes ) 374 return (HDDEDATA)DDE_FACK; 375 else 376 return (HDDEDATA)DDE_FNOTPROCESSED; 377 } 378 379 return (HDDEDATA)NULL; 380 } 381 382 // --- DdeInternat::FindService() ---------------------------------- 383 384 DdeService* DdeInternal::FindService( HSZ hService ) 385 { 386 DdeService* s; 387 DdeServices& rSvc = DdeService::GetServices(); 388 for ( s = rSvc.First(); s; s = rSvc.Next() ) 389 { 390 if ( *s->pName == hService ) 391 return s; 392 } 393 394 return NULL; 395 } 396 397 // --- DdeInternat::FindTopic() ------------------------------------ 398 399 DdeTopic* DdeInternal::FindTopic( DdeService& rService, HSZ hTopic ) 400 { 401 DdeTopic* s; 402 DdeTopics& rTopics = rService.aTopics; 403 int bWeiter = sal_False; 404 DdeInstData* pInst = ImpGetInstData(); 405 DBG_ASSERT(pInst,"SVDDE:No instance data"); 406 407 do { // middle check loop 408 for ( s = rTopics.First(); s; s = rTopics.Next() ) 409 { 410 if ( *s->pName == hTopic ) 411 return s; 412 } 413 414 bWeiter = !bWeiter; 415 if( !bWeiter ) 416 break; 417 418 // dann befragen wir doch mal unsere Ableitung: 419 TCHAR chBuf[250]; 420 DdeQueryString(pInst->hDdeInstSvr,hTopic,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE ); 421 bWeiter = rService.MakeTopic( reinterpret_cast<const sal_Unicode*>(chBuf) ); 422 // dann muessen wir noch mal suchen 423 } while( bWeiter ); 424 425 return 0; 426 } 427 428 // --- DdeInternal::FindItem() ------------------------------------- 429 430 DdeItem* DdeInternal::FindItem( DdeTopic& rTopic, HSZ hItem ) 431 { 432 DdeItem* s; 433 DdeItems& rItems = rTopic.aItems; 434 DdeInstData* pInst = ImpGetInstData(); 435 DBG_ASSERT(pInst,"SVDDE:No instance data"); 436 int bWeiter = sal_False; 437 438 do { // middle check loop 439 440 for ( s = rItems.First(); s; s = rItems.Next() ) 441 if ( *s->pName == hItem ) 442 return s; 443 444 bWeiter = !bWeiter; 445 if( !bWeiter ) 446 break; 447 448 // dann befragen wir doch mal unsere Ableitung: 449 TCHAR chBuf[250]; 450 DdeQueryString(pInst->hDdeInstSvr,hItem,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE ); 451 bWeiter = rTopic.MakeItem( reinterpret_cast<const sal_Unicode*>(chBuf) ); 452 // dann muessen wir noch mal suchen 453 } while( bWeiter ); 454 455 return 0; 456 } 457 458 // --- DdeService::DdeService() ------------------------------------ 459 460 DdeService::DdeService( const String& rService ) 461 { 462 DdeInstData* pInst = ImpGetInstData(); 463 if( !pInst ) 464 pInst = ImpInitInstData(); 465 pInst->nRefCount++; 466 pInst->nInstanceSvr++; 467 468 if ( !pInst->hDdeInstSvr ) 469 { 470 nStatus = sal::static_int_cast< short >( 471 DdeInitialize( &pInst->hDdeInstSvr, 472 (PFNCALLBACK)DdeInternal::SvrCallback, 473 APPCLASS_STANDARD | 474 CBF_SKIP_REGISTRATIONS | 475 CBF_SKIP_UNREGISTRATIONS, 0L ) ); 476 pInst->pServicesSvr = new DdeServices; 477 } 478 else 479 nStatus = DMLERR_NO_ERROR; 480 481 pConv = new ConvList; 482 483 if ( pInst->pServicesSvr ) 484 pInst->pServicesSvr->Insert( this ); 485 486 pName = new DdeString( pInst->hDdeInstSvr, rService ); 487 if ( nStatus == DMLERR_NO_ERROR ) 488 if ( !DdeNameService( pInst->hDdeInstSvr, *pName, NULL, 489 DNS_REGISTER | DNS_FILTEROFF ) ) 490 nStatus = DMLERR_SYS_ERROR; 491 492 AddFormat( FORMAT_STRING ); 493 pSysTopic = new DdeTopic( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) ); 494 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) ); 495 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) ); 496 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) ); 497 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) ); 498 pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) ); 499 AddTopic( *pSysTopic ); 500 } 501 502 // --- DdeService::~DdeService() ----------------------------------- 503 504 DdeService::~DdeService() 505 { 506 DdeInstData* pInst = ImpGetInstData(); 507 DBG_ASSERT(pInst,"SVDDE:No instance data"); 508 if ( pInst->pServicesSvr ) 509 pInst->pServicesSvr->Remove( this ); 510 511 // MT: Im Auftrage des Herrn (AM) auskommentiert... 512 // Grund: 513 // Bei Client/Server werden die Server nicht beendet, wenn mehr 514 // als einer gestartet. 515 // Weil keine System-Messagequeue ?! 516 517 delete pSysTopic; 518 delete pName; 519 520 pInst->nInstanceSvr--; 521 pInst->nRefCount--; 522 if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr ) 523 { 524 if( DdeUninitialize( pInst->hDdeInstSvr ) ) 525 { 526 pInst->hDdeInstSvr = NULL; 527 delete pInst->pServicesSvr; 528 pInst->pServicesSvr = NULL; 529 if( pInst->nRefCount == 0) 530 ImpDeinitInstData(); 531 } 532 } 533 delete pConv; 534 } 535 536 // --- DdeService::GetName() --------------------------------------- 537 538 const String& DdeService::GetName() const 539 { 540 return *pName; 541 } 542 543 // --- DdeService::GetServices() ----------------------------------- 544 545 DdeServices& DdeService::GetServices() 546 { 547 DdeInstData* pInst = ImpGetInstData(); 548 DBG_ASSERT(pInst,"SVDDE:No instance data"); 549 return *(pInst->pServicesSvr); 550 } 551 552 // --- DdeService::AddTopic() -------------------------------------- 553 554 void DdeService::AddTopic( const DdeTopic& rTopic ) 555 { 556 RemoveTopic( rTopic ); 557 aTopics.Insert( (DdeTopic*) &rTopic ); 558 } 559 560 // --- DdeService::RemoveTopic() ----------------------------------- 561 562 void DdeService::RemoveTopic( const DdeTopic& rTopic ) 563 { 564 DdeTopic* t; 565 for ( t = aTopics.First(); t; t = aTopics.Next() ) 566 { 567 if ( !DdeCmpStringHandles (*t->pName, *rTopic.pName ) ) 568 { 569 aTopics.Remove( t ); 570 // JP 27.07.95: und alle Conversions loeschen !!! 571 // (sonst wird auf geloeschten Topics gearbeitet!!) 572 for( sal_uLong n = pConv->Count(); n; ) 573 { 574 Conversation* pC = pConv->GetObject( --n ); 575 if( pC->pTopic == &rTopic ) 576 { 577 pConv->Remove( pC ); 578 delete pC; 579 } 580 } 581 break; 582 } 583 } 584 } 585 586 // --- DdeService::HasCbFormat() ----------------------------------- 587 588 sal_Bool DdeService::HasCbFormat( sal_uInt16 nFmt ) 589 { 590 return sal_Bool( aFormats.GetPos( nFmt ) != LIST_ENTRY_NOTFOUND ); 591 } 592 593 // --- DdeService::HasFormat() ------------------------------------- 594 595 sal_Bool DdeService::HasFormat( sal_uLong nFmt ) 596 { 597 return HasCbFormat( (sal_uInt16)DdeData::GetExternalFormat( nFmt )); 598 } 599 600 // --- DdeService::AddFormat() ------------------------------------- 601 602 void DdeService::AddFormat( sal_uLong nFmt ) 603 { 604 nFmt = DdeData::GetExternalFormat( nFmt ); 605 aFormats.Remove( nFmt ); 606 aFormats.Insert( nFmt ); 607 } 608 609 // --- DdeService::RemoveFormat() ---------------------------------- 610 611 void DdeService::RemoveFormat( sal_uLong nFmt ) 612 { 613 aFormats.Remove( DdeData::GetExternalFormat( nFmt ) ); 614 } 615 616 // --- DdeTopic::DdeTopic() ---------------------------------------- 617 618 DdeTopic::DdeTopic( const String& rName ) 619 { 620 DdeInstData* pInst = ImpGetInstData(); 621 DBG_ASSERT(pInst,"SVDDE:No instance data"); 622 pName = new DdeString( pInst->hDdeInstSvr, rName ); 623 } 624 625 // --- DdeTopic::~DdeTopic() --------------------------------------- 626 627 DdeTopic::~DdeTopic() 628 { 629 DdeItem* t; 630 while( ( t = aItems.First() ) != NULL ) 631 { 632 aItems.Remove( t ); 633 t->pMyTopic = 0; 634 delete t; 635 } 636 delete pName; 637 } 638 639 // --- DdeTopic::GetName() ----------------------------------------- 640 641 const String& DdeTopic::GetName() const 642 { 643 return *pName; 644 } 645 646 // --- DdeTopic::IsSystemTopic() ----------------------------------- 647 648 sal_Bool DdeTopic::IsSystemTopic() 649 { 650 return sal_Bool (GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC)); 651 } 652 653 // --- DdeTopic::AddItem() ----------------------------------------- 654 655 DdeItem* DdeTopic::AddItem( const DdeItem& r ) 656 { 657 DdeItem* s; 658 if( DDEGETPUTITEM == r.nType ) 659 s = new DdeGetPutItem( r ); 660 else 661 s = new DdeItem( r ); 662 if ( s ) 663 { 664 aItems.Insert( s ); 665 s->pMyTopic = this; 666 } 667 return s; 668 } 669 670 // --- DdeTopic::InsertItem() ----------------------------------------- 671 672 void DdeTopic::InsertItem( DdeItem* pNew ) 673 { 674 if( pNew ) 675 { 676 aItems.Insert( pNew ); 677 pNew->pMyTopic = this; 678 } 679 } 680 681 // --- DdeTopic::RemoveItem() -------------------------------------- 682 683 void DdeTopic::RemoveItem( const DdeItem& r ) 684 { 685 DdeItem* s; 686 for ( s = aItems.First(); s; s = aItems.Next() ) 687 { 688 if ( !DdeCmpStringHandles (*s->pName, *r.pName ) ) 689 break; 690 } 691 692 if ( s ) 693 { 694 aItems.Remove( s ); 695 s->pMyTopic = 0; 696 delete s; 697 } 698 } 699 700 // --- DdeTopic::NotifyClient() ------------------------------------ 701 702 void DdeTopic::NotifyClient( const String& rItem ) 703 { 704 DdeItem* pItem; 705 DdeInstData* pInst = ImpGetInstData(); 706 DBG_ASSERT(pInst,"SVDDE:No instance data"); 707 for ( pItem = aItems.First(); pItem; pItem = aItems.Next() ) 708 { 709 if ( pItem->GetName() == rItem ) 710 { 711 if ( pItem->pImpData ) 712 DdePostAdvise( pInst->hDdeInstSvr, *pName, *pItem->pName ); 713 } 714 break; 715 } 716 } 717 718 // --- DdeTopic::Connect() ----------------------------------------- 719 720 void __EXPORT DdeTopic::Connect( long nId ) 721 { 722 aConnectLink.Call( (void*)nId ); 723 } 724 725 // --- DdeTopic::Disconnect() -------------------------------------- 726 727 void __EXPORT DdeTopic::Disconnect( long nId ) 728 { 729 aDisconnectLink.Call( (void*)nId ); 730 } 731 732 // --- DdeTopic::_Disconnect() -------------------------------------- 733 734 void __EXPORT DdeTopic::_Disconnect( long nId ) 735 { 736 for( DdeItem* pItem = aItems.First(); pItem; pItem = aItems.Next() ) 737 pItem->DecMonitor( nId ); 738 739 Disconnect( nId ); 740 } 741 742 // --- DdeTopic::Get() --------------------------------------------- 743 744 DdeData* __EXPORT DdeTopic::Get( sal_uLong nFmt ) 745 { 746 if ( aGetLink.IsSet() ) 747 return (DdeData*)aGetLink.Call( (void*)nFmt ); 748 else 749 return NULL; 750 } 751 752 // --- DdeTopic::Put() --------------------------------------------- 753 754 sal_Bool __EXPORT DdeTopic::Put( const DdeData* r ) 755 { 756 if ( aPutLink.IsSet() ) 757 return (sal_Bool)aPutLink.Call( (void*) r ); 758 else 759 return sal_False; 760 } 761 762 // --- DdeTopic::Execute() ----------------------------------------- 763 764 sal_Bool __EXPORT DdeTopic::Execute( const String* r ) 765 { 766 if ( aExecLink.IsSet() ) 767 return (sal_Bool)aExecLink.Call( (void*)r ); 768 else 769 return sal_False; 770 } 771 772 // --- DdeTopic::GetConvId() --------------------------------------- 773 774 long DdeTopic::GetConvId() 775 { 776 DdeInstData* pInst = ImpGetInstData(); 777 DBG_ASSERT(pInst,"SVDDE:No instance data"); 778 return pInst->hCurConvSvr; 779 } 780 781 // --- DdeTopic::StartAdviseLoop() --------------------------------- 782 783 sal_Bool DdeTopic::StartAdviseLoop() 784 { 785 return sal_False; 786 } 787 788 // --- DdeTopic::StopAdviseLoop() ---------------------------------- 789 790 sal_Bool DdeTopic::StopAdviseLoop() 791 { 792 return sal_False; 793 } 794 795 // --- DdeItem::DdeItem() ------------------------------------------ 796 797 DdeItem::DdeItem( const sal_Unicode* p ) 798 { 799 DdeInstData* pInst = ImpGetInstData(); 800 DBG_ASSERT(pInst,"SVDDE:No instance data"); 801 pName = new DdeString( pInst->hDdeInstSvr, p ); 802 nType = DDEITEM; 803 pMyTopic = 0; 804 pImpData = 0; 805 } 806 807 // --- DdeItem::DdeItem() ------------------------------------------ 808 809 DdeItem::DdeItem( const String& r) 810 { 811 DdeInstData* pInst = ImpGetInstData(); 812 DBG_ASSERT(pInst,"SVDDE:No instance data"); 813 pName = new DdeString( pInst->hDdeInstSvr, r ); 814 nType = DDEITEM; 815 pMyTopic = 0; 816 pImpData = 0; 817 } 818 819 // --- DdeItem::DdeItem() ------------------------------------------ 820 821 DdeItem::DdeItem( const DdeItem& r) 822 { 823 DdeInstData* pInst = ImpGetInstData(); 824 DBG_ASSERT(pInst,"SVDDE:No instance data"); 825 pName = new DdeString( pInst->hDdeInstSvr, *r.pName ); 826 nType = DDEITEM; 827 pMyTopic = 0; 828 pImpData = 0; 829 } 830 831 // --- DdeItem::~DdeItem() ----------------------------------------- 832 833 DdeItem::~DdeItem() 834 { 835 if( pMyTopic ) 836 pMyTopic->aItems.Remove( this ); 837 delete pName; 838 delete pImpData; 839 } 840 841 // --- DdeItem::GetName() ------------------------------------------ 842 843 const String& DdeItem::GetName() const 844 { 845 return *pName; 846 } 847 848 // --- DdeItem::NotifyClient() ------------------------------------------ 849 850 void DdeItem::NotifyClient() 851 { 852 if( pMyTopic && pImpData ) 853 { 854 DdeInstData* pInst = ImpGetInstData(); 855 DBG_ASSERT(pInst,"SVDDE:No instance data"); 856 DdePostAdvise( pInst->hDdeInstSvr, *pMyTopic->pName, *pName ); 857 } 858 } 859 860 // --- DdeItem::IncMonitor() ------------------------------------------ 861 862 void DdeItem::IncMonitor( sal_uLong nHCnv ) 863 { 864 if( !pImpData ) 865 { 866 pImpData = new DdeItemImp; 867 if( DDEGETPUTITEM == nType ) 868 ((DdeGetPutItem*)this)->AdviseLoop( sal_True ); 869 } 870 else 871 { 872 for( sal_uInt16 n = pImpData->Count(); n; ) 873 if( (*pImpData)[ --n ].nHCnv == nHCnv ) 874 { 875 ++(*pImpData)[ n ].nHCnv; 876 return ; 877 } 878 } 879 880 pImpData->Insert( DdeItemImpData( nHCnv ), pImpData->Count() ); 881 } 882 883 // --- DdeItem::DecMonitor() ------------------------------------------ 884 885 void DdeItem::DecMonitor( sal_uLong nHCnv ) 886 { 887 if( pImpData ) 888 { 889 DdeItemImpData* pData = (DdeItemImpData*)pImpData->GetData(); 890 for( sal_uInt16 n = pImpData->Count(); n; --n, ++pData ) 891 if( pData->nHCnv == nHCnv ) 892 { 893 if( !pData->nCnt || !--pData->nCnt ) 894 { 895 if( 1 < pImpData->Count() ) 896 pImpData->Remove( pImpData->Count() - n ); 897 else 898 { 899 delete pImpData, pImpData = 0; 900 if( DDEGETPUTITEM == nType ) 901 ((DdeGetPutItem*)this)->AdviseLoop( sal_False ); 902 } 903 } 904 return ; 905 } 906 } 907 } 908 909 // --- DdeItem::GetLinks() ------------------------------------------ 910 911 short DdeItem::GetLinks() 912 { 913 short nCnt = 0; 914 if( pImpData ) 915 for( sal_uInt16 n = pImpData->Count(); n; ) 916 nCnt = nCnt + (*pImpData)[ --n ].nCnt; 917 return nCnt; 918 } 919 920 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------ 921 922 DdeGetPutItem::DdeGetPutItem( const sal_Unicode* p ) 923 : DdeItem( p ) 924 { 925 nType = DDEGETPUTITEM; 926 } 927 928 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------ 929 930 DdeGetPutItem::DdeGetPutItem( const String& rStr ) 931 : DdeItem( rStr ) 932 { 933 nType = DDEGETPUTITEM; 934 } 935 936 // --- DdeGetPutItem::DdeGetPutItem() ------------------------------ 937 938 DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem ) 939 : DdeItem( rItem ) 940 { 941 nType = DDEGETPUTITEM; 942 } 943 944 945 // --- DdeGetPutData::Get() ---------------------------------------- 946 947 DdeData* DdeGetPutItem::Get( sal_uLong ) 948 { 949 return 0; 950 } 951 952 // --- DdeGetPutData::Put() ---------------------------------------- 953 954 sal_Bool DdeGetPutItem::Put( const DdeData* ) 955 { 956 return sal_False; 957 } 958 959 // --- DdeGetPutData::AdviseLoop() --------------------------------- 960 961 void DdeGetPutItem::AdviseLoop( sal_Bool ) 962 { 963 } 964 965 966 // --- DdeService::SysItems() -------------------------------------- 967 968 String DdeService::SysItems() 969 { 970 String s; 971 DdeTopic* t; 972 for ( t = aTopics.First(); t; t = aTopics.Next() ) 973 { 974 if ( t->GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) ) 975 { 976 short n = 0; 977 DdeItem* pi; 978 for ( pi = t->aItems.First(); pi; pi = t->aItems.Next(), n++ ) 979 { 980 if ( n ) 981 s += '\t'; 982 s += pi->GetName(); 983 } 984 s += String::CreateFromAscii("\r\n"); 985 } 986 } 987 988 return s; 989 } 990 991 // --- DdeService::Topics() ---------------------------------------- 992 993 String DdeService::Topics() 994 { 995 String s; 996 DdeTopic* t; 997 short n = 0; 998 999 for ( t = aTopics.First(); t; t = aTopics.Next(), n++ ) 1000 { 1001 if ( n ) 1002 s += '\t'; 1003 s += t->GetName(); 1004 } 1005 s += String::CreateFromAscii("\r\n"); 1006 1007 return s; 1008 } 1009 1010 // --- DdeService::Formats() --------------------------------------- 1011 1012 String DdeService::Formats() 1013 { 1014 String s; 1015 long f; 1016 TCHAR buf[128]; 1017 LPCTSTR p; 1018 short n = 0; 1019 1020 for ( f = aFormats.First(); f; f = aFormats.Next(), n++ ) 1021 { 1022 if ( n ) 1023 s += '\t'; 1024 p = buf; 1025 1026 switch( (sal_uInt16)f ) 1027 { 1028 case CF_TEXT: 1029 p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("TEXT").GetBuffer()); 1030 break; 1031 case CF_BITMAP: 1032 p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("BITMAP").GetBuffer()); 1033 break; 1034 #ifdef OS2 1035 case CF_DSPTEXT: 1036 p = String::CreateFromAscii("TEXT").GetBuffer(); 1037 break; 1038 case CF_DSPBITMAP: 1039 p = String::CreateFromAscii("BITMAP").GetBuffer(); 1040 break; 1041 case CF_METAFILE: 1042 p = String::CreateFromAscii("METAFILE").GetBuffer(); 1043 break; 1044 case CF_DSPMETAFILE: 1045 p = String::CreateFromAscii("METAFILE").GetBuffer(); 1046 break; 1047 case CF_PALETTE: 1048 p = String::CreateFromAscii("PALETTE").GetBuffer(); 1049 break; 1050 default: 1051 p= String::CreateFromAscii("PRIVATE").GetBuffer(); 1052 #else 1053 default: 1054 GetClipboardFormatName( (UINT)f, buf, sizeof(buf) / sizeof(TCHAR) ); 1055 #endif 1056 } 1057 s += String( reinterpret_cast<const sal_Unicode*>(p) ); 1058 } 1059 s += String::CreateFromAscii("\r\n"); 1060 1061 return s; 1062 } 1063 1064 // --- DdeService::Status() ---------------------------------------- 1065 1066 String DdeService::Status() 1067 { 1068 return IsBusy() ? String::CreateFromAscii("Busy\r\n") : String::CreateFromAscii("Ready\r\n"); 1069 } 1070 1071 // --- DdeService::IsBusy() ---------------------------------------- 1072 1073 sal_Bool __EXPORT DdeService::IsBusy() 1074 { 1075 return sal_False; 1076 } 1077 1078 // --- DdeService::GetHelp() ---------------------------------------- 1079 1080 String __EXPORT DdeService::GetHelp() 1081 { 1082 return String(); 1083 } 1084 1085 sal_Bool DdeTopic::MakeItem( const String& ) 1086 { 1087 return sal_False; 1088 } 1089 1090 sal_Bool DdeService::MakeTopic( const String& ) 1091 { 1092 return sal_False; 1093 } 1094 1095 String DdeService::SysTopicGet( const String& ) 1096 { 1097 return String(); 1098 } 1099 1100 sal_Bool DdeService::SysTopicExecute( const String* ) 1101 { 1102 return sal_False; 1103 } 1104 1105