| /************************************************************** |
| * |
| * 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_basic.hxx" |
| #include <tools/errcode.hxx> |
| #include <svl/svdde.hxx> |
| #include "ddectrl.hxx" |
| #ifndef _SBERRORS_HXX |
| #include <basic/sberrors.hxx> |
| #endif |
| |
| #define DDE_FREECHANNEL ((DdeConnection*)0xffffffff) |
| |
| #define DDE_FIRSTERR 0x4000 |
| #define DDE_LASTERR 0x4011 |
| |
| static const SbError nDdeErrMap[] = |
| { |
| /* DMLERR_ADVACKTIMEOUT */ 0x4000, SbERR_DDE_TIMEOUT, |
| /* DMLERR_BUSY */ 0x4001, SbERR_DDE_BUSY, |
| /* DMLERR_DATAACKTIMEOUT */ 0x4002, SbERR_DDE_TIMEOUT, |
| /* DMLERR_DLL_NOT_INITIALIZED */ 0x4003, SbERR_DDE_ERROR, |
| /* DMLERR_DLL_USAGE */ 0x4004, SbERR_DDE_ERROR, |
| /* DMLERR_EXECACKTIMEOUT */ 0x4005, SbERR_DDE_TIMEOUT, |
| /* DMLERR_INVALIDPARAMETER */ 0x4006, SbERR_DDE_ERROR, |
| /* DMLERR_LOW_MEMORY */ 0x4007, SbERR_DDE_ERROR, |
| /* DMLERR_MEMORY_ERROR */ 0x4008, SbERR_DDE_ERROR, |
| /* DMLERR_NOTPROCESSED */ 0x4009, SbERR_DDE_NOTPROCESSED, |
| /* DMLERR_NO_CONV_ESTABLISHED */ 0x400a, SbERR_DDE_NO_CHANNEL, |
| /* DMLERR_POKEACKTIMEOUT */ 0x400b, SbERR_DDE_TIMEOUT, |
| /* DMLERR_POSTMSG_FAILED */ 0x400c, SbERR_DDE_QUEUE_OVERFLOW, |
| /* DMLERR_REENTRANCY */ 0x400d, SbERR_DDE_ERROR, |
| /* DMLERR_SERVER_DIED */ 0x400e, SbERR_DDE_PARTNER_QUIT, |
| /* DMLERR_SYS_ERROR */ 0x400f, SbERR_DDE_ERROR, |
| /* DMLERR_UNADVACKTIMEOUT */ 0x4010, SbERR_DDE_TIMEOUT, |
| /* DMLERR_UNFOUND_QUEUE_ID */ 0x4011, SbERR_DDE_NO_CHANNEL |
| }; |
| |
| SbError SbiDdeControl::GetLastErr( DdeConnection* pConv ) |
| { |
| if( !pConv ) |
| return 0; |
| long nErr = pConv->GetError(); |
| if( !nErr ) |
| return 0; |
| if( nErr < DDE_FIRSTERR || nErr > DDE_LASTERR ) |
| return SbERR_DDE_ERROR; |
| return nDdeErrMap[ 2*(nErr - DDE_FIRSTERR) + 1 ]; |
| } |
| |
| IMPL_LINK_INLINE( SbiDdeControl,Data , DdeData*, pData, |
| { |
| aData = String::CreateFromAscii( (char*)(const void*)*pData ); |
| return 1; |
| } |
| ) |
| |
| SbiDdeControl::SbiDdeControl() |
| { |
| pConvList = new DdeConnections; |
| DdeConnection* pPtr = DDE_FREECHANNEL; |
| pConvList->Insert( pPtr ); |
| } |
| |
| SbiDdeControl::~SbiDdeControl() |
| { |
| TerminateAll(); |
| delete pConvList; |
| } |
| |
| sal_Int16 SbiDdeControl::GetFreeChannel() |
| { |
| sal_Int16 nListSize = (sal_Int16)pConvList->Count(); |
| DdeConnection* pPtr = pConvList->First(); |
| pPtr = pConvList->Next(); // nullten eintrag ueberspringen |
| sal_Int16 nChannel; |
| for( nChannel = 1; nChannel < nListSize; nChannel++ ) |
| { |
| if( pPtr == DDE_FREECHANNEL ) |
| return nChannel; |
| pPtr = pConvList->Next(); |
| } |
| pPtr = DDE_FREECHANNEL; |
| pConvList->Insert( pPtr, LIST_APPEND ); |
| return nChannel; |
| } |
| |
| SbError SbiDdeControl::Initiate( const String& rService, const String& rTopic, |
| sal_Int16& rnHandle ) |
| { |
| SbError nErr; |
| DdeConnection* pConv = new DdeConnection( rService, rTopic ); |
| nErr = GetLastErr( pConv ); |
| if( nErr ) |
| { |
| delete pConv; |
| rnHandle = 0; |
| } |
| else |
| { |
| sal_Int16 nChannel = GetFreeChannel(); |
| pConvList->Replace( pConv, (sal_uIntPtr)nChannel ); |
| rnHandle = nChannel; |
| } |
| return 0; |
| } |
| |
| SbError SbiDdeControl::Terminate( sal_Int16 nChannel ) |
| { |
| DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); |
| if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) |
| return SbERR_DDE_NO_CHANNEL; |
| pConvList->Replace( DDE_FREECHANNEL, (sal_uIntPtr)nChannel ); |
| delete pConv; |
| return 0L; |
| } |
| |
| SbError SbiDdeControl::TerminateAll() |
| { |
| sal_Int16 nChannel = (sal_Int16)pConvList->Count(); |
| while( nChannel ) |
| { |
| nChannel--; |
| Terminate( nChannel ); |
| } |
| |
| pConvList->Clear(); |
| DdeConnection* pPtr = DDE_FREECHANNEL; |
| pConvList->Insert( pPtr ); |
| |
| return 0; |
| } |
| |
| SbError SbiDdeControl::Request( sal_Int16 nChannel, const String& rItem, String& rResult ) |
| { |
| DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); |
| if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) |
| return SbERR_DDE_NO_CHANNEL; |
| |
| DdeRequest aRequest( *pConv, rItem, 30000 ); |
| aRequest.SetDataHdl( LINK( this, SbiDdeControl, Data ) ); |
| aRequest.Execute(); |
| rResult = aData; |
| return GetLastErr( pConv ); |
| } |
| |
| SbError SbiDdeControl::Execute( sal_Int16 nChannel, const String& rCommand ) |
| { |
| DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); |
| if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) |
| return SbERR_DDE_NO_CHANNEL; |
| DdeExecute aRequest( *pConv, rCommand, 30000 ); |
| aRequest.Execute(); |
| return GetLastErr( pConv ); |
| } |
| |
| SbError SbiDdeControl::Poke( sal_Int16 nChannel, const String& rItem, const String& rData ) |
| { |
| DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); |
| if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) |
| return SbERR_DDE_NO_CHANNEL; |
| DdePoke aRequest( *pConv, rItem, DdeData(rData), 30000 ); |
| aRequest.Execute(); |
| return GetLastErr( pConv ); |
| } |
| |
| |