office-gobmx/svtools/source/svdde/ddesvr.cxx
2001-09-04 16:08:34 +00:00

1140 lines
31 KiB
C++

/*************************************************************************
*
* $RCSfile: ddesvr.cxx,v $
*
* $Revision: 1.4 $
*
* last change: $Author: pl $ $Date: 2001-09-04 17:05:08 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#define UNICODE
#include "ddeimp.hxx"
#include <svdde.hxx>
#include <svarray.hxx>
#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif
//static long hCurConv = 0;
//static DWORD hDdeInst = NULL;
//static short nInstance = 0;
//static DdeServices* pServices;
enum DdeItemType
{
DDEITEM,
DDEGETPUTITEM
};
struct DdeItemImpData
{
ULONG nHCnv;
USHORT nCnt;
DdeItemImpData( 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:
{
short 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 )
{
USHORT n = 0;
while( STRING_NOTFOUND != n )
{
String s( sTopics.GetToken( 0, '\t', n ));
if( s == 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() );
USHORT n = 0;
while( STRING_NOTFOUND != n )
{
String s( sTopics.GetToken( 0, '\t', n ));
s.EraseAllChars( '\n' ).EraseAllChars( '\r' );
if( !hText1 || s == 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;
}
BOOL bExec = 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();
BOOL bRes = 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 == SZDDESYS_ITEM_TOPICS )
aRes = pService->Topics();
else if ( pTopic->aItem == SZDDESYS_ITEM_SYSITEMS )
aRes = pService->SysItems();
else if ( pTopic->aItem == SZDDESYS_ITEM_STATUS )
aRes = pService->Status();
else if ( pTopic->aItem == SZDDESYS_ITEM_FORMATS )
aRes = pService->Formats();
else if ( pTopic->aItem == 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)TRUE;
case XTYP_ADVSTOP:
pItem->DecMonitor( (long)hConv );
if( !pItem->pImpData )
pTopic->StopAdviseLoop();
pInst->hCurConvSvr = NULL;
return (HDDEDATA)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 = 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( 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 = 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( 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 = 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( SZDDESYS_TOPIC );
pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_TOPICS ) );
pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_SYSITEMS ) );
pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_STATUS ) );
pSysTopic->AddItem( DdeItem( SZDDESYS_ITEM_FORMATS ) );
pSysTopic->AddItem( DdeItem( 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( ULONG n = pConv->Count(); n; )
{
Conversation* pC = pConv->GetObject( --n );
if( pC->pTopic == &rTopic )
{
pConv->Remove( pC );
delete pC;
}
}
break;
}
}
}
// --- DdeService::HasCbFormat() -----------------------------------
BOOL DdeService::HasCbFormat( USHORT nFmt )
{
return BOOL( aFormats.GetPos( nFmt ) != LIST_ENTRY_NOTFOUND );
}
// --- DdeService::HasFormat() -------------------------------------
BOOL DdeService::HasFormat( ULONG nFmt )
{
return HasCbFormat( (USHORT)DdeData::GetExternalFormat( nFmt ));
}
// --- DdeService::AddFormat() -------------------------------------
void DdeService::AddFormat( ULONG nFmt )
{
nFmt = DdeData::GetExternalFormat( nFmt );
aFormats.Remove( nFmt );
aFormats.Insert( nFmt );
}
// --- DdeService::RemoveFormat() ----------------------------------
void DdeService::RemoveFormat( 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() -----------------------------------
BOOL DdeTopic::IsSystemTopic()
{
return BOOL (GetName() == 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( ULONG nFmt )
{
if ( aGetLink.IsSet() )
return (DdeData*)aGetLink.Call( (void*)nFmt );
else
return NULL;
}
// --- DdeTopic::Put() ---------------------------------------------
BOOL __EXPORT DdeTopic::Put( const DdeData* r )
{
if ( aPutLink.IsSet() )
return (BOOL)aPutLink.Call( (void*) r );
else
return FALSE;
}
// --- DdeTopic::Execute() -----------------------------------------
BOOL __EXPORT DdeTopic::Execute( const String* r )
{
if ( aExecLink.IsSet() )
return (BOOL)aExecLink.Call( (void*)r );
else
return FALSE;
}
// --- DdeTopic::GetConvId() ---------------------------------------
long DdeTopic::GetConvId()
{
DdeInstData* pInst = ImpGetInstData();
DBG_ASSERT(pInst,"SVDDE:No instance data");
return pInst->hCurConvSvr;
}
// --- DdeTopic::StartAdviseLoop() ---------------------------------
BOOL DdeTopic::StartAdviseLoop()
{
return FALSE;
}
// --- DdeTopic::StopAdviseLoop() ----------------------------------
BOOL DdeTopic::StopAdviseLoop()
{
return 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( ULONG nHCnv )
{
if( !pImpData )
{
pImpData = new DdeItemImp;
if( DDEGETPUTITEM == nType )
((DdeGetPutItem*)this)->AdviseLoop( TRUE );
}
else
{
for( USHORT n = pImpData->Count(); n; )
if( (*pImpData)[ --n ].nHCnv == nHCnv )
{
++(*pImpData)[ n ].nHCnv;
return ;
}
}
pImpData->Insert( DdeItemImpData( nHCnv ), pImpData->Count() );
}
// --- DdeItem::DecMonitor() ------------------------------------------
void DdeItem::DecMonitor( ULONG nHCnv )
{
if( pImpData )
{
DdeItemImpData* pData = (DdeItemImpData*)pImpData->GetData();
for( USHORT 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( FALSE );
}
}
return ;
}
}
}
// --- DdeItem::GetLinks() ------------------------------------------
short DdeItem::GetLinks()
{
short nCnt = 0;
if( pImpData )
for( USHORT n = pImpData->Count(); n; )
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( ULONG )
{
return 0;
}
// --- DdeGetPutData::Put() ----------------------------------------
BOOL DdeGetPutItem::Put( const DdeData* )
{
return FALSE;
}
// --- DdeGetPutData::AdviseLoop() ---------------------------------
void DdeGetPutItem::AdviseLoop( BOOL )
{
}
// --- DdeService::SysItems() --------------------------------------
String DdeService::SysItems()
{
String s;
DdeTopic* t;
for ( t = aTopics.First(); t; t = aTopics.Next() )
{
if ( t->GetName() == String::CreateFromAscii( (const sal_Char *)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( (USHORT)f )
{
case CF_TEXT:
p = String::CreateFromAscii("TEXT").GetBuffer();
break;
case CF_BITMAP:
p = 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( 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() ----------------------------------------
BOOL __EXPORT DdeService::IsBusy()
{
return FALSE;
}
// --- DdeService::GetHelp() ----------------------------------------
String __EXPORT DdeService::GetHelp()
{
return String();
}
BOOL DdeTopic::MakeItem( const String& )
{
return FALSE;
}
BOOL DdeService::MakeTopic( const String& )
{
return FALSE;
}
String DdeService::SysTopicGet( const String& )
{
return String();
}
BOOL DdeService::SysTopicExecute( const String* )
{
return FALSE;
}