blob: 0335c7af2102372ea514b1c7aa87ad1c1c041927 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svl.hxx"
#define UNICODE
#include "ddeimp.hxx"
#include <svl/svdde.hxx>
#include <svl/svarray.hxx>
#include <tools/debug.hxx>
#include <osl/thread.h>
//static long hCurConv = 0;
//static DWORD hDdeInst = NULL;
//static short nInstance = 0;
//static DdeServices* pServices;
enum DdeItemType
{
DDEITEM,
DDEGETPUTITEM
};
struct DdeItemImpData
{
sal_uLong nHCnv;
sal_uInt16 nCnt;
DdeItemImpData( sal_uLong nH ) : nHCnv( nH ), nCnt( 1 ) {}
};
SV_DECL_VARARR( DdeItemImp, DdeItemImpData, 1, 1 )
SV_IMPL_VARARR( DdeItemImp, DdeItemImpData )
// --- DdeInternat::SvrCallback() ----------------------------------
#ifdef WNT
HDDEDATA CALLBACK DdeInternal::SvrCallback(
WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
HDDEDATA hData, DWORD, DWORD )
#else
#if defined ( MTW ) || ( defined ( GCC ) && defined ( OS2 )) || defined( ICC )
HDDEDATA CALLBACK __EXPORT DdeInternal::SvrCallback(
WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
HDDEDATA hData, DWORD, DWORD )
#else
HDDEDATA CALLBACK _export DdeInternal::SvrCallback(
WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2,
HDDEDATA hData, DWORD, DWORD )
#endif
#endif
{
DdeServices& rAll = DdeService::GetServices();
DdeService* pService;
DdeTopic* pTopic;
DdeItem* pItem;
DdeData* pData;
Conversation* pC;
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
switch( nCode )
{
case XTYP_WILDCONNECT:
{
int nTopics = 0;
#if 1
TCHAR chTopicBuf[250];
if( hText1 )
DdeQueryString( pInst->hDdeInstSvr, hText1, chTopicBuf,
sizeof(chTopicBuf)/sizeof(TCHAR), CP_WINUNICODE );
for( pService = rAll.First();pService;pService = rAll.Next() )
{
if ( !hText2 || ( *pService->pName == hText2 ) )
{
String sTopics( pService->Topics() );
if( sTopics.Len() )
{
if( hText1 )
{
sal_uInt16 n = 0;
while( STRING_NOTFOUND != n )
{
String s( sTopics.GetToken( 0, '\t', n ));
if( s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
++nTopics;
}
}
else
nTopics += sTopics.GetTokenCount( '\t' );
}
}
}
#else
for( pService = rAll.First();pService;pService = rAll.Next() )
{
if ( !hText2 || ( *pService->pName == hText2 ) )
{
for( pTopic = pService->aTopics.First(); pTopic;
pTopic = pService->aTopics.Next() )
{
if ( !hText1 || (*pTopic->pName == hText1) )
nTopics++;
}
}
}
#endif
if( !nTopics )
return (HDDEDATA)NULL;
HSZPAIR* pPairs = new HSZPAIR [nTopics + 1];
if ( !pPairs )
return (HDDEDATA)NULL;
HSZPAIR* q = pPairs;
for( pService = rAll.First(); pService; pService = rAll.Next() )
{
if ( !hText2 || (*pService->pName == hText2 ) )
{
#if 0
for ( pTopic = pService->aTopics.First(); pTopic;
pTopic = pService->aTopics.Next() )
{
if ( !hText1 || (*pTopic->pName == hText1) )
{
q->hszSvc = *pService->pName;
q->hszTopic = *pTopic->pName;
q++;
}
}
#else
String sTopics( pService->Topics() );
sal_uInt16 n = 0;
while( STRING_NOTFOUND != n )
{
String s( sTopics.GetToken( 0, '\t', n ));
s.EraseAllChars( '\n' ).EraseAllChars( '\r' );
if( !hText1 || s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) )
{
DdeString aDStr( pInst->hDdeInstSvr, s );
pTopic = FindTopic( *pService, (HSZ)aDStr );
if( pTopic )
{
q->hszSvc = *pService->pName;
q->hszTopic = *pTopic->pName;
q++;
}
}
}
#endif
}
}
q->hszSvc = NULL;
q->hszTopic = NULL;
HDDEDATA h = DdeCreateDataHandle(
pInst->hDdeInstSvr, (LPBYTE) pPairs,
sizeof(HSZPAIR) * (nTopics+1),
0, NULL, nCbType, 0);
delete [] pPairs;
return h;
}
case XTYP_CONNECT:
pService = FindService( hText2 );
if ( pService)
pTopic = FindTopic( *pService, hText1 );
else
pTopic = NULL;
if ( pTopic )
return (HDDEDATA)DDE_FACK;
else
return (HDDEDATA) NULL;
case XTYP_CONNECT_CONFIRM:
pService = FindService( hText2 );
if ( pService )
{
pTopic = FindTopic( *pService, hText1 );
if ( pTopic )
{
pTopic->Connect( (long) hConv );
pC = new Conversation;
pC->hConv = hConv;
pC->pTopic = pTopic;
pService->pConv->Insert( pC );
}
}
return (HDDEDATA)NULL;
}
for ( pService = rAll.First(); pService; pService = rAll.Next() )
{
for( pC = pService->pConv->First(); pC;
pC = pService->pConv->Next() )
{
if ( pC->hConv == hConv )
goto found;
}
}
return (HDDEDATA) DDE_FNOTPROCESSED;
found:
if ( nCode == XTYP_DISCONNECT)
{
pC->pTopic->_Disconnect( (long) hConv );
pService->pConv->Remove( pC );
delete pC;
return (HDDEDATA)NULL;
}
sal_Bool bExec = sal_Bool(nCode == XTYP_EXECUTE);
pTopic = pC->pTopic;
if ( pTopic && !bExec )
pItem = FindItem( *pTopic, hText2 );
else
pItem = NULL;
if ( !bExec && !pService->HasCbFormat( nCbType ) )
pItem = NULL;
if ( !pItem && !bExec )
return (HDDEDATA)DDE_FNOTPROCESSED;
if ( pItem )
pTopic->aItem = pItem->GetName();
else
pTopic->aItem.Erase();
sal_Bool bRes = sal_False;
pInst->hCurConvSvr = (long)hConv;
switch( nCode )
{
case XTYP_REQUEST:
case XTYP_ADVREQ:
{
String aRes; // darf erst am Ende freigegeben werden!!
if ( pTopic->IsSystemTopic() )
{
if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) )
aRes = pService->Topics();
else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) )
aRes = pService->SysItems();
else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) )
aRes = pService->Status();
else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) )
aRes = pService->Formats();
else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) )
aRes = pService->GetHelp();
else
aRes = pService->SysTopicGet( pTopic->aItem );
if ( aRes.Len() )
pData = new DdeData( aRes );
else
pData = NULL;
}
else if( DDEGETPUTITEM == pItem->nType )
pData = ((DdeGetPutItem*)pItem)->Get(
DdeData::GetInternalFormat( nCbType ) );
else
pData = pTopic->Get( DdeData::GetInternalFormat( nCbType ));
if ( pData )
return DdeCreateDataHandle( pInst->hDdeInstSvr,
(LPBYTE)pData->pImp->pData,
pData->pImp->nData,
0, hText2,
DdeData::GetExternalFormat(
pData->pImp->nFmt ),
0 );
}
break;
case XTYP_POKE:
if ( !pTopic->IsSystemTopic() )
{
DdeData d;
d.pImp->hData = hData;
d.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
d.Lock();
if( DDEGETPUTITEM == pItem->nType )
bRes = ((DdeGetPutItem*)pItem)->Put( &d );
else
bRes = pTopic->Put( &d );
}
pInst->hCurConvSvr = NULL;
if ( bRes )
return (HDDEDATA)DDE_FACK;
else
return (HDDEDATA) DDE_FNOTPROCESSED;
case XTYP_ADVSTART:
{
// wird das Item zum erstenmal ein HotLink ?
if( !pItem->pImpData && pTopic->StartAdviseLoop() )
{
// dann wurde das Item ausgewechselt
pTopic->aItems.Remove( pItem );
DdeItem* pTmp;
for( pTmp = pTopic->aItems.First(); pTmp;
pTmp = pTopic->aItems.Next() )
if( *pTmp->pName == hText2 )
{
// es wurde tatsaechlich ausgewechselt
delete pItem;
pItem = 0;
break;
}
if( pItem )
// es wurde doch nicht ausgewechselt, also wieder rein
pTopic->aItems.Insert( pItem );
else
pItem = pTmp;
}
pItem->IncMonitor( (long)hConv );
pInst->hCurConvSvr = NULL;
}
return (HDDEDATA)sal_True;
case XTYP_ADVSTOP:
pItem->DecMonitor( (long)hConv );
if( !pItem->pImpData )
pTopic->StopAdviseLoop();
pInst->hCurConvSvr = NULL;
return (HDDEDATA)sal_True;
case XTYP_EXECUTE:
{
DdeData aExec;
aExec.pImp->hData = hData;
aExec.pImp->nFmt = DdeData::GetInternalFormat( nCbType );
aExec.Lock();
String aName;
aName = (const sal_Unicode *)aExec.pImp->pData;
if( pTopic->IsSystemTopic() )
bRes = pService->SysTopicExecute( &aName );
else
bRes = pTopic->Execute( &aName );
}
pInst->hCurConvSvr = NULL;
if ( bRes )
return (HDDEDATA)DDE_FACK;
else
return (HDDEDATA)DDE_FNOTPROCESSED;
}
return (HDDEDATA)NULL;
}
// --- DdeInternat::FindService() ----------------------------------
DdeService* DdeInternal::FindService( HSZ hService )
{
DdeService* s;
DdeServices& rSvc = DdeService::GetServices();
for ( s = rSvc.First(); s; s = rSvc.Next() )
{
if ( *s->pName == hService )
return s;
}
return NULL;
}
// --- DdeInternat::FindTopic() ------------------------------------
DdeTopic* DdeInternal::FindTopic( DdeService& rService, HSZ hTopic )
{
DdeTopic* s;
DdeTopics& rTopics = rService.aTopics;
int bWeiter = sal_False;
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
do { // middle check loop
for ( s = rTopics.First(); s; s = rTopics.Next() )
{
if ( *s->pName == hTopic )
return s;
}
bWeiter = !bWeiter;
if( !bWeiter )
break;
// dann befragen wir doch mal unsere Ableitung:
TCHAR chBuf[250];
DdeQueryString(pInst->hDdeInstSvr,hTopic,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
bWeiter = rService.MakeTopic( reinterpret_cast<const sal_Unicode*>(chBuf) );
// dann muessen wir noch mal suchen
} while( bWeiter );
return 0;
}
// --- DdeInternal::FindItem() -------------------------------------
DdeItem* DdeInternal::FindItem( DdeTopic& rTopic, HSZ hItem )
{
DdeItem* s;
DdeItems& rItems = rTopic.aItems;
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
int bWeiter = sal_False;
do { // middle check loop
for ( s = rItems.First(); s; s = rItems.Next() )
if ( *s->pName == hItem )
return s;
bWeiter = !bWeiter;
if( !bWeiter )
break;
// dann befragen wir doch mal unsere Ableitung:
TCHAR chBuf[250];
DdeQueryString(pInst->hDdeInstSvr,hItem,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE );
bWeiter = rTopic.MakeItem( reinterpret_cast<const sal_Unicode*>(chBuf) );
// dann muessen wir noch mal suchen
} while( bWeiter );
return 0;
}
// --- DdeService::DdeService() ------------------------------------
DdeService::DdeService( const String& rService )
{
DdeInstData* pInst = ImpGetInstData();
if( !pInst )
pInst = ImpInitInstData();
pInst->nRefCount++;
pInst->nInstanceSvr++;
if ( !pInst->hDdeInstSvr )
{
nStatus = sal::static_int_cast< short >(
DdeInitialize( &pInst->hDdeInstSvr,
(PFNCALLBACK)DdeInternal::SvrCallback,
APPCLASS_STANDARD |
CBF_SKIP_REGISTRATIONS |
CBF_SKIP_UNREGISTRATIONS, 0L ) );
pInst->pServicesSvr = new DdeServices;
}
else
nStatus = DMLERR_NO_ERROR;
pConv = new ConvList;
if ( pInst->pServicesSvr )
pInst->pServicesSvr->Insert( this );
pName = new DdeString( pInst->hDdeInstSvr, rService );
if ( nStatus == DMLERR_NO_ERROR )
if ( !DdeNameService( pInst->hDdeInstSvr, *pName, NULL,
DNS_REGISTER | DNS_FILTEROFF ) )
nStatus = DMLERR_SYS_ERROR;
AddFormat( FORMAT_STRING );
pSysTopic = new DdeTopic( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) );
pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) );
pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) );
pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) );
pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) );
pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) );
AddTopic( *pSysTopic );
}
// --- DdeService::~DdeService() -----------------------------------
DdeService::~DdeService()
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
if ( pInst->pServicesSvr )
pInst->pServicesSvr->Remove( this );
// MT: Im Auftrage des Herrn (AM) auskommentiert...
// Grund:
// Bei Client/Server werden die Server nicht beendet, wenn mehr
// als einer gestartet.
// Weil keine System-Messagequeue ?!
delete pSysTopic;
delete pName;
pInst->nInstanceSvr--;
pInst->nRefCount--;
if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr )
{
if( DdeUninitialize( pInst->hDdeInstSvr ) )
{
pInst->hDdeInstSvr = NULL;
delete pInst->pServicesSvr;
pInst->pServicesSvr = NULL;
if( pInst->nRefCount == 0)
ImpDeinitInstData();
}
}
delete pConv;
}
// --- DdeService::GetName() ---------------------------------------
const String& DdeService::GetName() const
{
return *pName;
}
// --- DdeService::GetServices() -----------------------------------
DdeServices& DdeService::GetServices()
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
return *(pInst->pServicesSvr);
}
// --- DdeService::AddTopic() --------------------------------------
void DdeService::AddTopic( const DdeTopic& rTopic )
{
RemoveTopic( rTopic );
aTopics.Insert( (DdeTopic*) &rTopic );
}
// --- DdeService::RemoveTopic() -----------------------------------
void DdeService::RemoveTopic( const DdeTopic& rTopic )
{
DdeTopic* t;
for ( t = aTopics.First(); t; t = aTopics.Next() )
{
if ( !DdeCmpStringHandles (*t->pName, *rTopic.pName ) )
{
aTopics.Remove( t );
// JP 27.07.95: und alle Conversions loeschen !!!
// (sonst wird auf geloeschten Topics gearbeitet!!)
for( sal_uLong n = pConv->Count(); n; )
{
Conversation* pC = pConv->GetObject( --n );
if( pC->pTopic == &rTopic )
{
pConv->Remove( pC );
delete pC;
}
}
break;
}
}
}
// --- DdeService::HasCbFormat() -----------------------------------
sal_Bool DdeService::HasCbFormat( sal_uInt16 nFmt )
{
return sal_Bool( aFormats.GetPos( nFmt ) != LIST_ENTRY_NOTFOUND );
}
// --- DdeService::HasFormat() -------------------------------------
sal_Bool DdeService::HasFormat( sal_uLong nFmt )
{
return HasCbFormat( (sal_uInt16)DdeData::GetExternalFormat( nFmt ));
}
// --- DdeService::AddFormat() -------------------------------------
void DdeService::AddFormat( sal_uLong nFmt )
{
nFmt = DdeData::GetExternalFormat( nFmt );
aFormats.Remove( nFmt );
aFormats.Insert( nFmt );
}
// --- DdeService::RemoveFormat() ----------------------------------
void DdeService::RemoveFormat( sal_uLong nFmt )
{
aFormats.Remove( DdeData::GetExternalFormat( nFmt ) );
}
// --- DdeTopic::DdeTopic() ----------------------------------------
DdeTopic::DdeTopic( const String& rName )
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
pName = new DdeString( pInst->hDdeInstSvr, rName );
}
// --- DdeTopic::~DdeTopic() ---------------------------------------
DdeTopic::~DdeTopic()
{
DdeItem* t;
while( ( t = aItems.First() ) != NULL )
{
aItems.Remove( t );
t->pMyTopic = 0;
delete t;
}
delete pName;
}
// --- DdeTopic::GetName() -----------------------------------------
const String& DdeTopic::GetName() const
{
return *pName;
}
// --- DdeTopic::IsSystemTopic() -----------------------------------
sal_Bool DdeTopic::IsSystemTopic()
{
return sal_Bool (GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC));
}
// --- DdeTopic::AddItem() -----------------------------------------
DdeItem* DdeTopic::AddItem( const DdeItem& r )
{
DdeItem* s;
if( DDEGETPUTITEM == r.nType )
s = new DdeGetPutItem( r );
else
s = new DdeItem( r );
if ( s )
{
aItems.Insert( s );
s->pMyTopic = this;
}
return s;
}
// --- DdeTopic::InsertItem() -----------------------------------------
void DdeTopic::InsertItem( DdeItem* pNew )
{
if( pNew )
{
aItems.Insert( pNew );
pNew->pMyTopic = this;
}
}
// --- DdeTopic::RemoveItem() --------------------------------------
void DdeTopic::RemoveItem( const DdeItem& r )
{
DdeItem* s;
for ( s = aItems.First(); s; s = aItems.Next() )
{
if ( !DdeCmpStringHandles (*s->pName, *r.pName ) )
break;
}
if ( s )
{
aItems.Remove( s );
s->pMyTopic = 0;
delete s;
}
}
// --- DdeTopic::NotifyClient() ------------------------------------
void DdeTopic::NotifyClient( const String& rItem )
{
DdeItem* pItem;
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
for ( pItem = aItems.First(); pItem; pItem = aItems.Next() )
{
if ( pItem->GetName() == rItem )
{
if ( pItem->pImpData )
DdePostAdvise( pInst->hDdeInstSvr, *pName, *pItem->pName );
}
break;
}
}
// --- DdeTopic::Connect() -----------------------------------------
void __EXPORT DdeTopic::Connect( long nId )
{
aConnectLink.Call( (void*)nId );
}
// --- DdeTopic::Disconnect() --------------------------------------
void __EXPORT DdeTopic::Disconnect( long nId )
{
aDisconnectLink.Call( (void*)nId );
}
// --- DdeTopic::_Disconnect() --------------------------------------
void __EXPORT DdeTopic::_Disconnect( long nId )
{
for( DdeItem* pItem = aItems.First(); pItem; pItem = aItems.Next() )
pItem->DecMonitor( nId );
Disconnect( nId );
}
// --- DdeTopic::Get() ---------------------------------------------
DdeData* __EXPORT DdeTopic::Get( sal_uLong nFmt )
{
if ( aGetLink.IsSet() )
return (DdeData*)aGetLink.Call( (void*)nFmt );
else
return NULL;
}
// --- DdeTopic::Put() ---------------------------------------------
sal_Bool __EXPORT DdeTopic::Put( const DdeData* r )
{
if ( aPutLink.IsSet() )
return (sal_Bool)aPutLink.Call( (void*) r );
else
return sal_False;
}
// --- DdeTopic::Execute() -----------------------------------------
sal_Bool __EXPORT DdeTopic::Execute( const String* r )
{
if ( aExecLink.IsSet() )
return (sal_Bool)aExecLink.Call( (void*)r );
else
return sal_False;
}
// --- DdeTopic::GetConvId() ---------------------------------------
long DdeTopic::GetConvId()
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
return pInst->hCurConvSvr;
}
// --- DdeTopic::StartAdviseLoop() ---------------------------------
sal_Bool DdeTopic::StartAdviseLoop()
{
return sal_False;
}
// --- DdeTopic::StopAdviseLoop() ----------------------------------
sal_Bool DdeTopic::StopAdviseLoop()
{
return sal_False;
}
// --- DdeItem::DdeItem() ------------------------------------------
DdeItem::DdeItem( const sal_Unicode* p )
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
pName = new DdeString( pInst->hDdeInstSvr, p );
nType = DDEITEM;
pMyTopic = 0;
pImpData = 0;
}
// --- DdeItem::DdeItem() ------------------------------------------
DdeItem::DdeItem( const String& r)
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
pName = new DdeString( pInst->hDdeInstSvr, r );
nType = DDEITEM;
pMyTopic = 0;
pImpData = 0;
}
// --- DdeItem::DdeItem() ------------------------------------------
DdeItem::DdeItem( const DdeItem& r)
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
pName = new DdeString( pInst->hDdeInstSvr, *r.pName );
nType = DDEITEM;
pMyTopic = 0;
pImpData = 0;
}
// --- DdeItem::~DdeItem() -----------------------------------------
DdeItem::~DdeItem()
{
if( pMyTopic )
pMyTopic->aItems.Remove( this );
delete pName;
delete pImpData;
}
// --- DdeItem::GetName() ------------------------------------------
const String& DdeItem::GetName() const
{
return *pName;
}
// --- DdeItem::NotifyClient() ------------------------------------------
void DdeItem::NotifyClient()
{
if( pMyTopic && pImpData )
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
DdePostAdvise( pInst->hDdeInstSvr, *pMyTopic->pName, *pName );
}
}
// --- DdeItem::IncMonitor() ------------------------------------------
void DdeItem::IncMonitor( sal_uLong nHCnv )
{
if( !pImpData )
{
pImpData = new DdeItemImp;
if( DDEGETPUTITEM == nType )
((DdeGetPutItem*)this)->AdviseLoop( sal_True );
}
else
{
for( sal_uInt16 n = pImpData->Count(); n; )
if( (*pImpData)[ --n ].nHCnv == nHCnv )
{
++(*pImpData)[ n ].nHCnv;
return ;
}
}
pImpData->Insert( DdeItemImpData( nHCnv ), pImpData->Count() );
}
// --- DdeItem::DecMonitor() ------------------------------------------
void DdeItem::DecMonitor( sal_uLong nHCnv )
{
if( pImpData )
{
DdeItemImpData* pData = (DdeItemImpData*)pImpData->GetData();
for( sal_uInt16 n = pImpData->Count(); n; --n, ++pData )
if( pData->nHCnv == nHCnv )
{
if( !pData->nCnt || !--pData->nCnt )
{
if( 1 < pImpData->Count() )
pImpData->Remove( pImpData->Count() - n );
else
{
delete pImpData, pImpData = 0;
if( DDEGETPUTITEM == nType )
((DdeGetPutItem*)this)->AdviseLoop( sal_False );
}
}
return ;
}
}
}
// --- DdeItem::GetLinks() ------------------------------------------
short DdeItem::GetLinks()
{
short nCnt = 0;
if( pImpData )
for( sal_uInt16 n = pImpData->Count(); n; )
nCnt = nCnt + (*pImpData)[ --n ].nCnt;
return nCnt;
}
// --- DdeGetPutItem::DdeGetPutItem() ------------------------------
DdeGetPutItem::DdeGetPutItem( const sal_Unicode* p )
: DdeItem( p )
{
nType = DDEGETPUTITEM;
}
// --- DdeGetPutItem::DdeGetPutItem() ------------------------------
DdeGetPutItem::DdeGetPutItem( const String& rStr )
: DdeItem( rStr )
{
nType = DDEGETPUTITEM;
}
// --- DdeGetPutItem::DdeGetPutItem() ------------------------------
DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem )
: DdeItem( rItem )
{
nType = DDEGETPUTITEM;
}
// --- DdeGetPutData::Get() ----------------------------------------
DdeData* DdeGetPutItem::Get( sal_uLong )
{
return 0;
}
// --- DdeGetPutData::Put() ----------------------------------------
sal_Bool DdeGetPutItem::Put( const DdeData* )
{
return sal_False;
}
// --- DdeGetPutData::AdviseLoop() ---------------------------------
void DdeGetPutItem::AdviseLoop( sal_Bool )
{
}
// --- DdeService::SysItems() --------------------------------------
String DdeService::SysItems()
{
String s;
DdeTopic* t;
for ( t = aTopics.First(); t; t = aTopics.Next() )
{
if ( t->GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) )
{
short n = 0;
DdeItem* pi;
for ( pi = t->aItems.First(); pi; pi = t->aItems.Next(), n++ )
{
if ( n )
s += '\t';
s += pi->GetName();
}
s += String::CreateFromAscii("\r\n");
}
}
return s;
}
// --- DdeService::Topics() ----------------------------------------
String DdeService::Topics()
{
String s;
DdeTopic* t;
short n = 0;
for ( t = aTopics.First(); t; t = aTopics.Next(), n++ )
{
if ( n )
s += '\t';
s += t->GetName();
}
s += String::CreateFromAscii("\r\n");
return s;
}
// --- DdeService::Formats() ---------------------------------------
String DdeService::Formats()
{
String s;
long f;
TCHAR buf[128];
LPCTSTR p;
short n = 0;
for ( f = aFormats.First(); f; f = aFormats.Next(), n++ )
{
if ( n )
s += '\t';
p = buf;
switch( (sal_uInt16)f )
{
case CF_TEXT:
p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("TEXT").GetBuffer());
break;
case CF_BITMAP:
p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("BITMAP").GetBuffer());
break;
#ifdef OS2
case CF_DSPTEXT:
p = String::CreateFromAscii("TEXT").GetBuffer();
break;
case CF_DSPBITMAP:
p = String::CreateFromAscii("BITMAP").GetBuffer();
break;
case CF_METAFILE:
p = String::CreateFromAscii("METAFILE").GetBuffer();
break;
case CF_DSPMETAFILE:
p = String::CreateFromAscii("METAFILE").GetBuffer();
break;
case CF_PALETTE:
p = String::CreateFromAscii("PALETTE").GetBuffer();
break;
default:
p= String::CreateFromAscii("PRIVATE").GetBuffer();
#else
default:
GetClipboardFormatName( (UINT)f, buf, sizeof(buf) / sizeof(TCHAR) );
#endif
}
s += String( reinterpret_cast<const sal_Unicode*>(p) );
}
s += String::CreateFromAscii("\r\n");
return s;
}
// --- DdeService::Status() ----------------------------------------
String DdeService::Status()
{
return IsBusy() ? String::CreateFromAscii("Busy\r\n") : String::CreateFromAscii("Ready\r\n");
}
// --- DdeService::IsBusy() ----------------------------------------
sal_Bool __EXPORT DdeService::IsBusy()
{
return sal_False;
}
// --- DdeService::GetHelp() ----------------------------------------
String __EXPORT DdeService::GetHelp()
{
return String();
}
sal_Bool DdeTopic::MakeItem( const String& )
{
return sal_False;
}
sal_Bool DdeService::MakeTopic( const String& )
{
return sal_False;
}
String DdeService::SysTopicGet( const String& )
{
return String();
}
sal_Bool DdeService::SysTopicExecute( const String* )
{
return sal_False;
}