office-gobmx/svtools/source/svdde/ddemlimp.hxx
Jens-Heiner Rechtien 8ab086b6cc initial import
2000-09-18 16:07:07 +00:00

467 lines
17 KiB
C++

/*************************************************************************
*
* $RCSfile: ddemlimp.hxx,v $
*
* $Revision: 1.1.1.1 $
*
* last change: $Author: hr $ $Date: 2000-09-18 16:59:05 $
*
* 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): _______________________________________
*
*
************************************************************************/
#ifndef _DDEMLIMP_HXX
#define _DDEMLIMP_HXX
#include <string.h>
#include <ctype.h>
#include "ddemlos2.h"
#define DDEMLSERVICETABLE_INISIZE 8
// Bezeichner der systemglobalen DDEML-Tabelle
#define DDEMLDATA "\\SHAREMEM\\OV_DDEML.DAT"
// vorlaeufig konstante Tabellengroessen
#define CONVTABLECOUNT 2048 /* max count conversations */
#define TRANSTABLECOUNT 2048 /* transactions */
#define DDEMLAPPCOUNT 16 /* max count simultaniously running */
/* ddeml (StarDivision) applications */
#define ST_TERMACKREC 0x8000 /* wird im Conversationhandle gesetzt, */
/* wenn die Partner-App DDE_TERMINATE */
/* bestaetigt hat */
#define XST_TIMEOUT 17 /* Trans. hat Timeout ueberschritten */
#define XST_WAITING_ACK 18 /* Trans. wartet auf Acknowledge */
#define XST_WAITING_ADVDATA 19 /* Trans. wartet auf Advise-Daten */
#define XST_WAITING_REQDATA 20 /* Trans. wartet auf angeforderte Daten */
/* User-Flags DDESTRUCT */
#define IMP_HDATAAPPOWNED 0x8000
#define CONVLISTNAME "DdeConvListId"
#define XTYPF_MASK (XTYPF_NOBLOCK | XTYPF_NODATA | XTYPF_ACKREQ)
//
// DDEML-Messages; werden nur an registrierte DDEML-Apps gesendet
//
// Msg: WM_DDEML_REGISTER
// Empfaenger: wird allen DDEML-Applikationen nach Registrierung
// eines neuen Services gesendet
// Params: nPar1: hszBaseServName
// nPar2: hszInstServName
#define WM_DDEML_REGISTER WM_USER+1
// Msg: WM_DDEML_UNREGISTER
// Empfaenger: wird allen DDEML-Applikationen nach Deregistrierung
// eines Services gesendet
// Params: nPar1: hszBaseServName
// nPar2: hszInstServName
#define WM_DDEML_UNREGISTER WM_USER+2
//
//
//
struct ImpHCONV
{
HCONV hConvPartner;
HSZ hszPartner; // Name of partner application
HSZ hszServiceReq; // Service name
HSZ hszTopic; // Topic name
USHORT nStatus; // ST_* of conversation
HCONVLIST hConvList; // ConvListId , wenn in ConvList
CONVCONTEXT aConvContext; // Conversation context
// private
HWND hWndThis; // 0 == Handle not used
HWND hWndPartner;
PID pidOwner; // PID des DdeManagers, der
// den Conv-Handle erzeugt hat.
USHORT nPrevHCONV; // 0 == no previous hConv or not in list
USHORT nNextHCONV; // 0 == no next hconv or not in list
};
struct Transaction
{
HSZ hszItem; // Item name
USHORT nFormat; // Data format
USHORT nType; // Transaction type (XTYP_*)
// XTYP_ADVREQ [|XTYPF_NODATA] == Advise-Loop
// [|XTYPF_ACKREQ]
// XTYP_EXECUTE == laufendes Execute
// XTYP_REQUEST
// XTYP_POKE
// XTYP_ADVSTOP
// XTYP_ADVSTART
USHORT nConvst; // Conversation state (XST_*)
// 0 == idle
// XST_REQSENT (fuer XTYP_ADVREQ)
// XST_TIMEOUT (fuer alle Typen!)
// XST_WAITING (alle ausser XTYP_ADVREQ)
USHORT nLastError; // last err in transaction
ULONG nUser; // Userhandle
// private
HCONV hConvOwner; // 0 == Transaction not used
};
struct ImpWndProcParams
{
HWND hWndReceiver;
MPARAM nPar1;
MPARAM nPar2;
};
struct ImpService
{
HSZ hBaseServName; // Basis-Name des Service
HSZ hInstServName; // Basis-Name + DDEML-Server-HWND der App
};
class ImpDdeMgr;
// Daten eines Conversation-Windows
struct ImpConvWndData
{
ImpDdeMgr* pThis;
USHORT nRefCount; // Zahl Conversations auf diesem Window
};
// systemglobale Daten der Library (liegen in named shared memory)
struct ImpDdeMgrData
{
ULONG nTotalSize;
ULONG nOffsAppTable;
ULONG nOffsConvTable;
ULONG nOffsTransTable;
USHORT nMaxAppCount;
USHORT nMaxConvCount;
USHORT nMaxTransCount;
USHORT nLastErr;
USHORT nReserved;
USHORT nCurTransCount;
USHORT nCurConvCount;
HWND aAppTable[ 1 ]; // fuer Broadcast-Messages
ImpHCONV aConvTable[ 1 ];
Transaction aTransTable[ 1 ];
};
class ImpDdeMgr
{
friend MRESULT EXPENTRY ConvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2);
friend MRESULT EXPENTRY ServerWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2);
friend void ImpWriteDdeStatus(char*,char*);
friend void ImpAddHSZ( HSZ, String& );
static PSZ AllocAtomName( ATOM hString, ULONG& rBufLen );
static PDDESTRUCT MakeDDEObject( HWND hwnd, ATOM hItemName,
USHORT fsStatus, USHORT usFormat, PVOID pabData, ULONG usDataLen );
static APIRET AllocNamedSharedMem( PPVOID ppBaseAddress, PSZ pName,
ULONG nElementSize, ULONG nElementCount );
HWND hWndServer;
PID pidThis;
PFNCALLBACK pCallback;
ULONG nTransactFilter;
CONVCONTEXT aDefaultContext;
ImpDdeMgrData* pData;
ImpService* pServices;
USHORT nServiceCount;
ImpHCONV* pConvTable; // liegt in pData (nicht deleten!)
Transaction* pTransTable; // liegt in pData (nicht deleten!)
HWND* pAppTable; // liegt in pData (nicht deleten!)
static ImpHCONV* GetConvTable( ImpDdeMgrData* );
static Transaction* GetTransTable( ImpDdeMgrData* );
static HWND* GetAppTable( ImpDdeMgrData* );
static HWND NextFrameWin( HENUM hEnum );
void CreateServerWnd();
void DestroyServerWnd();
HWND CreateConversationWnd();
// Fktn. duerfen nur fuer HCONVs aufgerufen werden, die
// in der eigenen Applikation erzeugt wurden
static void DestroyConversationWnd( HWND hWndConv );
static USHORT GetConversationWndRefCount( HWND hWndConv );
static USHORT IncConversationWndRefCount( HWND hWndConv );
MRESULT SrvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2);
MRESULT ConvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2);
void RegisterDDEMLApp();
void UnregisterDDEMLApp();
void CleanUp();
ImpDdeMgrData* InitAll();
static BOOL MyWinDdePostMsg( HWND, HWND, USHORT, PDDESTRUCT, ULONG );
void MyInitiateDde( HWND hWndServer, HWND hWndClient,
HSZ hszService, HSZ hszTopic, CONVCONTEXT* pCC );
DDEINIT* CreateDDEInitData( HWND hWndDest, HSZ hszService,
HSZ hszTopic, CONVCONTEXT* pCC );
// wenn pDDEData==0, muss pCC gesetzt sein
HCONV ConnectWithClient( HWND hWndClient, HSZ hszPartner,
HSZ hszService, HSZ hszTopic, BOOL bSameInst,
DDEINIT* pDDEData, CONVCONTEXT* pCC = 0);
HCONV CheckIncoming( ImpWndProcParams*, ULONG nTransMask,
HSZ& rhszItem );
// fuer Serverbetrieb. Ruft Callback-Fkt fuer alle offenen Advises
// auf, deren Owner der uebergebene HCONV ist.
// bFreeTransactions==TRUE: loescht die Transaktionen
// gibt Anzahl der getrennten Transaktionen zurueck
USHORT SendUnadvises( HCONV hConv,
USHORT nFormat, // 0==alle
BOOL bFreeTransactions );
BOOL WaitTransState(
Transaction* pTrans, ULONG nTransId,
USHORT nNewState,
ULONG nTimeout );
// DDEML ruft Callback mit XTYP_CONNECT-Transaction nur auf,
// wenn die App den angeforderten Service registriert hat
// Standardeinstellung: TRUE
BOOL bServFilterOn;
// Fehlercode muss noch systemglobal werden (Atom o. ae.)
static USHORT nLastErrInstance; // wenn 0, dann gilt globaler Fehlercode
static ImpDdeMgrData* AccessMgrData();
static HCONV CreateConvHandle( ImpDdeMgrData* pBase,
PID pidOwner,
HWND hWndThis, HWND hWndPartner,
HSZ hszPartner, HSZ hszServiceReq, HSZ hszTopic,
HCONV hPrevHCONV = 0 );
static HCONV IsConvHandleAvailable( ImpDdeMgrData* pBase );
static HCONV GetConvHandle( ImpDdeMgrData* pBase,
HWND hWndThis, HWND hWndPartner );
static void FreeConvHandle( ImpDdeMgrData*, HCONV,
BOOL bDestroyHWndThis = TRUE );
static ULONG CreateTransaction( ImpDdeMgrData* pBase,
HCONV hOwner, HSZ hszItem, USHORT nFormat,
USHORT nTransactionType );
static ULONG GetTransaction( ImpDdeMgrData* pBase,
HCONV hOwner, HSZ hszItem, USHORT nFormat );
static void FreeTransaction( ImpDdeMgrData*, ULONG nTransId );
BOOL DisconnectAll();
// Transaktionen muessen _vor_ den Konversationen geloescht werden!
static void FreeTransactions( ImpDdeMgrData*, HWND hWndThis,
HWND hWndPartner );
static void FreeTransactions( ImpDdeMgrData*, HCONV hConvOwner );
static void FreeConversations( ImpDdeMgrData*,HWND hWndThis,
HWND hWndPartner );
ImpService* GetService( HSZ hszService );
ImpService* PutService( HSZ hszService );
void BroadcastService( ImpService*, BOOL bRegistered );
// rh: Startposition(!) & gefundener Handle
static ImpHCONV* GetFirstServer( ImpDdeMgrData*, HCONVLIST, HCONV& rh);
static ImpHCONV* GetLastServer( ImpDdeMgrData*, HCONVLIST, HCONV& );
static BOOL CheckConvListId( HCONVLIST hConvListId );
BOOL IsSameInstance( HWND hWnd );
HSZ GetAppName( HWND hWnd );
// Transactions
MRESULT DdeAck( ImpWndProcParams* pParams );
MRESULT DdeAdvise( ImpWndProcParams* pParams );
MRESULT DdeData( ImpWndProcParams* pParams );
MRESULT DdeExecute( ImpWndProcParams* pParams );
MRESULT DdeInitiate( ImpWndProcParams* pParams );
MRESULT DdeInitiateAck( ImpWndProcParams* pParams );
MRESULT DdePoke( ImpWndProcParams* pParams );
MRESULT DdeRequest( ImpWndProcParams* pParams );
MRESULT DdeTerminate( ImpWndProcParams* pParams );
MRESULT DdeUnadvise( ImpWndProcParams* pParams );
MRESULT DdeRegister( ImpWndProcParams* pParams );
MRESULT DdeUnregister( ImpWndProcParams* pParams );
MRESULT DdeTimeout( ImpWndProcParams* pParams );
HDDEDATA Callback(
USHORT nTransactionType,
USHORT nClipboardFormat,
HCONV hConversationHandle,
HSZ hsz1,
HSZ hsz2,
HDDEDATA hData,
ULONG nData1,
ULONG nData2 );
HCONV DdeConnectImp( HSZ hszService,HSZ hszTopic,CONVCONTEXT* pCC);
// connection data
HCONV hCurConv; // wird im DdeInitiateAck gesetzt
HCONVLIST hCurListId; // fuer DdeConnectList
USHORT nPrevConv; // .... "" ....
BOOL bListConnect;
// synchr. transaction data
BOOL bInSyncTrans;
ULONG nSyncTransId;
HDDEDATA hSyncResponseData;
ULONG nSyncResponseMsg; // WM_DDE_ACK, WM_DDE_DATA, WM_TIMER
// TRUE==nach Ende der synchronen Transaktion eine evtl. benutzte
// asynchrone Transaktion beenden (typisch synchroner Request auf
// Advise-Loop)
BOOL bSyncAbandonTrans;
public:
ImpDdeMgr();
~ImpDdeMgr();
USHORT DdeInitialize( PFNCALLBACK pCallbackProc, ULONG nTransactionFilter );
USHORT DdeGetLastError();
HCONV DdeConnect( HSZ hszService, HSZ hszTopic, CONVCONTEXT* );
HCONVLIST DdeConnectList( HSZ hszService, HSZ hszTopic,
HCONVLIST hConvList, CONVCONTEXT* );
static BOOL DdeDisconnect( HCONV hConv );
static BOOL DdeDisconnectList( HCONVLIST hConvList );
static HCONV DdeReconnect(HCONV hConv);
static HCONV DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev);
static USHORT DdeQueryConvInfo(HCONV hConv, ULONG idTrans,CONVINFO* pCI);
static BOOL DdeSetUserHandle(HCONV hConv, ULONG id, ULONG hUser);
BOOL DdeAbandonTransaction( HCONV hConv, ULONG idTransaction);
BOOL DdePostAdvise( HSZ hszTopic, HSZ hszItem);
BOOL DdeEnableCallback( HCONV hConv, USHORT wCmd);
HDDEDATA DdeNameService( HSZ hszService, USHORT afCmd);
static HDDEDATA DdeClientTransaction(void* pData, ULONG cbData,
HCONV hConv, HSZ hszItem, USHORT wFmt, USHORT wType,
ULONG dwTimeout, ULONG* pdwResult);
// Data handles
HDDEDATA DdeCreateDataHandle( void* pSrc, ULONG cb, ULONG cbOff,
HSZ hszItem, USHORT wFmt, USHORT afCmd);
static BYTE* DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize);
static BOOL DdeUnaccessData(HDDEDATA hData);
static BOOL DdeFreeDataHandle(HDDEDATA hData);
static HDDEDATA DdeAddData(HDDEDATA hData,void* pSrc,ULONG cb,ULONG cbOff);
static ULONG DdeGetData(HDDEDATA hData,void* pDst,ULONG cbMax,ULONG cbOff);
// String handles
static HSZ DdeCreateStringHandle( PSZ pStr, int iCodePage);
static ULONG DdeQueryString(HSZ hsz,PSZ pStr,ULONG cchMax,int iCPage);
static BOOL DdeFreeStringHandle( HSZ hsz );
static BOOL DdeKeepStringHandle( HSZ hsz );
static int DdeCmpStringHandles(HSZ hsz1, HSZ hsz2);
// mit dieser Funktion kann geprueft werden, ob eine
// Applikation schon eine DDEML-Instanz angelegt hat.
// Die aktuelle Impl. unterstuetzt nur eine DDEML-Instanz
// pro Applikation (wg. synchroner Transaktionen)
static ImpDdeMgr* GetImpDdeMgrInstance( HWND hWnd );
// gibt TRUE zurueck, wenn mind. ein lebender HCONV
// von diesem DdeMgr erzeugt wurde
BOOL OwnsConversationHandles();
};
// static
inline ImpHCONV* ImpDdeMgr::GetConvTable( ImpDdeMgrData* pData )
{
ImpHCONV* pRet;
if( pData )
pRet = (ImpHCONV*)((ULONG)(pData) + pData->nOffsConvTable);
else
pRet = 0;
return pRet;
}
// static
inline Transaction* ImpDdeMgr::GetTransTable( ImpDdeMgrData* pData )
{
Transaction* pRet;
if( pData )
pRet = (Transaction*)((ULONG)(pData) + pData->nOffsTransTable);
else
pRet = 0;
return pRet;
}
// static
inline HWND* ImpDdeMgr::GetAppTable( ImpDdeMgrData* pData )
{
HWND* pRet;
if( pData )
pRet = (HWND*)((ULONG)(pData) + pData->nOffsAppTable);
else
pRet = 0;
return pRet;
}
#endif