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