1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ddectrl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 #include <tools/errcode.hxx>
34 #include <svtools/svdde.hxx>
35 #include "ddectrl.hxx"
37 #include <basic/sberrors.hxx>
40 #define DDE_FREECHANNEL ((DdeConnection*)0xffffffff)
42 #define DDE_FIRSTERR 0x4000
43 #define DDE_LASTERR 0x4011
45 static const SbError nDdeErrMap
[] =
47 /* DMLERR_ADVACKTIMEOUT */ 0x4000, SbERR_DDE_TIMEOUT
,
48 /* DMLERR_BUSY */ 0x4001, SbERR_DDE_BUSY
,
49 /* DMLERR_DATAACKTIMEOUT */ 0x4002, SbERR_DDE_TIMEOUT
,
50 /* DMLERR_DLL_NOT_INITIALIZED */ 0x4003, SbERR_DDE_ERROR
,
51 /* DMLERR_DLL_USAGE */ 0x4004, SbERR_DDE_ERROR
,
52 /* DMLERR_EXECACKTIMEOUT */ 0x4005, SbERR_DDE_TIMEOUT
,
53 /* DMLERR_INVALIDPARAMETER */ 0x4006, SbERR_DDE_ERROR
,
54 /* DMLERR_LOW_MEMORY */ 0x4007, SbERR_DDE_ERROR
,
55 /* DMLERR_MEMORY_ERROR */ 0x4008, SbERR_DDE_ERROR
,
56 /* DMLERR_NOTPROCESSED */ 0x4009, SbERR_DDE_NOTPROCESSED
,
57 /* DMLERR_NO_CONV_ESTABLISHED */ 0x400a, SbERR_DDE_NO_CHANNEL
,
58 /* DMLERR_POKEACKTIMEOUT */ 0x400b, SbERR_DDE_TIMEOUT
,
59 /* DMLERR_POSTMSG_FAILED */ 0x400c, SbERR_DDE_QUEUE_OVERFLOW
,
60 /* DMLERR_REENTRANCY */ 0x400d, SbERR_DDE_ERROR
,
61 /* DMLERR_SERVER_DIED */ 0x400e, SbERR_DDE_PARTNER_QUIT
,
62 /* DMLERR_SYS_ERROR */ 0x400f, SbERR_DDE_ERROR
,
63 /* DMLERR_UNADVACKTIMEOUT */ 0x4010, SbERR_DDE_TIMEOUT
,
64 /* DMLERR_UNFOUND_QUEUE_ID */ 0x4011, SbERR_DDE_NO_CHANNEL
67 SbError
SbiDdeControl::GetLastErr( DdeConnection
* pConv
)
71 long nErr
= pConv
->GetError();
74 if( nErr
< DDE_FIRSTERR
|| nErr
> DDE_LASTERR
)
75 return SbERR_DDE_ERROR
;
76 return nDdeErrMap
[ 2*(nErr
- DDE_FIRSTERR
) + 1 ];
79 IMPL_LINK_INLINE( SbiDdeControl
,Data
, DdeData
*, pData
,
81 aData
= String::CreateFromAscii( (char*)(const void*)*pData
);
86 SbiDdeControl::SbiDdeControl()
88 pConvList
= new DdeConnections
;
89 DdeConnection
* pPtr
= DDE_FREECHANNEL
;
90 pConvList
->Insert( pPtr
);
93 SbiDdeControl::~SbiDdeControl()
99 INT16
SbiDdeControl::GetFreeChannel()
101 INT16 nListSize
= (INT16
)pConvList
->Count();
102 DdeConnection
* pPtr
= pConvList
->First();
103 pPtr
= pConvList
->Next(); // nullten eintrag ueberspringen
105 for( nChannel
= 1; nChannel
< nListSize
; nChannel
++ )
107 if( pPtr
== DDE_FREECHANNEL
)
109 pPtr
= pConvList
->Next();
111 pPtr
= DDE_FREECHANNEL
;
112 pConvList
->Insert( pPtr
, LIST_APPEND
);
116 SbError
SbiDdeControl::Initiate( const String
& rService
, const String
& rTopic
,
120 DdeConnection
* pConv
= new DdeConnection( rService
, rTopic
);
121 nErr
= GetLastErr( pConv
);
129 INT16 nChannel
= GetFreeChannel();
130 pConvList
->Replace( pConv
, (ULONG
)nChannel
);
136 SbError
SbiDdeControl::Terminate( INT16 nChannel
)
138 DdeConnection
* pConv
= pConvList
->GetObject( (ULONG
)nChannel
);
139 if( !nChannel
|| !pConv
|| pConv
== DDE_FREECHANNEL
)
140 return SbERR_DDE_NO_CHANNEL
;
141 pConvList
->Replace( DDE_FREECHANNEL
, (ULONG
)nChannel
);
146 SbError
SbiDdeControl::TerminateAll()
148 INT16 nChannel
= (INT16
)pConvList
->Count();
152 Terminate( nChannel
);
156 DdeConnection
* pPtr
= DDE_FREECHANNEL
;
157 pConvList
->Insert( pPtr
);
162 SbError
SbiDdeControl::Request( INT16 nChannel
, const String
& rItem
, String
& rResult
)
164 DdeConnection
* pConv
= pConvList
->GetObject( (ULONG
)nChannel
);
165 if( !nChannel
|| !pConv
|| pConv
== DDE_FREECHANNEL
)
166 return SbERR_DDE_NO_CHANNEL
;
168 DdeRequest
aRequest( *pConv
, rItem
, 30000 );
169 aRequest
.SetDataHdl( LINK( this, SbiDdeControl
, Data
) );
172 return GetLastErr( pConv
);
175 SbError
SbiDdeControl::Execute( INT16 nChannel
, const String
& rCommand
)
177 DdeConnection
* pConv
= pConvList
->GetObject( (ULONG
)nChannel
);
178 if( !nChannel
|| !pConv
|| pConv
== DDE_FREECHANNEL
)
179 return SbERR_DDE_NO_CHANNEL
;
180 DdeExecute
aRequest( *pConv
, rCommand
, 30000 );
182 return GetLastErr( pConv
);
185 SbError
SbiDdeControl::Poke( INT16 nChannel
, const String
& rItem
, const String
& rData
)
187 DdeConnection
* pConv
= pConvList
->GetObject( (ULONG
)nChannel
);
188 if( !nChannel
|| !pConv
|| pConv
== DDE_FREECHANNEL
)
189 return SbERR_DDE_NO_CHANNEL
;
190 DdePoke
aRequest( *pConv
, rItem
, DdeData(rData
), 30000 );
192 return GetLastErr( pConv
);