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