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: ddemlimp.hxx,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 ************************************************************************/
39 #define DDEMLSERVICETABLE_INISIZE 8
41 // Bezeichner der systemglobalen DDEML-Tabelle
42 #define DDEMLDATA "\\SHAREMEM\\OV_DDEML.DAT"
44 // vorlaeufig konstante Tabellengroessen
45 #define CONVTABLECOUNT 2048 /* max count conversations */
46 #define TRANSTABLECOUNT 2048 /* transactions */
47 #define DDEMLAPPCOUNT 16 /* max count simultaniously running */
48 /* ddeml (StarDivision) applications */
50 #define ST_TERMACKREC 0x8000 /* wird im Conversationhandle gesetzt, */
51 /* wenn die Partner-App DDE_TERMINATE */
54 #define XST_TIMEOUT 17 /* Trans. hat Timeout ueberschritten */
55 #define XST_WAITING_ACK 18 /* Trans. wartet auf Acknowledge */
56 #define XST_WAITING_ADVDATA 19 /* Trans. wartet auf Advise-Daten */
57 #define XST_WAITING_REQDATA 20 /* Trans. wartet auf angeforderte Daten */
60 /* User-Flags DDESTRUCT */
61 #define IMP_HDATAAPPOWNED 0x8000
63 #define CONVLISTNAME "DdeConvListId"
65 #define XTYPF_MASK (XTYPF_NOBLOCK | XTYPF_NODATA | XTYPF_ACKREQ)
68 // DDEML-Messages; werden nur an registrierte DDEML-Apps gesendet
71 // Msg: WM_DDEML_REGISTER
72 // Empfaenger: wird allen DDEML-Applikationen nach Registrierung
73 // eines neuen Services gesendet
74 // Params: nPar1: hszBaseServName
75 // nPar2: hszInstServName
76 #define WM_DDEML_REGISTER WM_USER+1
78 // Msg: WM_DDEML_UNREGISTER
79 // Empfaenger: wird allen DDEML-Applikationen nach Deregistrierung
80 // eines Services gesendet
81 // Params: nPar1: hszBaseServName
82 // nPar2: hszInstServName
83 #define WM_DDEML_UNREGISTER WM_USER+2
92 HSZ hszPartner
; // Name of partner application
93 HSZ hszServiceReq
; // Service name
94 HSZ hszTopic
; // Topic name
95 USHORT nStatus
; // ST_* of conversation
96 HCONVLIST hConvList
; // ConvListId , wenn in ConvList
97 CONVCONTEXT aConvContext
; // Conversation context
100 HWND hWndThis
; // 0 == Handle not used
102 PID pidOwner
; // PID des DdeManagers, der
103 // den Conv-Handle erzeugt hat.
104 USHORT nPrevHCONV
; // 0 == no previous hConv or not in list
105 USHORT nNextHCONV
; // 0 == no next hconv or not in list
110 HSZ hszItem
; // Item name
111 USHORT nFormat
; // Data format
112 USHORT nType
; // Transaction type (XTYP_*)
113 // XTYP_ADVREQ [|XTYPF_NODATA] == Advise-Loop
115 // XTYP_EXECUTE == laufendes Execute
120 USHORT nConvst
; // Conversation state (XST_*)
122 // XST_REQSENT (fuer XTYP_ADVREQ)
123 // XST_TIMEOUT (fuer alle Typen!)
124 // XST_WAITING (alle ausser XTYP_ADVREQ)
125 USHORT nLastError
; // last err in transaction
126 ULONG nUser
; // Userhandle
128 HCONV hConvOwner
; // 0 == Transaction not used
132 struct ImpWndProcParams
141 HSZ hBaseServName
; // Basis-Name des Service
142 HSZ hInstServName
; // Basis-Name + DDEML-Server-HWND der App
147 // Daten eines Conversation-Windows
148 struct ImpConvWndData
151 USHORT nRefCount
; // Zahl Conversations auf diesem Window
155 // systemglobale Daten der Library (liegen in named shared memory)
160 ULONG nOffsConvTable
;
161 ULONG nOffsTransTable
;
163 USHORT nMaxConvCount
;
164 USHORT nMaxTransCount
;
167 USHORT nCurTransCount
;
168 USHORT nCurConvCount
;
169 HWND aAppTable
[ 1 ]; // fuer Broadcast-Messages
170 ImpHCONV aConvTable
[ 1 ];
171 Transaction aTransTable
[ 1 ];
178 friend MRESULT EXPENTRY
ConvWndProc(HWND hWnd
,ULONG nMsg
,MPARAM nPar1
,MPARAM nPar2
);
179 friend MRESULT EXPENTRY
ServerWndProc(HWND hWnd
,ULONG nMsg
,MPARAM nPar1
,MPARAM nPar2
);
180 friend void ImpWriteDdeStatus(char*,char*);
181 friend void ImpAddHSZ( HSZ
, String
& );
183 static PSZ
AllocAtomName( ATOM hString
, ULONG
& rBufLen
);
184 static PDDESTRUCT
MakeDDEObject( HWND hwnd
, ATOM hItemName
,
185 USHORT fsStatus
, USHORT usFormat
, PVOID pabData
, ULONG usDataLen
);
186 static APIRET
AllocNamedSharedMem( PPVOID ppBaseAddress
, PSZ pName
,
187 ULONG nElementSize
, ULONG nElementCount
);
191 PFNCALLBACK pCallback
;
192 ULONG nTransactFilter
;
193 CONVCONTEXT aDefaultContext
;
194 ImpDdeMgrData
* pData
;
195 ImpService
* pServices
;
196 USHORT nServiceCount
;
198 ImpHCONV
* pConvTable
; // liegt in pData (nicht deleten!)
199 Transaction
* pTransTable
; // liegt in pData (nicht deleten!)
200 HWND
* pAppTable
; // liegt in pData (nicht deleten!)
202 static ImpHCONV
* GetConvTable( ImpDdeMgrData
* );
203 static Transaction
* GetTransTable( ImpDdeMgrData
* );
204 static HWND
* GetAppTable( ImpDdeMgrData
* );
207 static HWND
NextFrameWin( HENUM hEnum
);
208 void CreateServerWnd();
209 void DestroyServerWnd();
210 HWND
CreateConversationWnd();
211 // Fktn. duerfen nur fuer HCONVs aufgerufen werden, die
212 // in der eigenen Applikation erzeugt wurden
213 static void DestroyConversationWnd( HWND hWndConv
);
214 static USHORT
GetConversationWndRefCount( HWND hWndConv
);
215 static USHORT
IncConversationWndRefCount( HWND hWndConv
);
217 MRESULT
SrvWndProc(HWND hWnd
,ULONG nMsg
,MPARAM nPar1
,MPARAM nPar2
);
218 MRESULT
ConvWndProc(HWND hWnd
,ULONG nMsg
,MPARAM nPar1
,MPARAM nPar2
);
219 void RegisterDDEMLApp();
220 void UnregisterDDEMLApp();
222 ImpDdeMgrData
* InitAll();
223 static BOOL
MyWinDdePostMsg( HWND
, HWND
, USHORT
, PDDESTRUCT
, ULONG
);
224 void MyInitiateDde( HWND hWndServer
, HWND hWndClient
,
225 HSZ hszService
, HSZ hszTopic
, CONVCONTEXT
* pCC
);
226 DDEINIT
* CreateDDEInitData( HWND hWndDest
, HSZ hszService
,
227 HSZ hszTopic
, CONVCONTEXT
* pCC
);
228 // wenn pDDEData==0, muss pCC gesetzt sein
229 HCONV
ConnectWithClient( HWND hWndClient
, HSZ hszPartner
,
230 HSZ hszService
, HSZ hszTopic
, BOOL bSameInst
,
231 DDEINIT
* pDDEData
, CONVCONTEXT
* pCC
= 0);
233 HCONV
CheckIncoming( ImpWndProcParams
*, ULONG nTransMask
,
235 // fuer Serverbetrieb. Ruft Callback-Fkt fuer alle offenen Advises
236 // auf, deren Owner der uebergebene HCONV ist.
237 // bFreeTransactions==TRUE: loescht die Transaktionen
238 // gibt Anzahl der getrennten Transaktionen zurueck
239 USHORT
SendUnadvises( HCONV hConv
,
240 USHORT nFormat
, // 0==alle
241 BOOL bFreeTransactions
);
244 Transaction
* pTrans
, ULONG nTransId
,
248 // DDEML ruft Callback mit XTYP_CONNECT-Transaction nur auf,
249 // wenn die App den angeforderten Service registriert hat
250 // Standardeinstellung: TRUE
253 // Fehlercode muss noch systemglobal werden (Atom o. ae.)
254 static USHORT nLastErrInstance
; // wenn 0, dann gilt globaler Fehlercode
256 static ImpDdeMgrData
* AccessMgrData();
258 static HCONV
CreateConvHandle( ImpDdeMgrData
* pBase
,
260 HWND hWndThis
, HWND hWndPartner
,
261 HSZ hszPartner
, HSZ hszServiceReq
, HSZ hszTopic
,
262 HCONV hPrevHCONV
= 0 );
264 static HCONV
IsConvHandleAvailable( ImpDdeMgrData
* pBase
);
265 static HCONV
GetConvHandle( ImpDdeMgrData
* pBase
,
266 HWND hWndThis
, HWND hWndPartner
);
267 static void FreeConvHandle( ImpDdeMgrData
*, HCONV
,
268 BOOL bDestroyHWndThis
= TRUE
);
270 static ULONG
CreateTransaction( ImpDdeMgrData
* pBase
,
271 HCONV hOwner
, HSZ hszItem
, USHORT nFormat
,
272 USHORT nTransactionType
);
273 static ULONG
GetTransaction( ImpDdeMgrData
* pBase
,
274 HCONV hOwner
, HSZ hszItem
, USHORT nFormat
);
276 static void FreeTransaction( ImpDdeMgrData
*, ULONG nTransId
);
278 BOOL
DisconnectAll();
279 // Transaktionen muessen _vor_ den Konversationen geloescht werden!
280 static void FreeTransactions( ImpDdeMgrData
*, HWND hWndThis
,
282 static void FreeTransactions( ImpDdeMgrData
*, HCONV hConvOwner
);
284 static void FreeConversations( ImpDdeMgrData
*,HWND hWndThis
,
287 ImpService
* GetService( HSZ hszService
);
288 ImpService
* PutService( HSZ hszService
);
289 void BroadcastService( ImpService
*, BOOL bRegistered
);
291 // rh: Startposition(!) & gefundener Handle
292 static ImpHCONV
* GetFirstServer( ImpDdeMgrData
*, HCONVLIST
, HCONV
& rh
);
293 static ImpHCONV
* GetLastServer( ImpDdeMgrData
*, HCONVLIST
, HCONV
& );
294 static BOOL
CheckConvListId( HCONVLIST hConvListId
);
296 BOOL
IsSameInstance( HWND hWnd
);
297 HSZ
GetAppName( HWND hWnd
);
301 MRESULT
DdeAck( ImpWndProcParams
* pParams
);
302 MRESULT
DdeAdvise( ImpWndProcParams
* pParams
);
303 MRESULT
DdeData( ImpWndProcParams
* pParams
);
304 MRESULT
DdeExecute( ImpWndProcParams
* pParams
);
305 MRESULT
DdeInitiate( ImpWndProcParams
* pParams
);
306 MRESULT
DdeInitiateAck( ImpWndProcParams
* pParams
);
307 MRESULT
DdePoke( ImpWndProcParams
* pParams
);
308 MRESULT
DdeRequest( ImpWndProcParams
* pParams
);
309 MRESULT
DdeTerminate( ImpWndProcParams
* pParams
);
310 MRESULT
DdeUnadvise( ImpWndProcParams
* pParams
);
311 MRESULT
DdeRegister( ImpWndProcParams
* pParams
);
312 MRESULT
DdeUnregister( ImpWndProcParams
* pParams
);
313 MRESULT
DdeTimeout( ImpWndProcParams
* pParams
);
316 USHORT nTransactionType
,
317 USHORT nClipboardFormat
,
318 HCONV hConversationHandle
,
325 HCONV
DdeConnectImp( HSZ hszService
,HSZ hszTopic
,CONVCONTEXT
* pCC
);
328 HCONV hCurConv
; // wird im DdeInitiateAck gesetzt
329 HCONVLIST hCurListId
; // fuer DdeConnectList
330 USHORT nPrevConv
; // .... "" ....
333 // synchr. transaction data
336 HDDEDATA hSyncResponseData
;
337 ULONG nSyncResponseMsg
; // WM_DDE_ACK, WM_DDE_DATA, WM_TIMER
338 // TRUE==nach Ende der synchronen Transaktion eine evtl. benutzte
339 // asynchrone Transaktion beenden (typisch synchroner Request auf
341 BOOL bSyncAbandonTrans
;
347 USHORT
DdeInitialize( PFNCALLBACK pCallbackProc
, ULONG nTransactionFilter
);
348 USHORT
DdeGetLastError();
350 HCONV
DdeConnect( HSZ hszService
, HSZ hszTopic
, CONVCONTEXT
* );
351 HCONVLIST
DdeConnectList( HSZ hszService
, HSZ hszTopic
,
352 HCONVLIST hConvList
, CONVCONTEXT
* );
353 static BOOL
DdeDisconnect( HCONV hConv
);
354 static BOOL
DdeDisconnectList( HCONVLIST hConvList
);
355 static HCONV
DdeReconnect(HCONV hConv
);
356 static HCONV
DdeQueryNextServer(HCONVLIST hConvList
, HCONV hConvPrev
);
357 static USHORT
DdeQueryConvInfo(HCONV hConv
, ULONG idTrans
,CONVINFO
* pCI
);
358 static BOOL
DdeSetUserHandle(HCONV hConv
, ULONG id
, ULONG hUser
);
359 BOOL
DdeAbandonTransaction( HCONV hConv
, ULONG idTransaction
);
361 BOOL
DdePostAdvise( HSZ hszTopic
, HSZ hszItem
);
362 BOOL
DdeEnableCallback( HCONV hConv
, USHORT wCmd
);
364 HDDEDATA
DdeNameService( HSZ hszService
, USHORT afCmd
);
366 static HDDEDATA
DdeClientTransaction(void* pData
, ULONG cbData
,
367 HCONV hConv
, HSZ hszItem
, USHORT wFmt
, USHORT wType
,
368 ULONG dwTimeout
, ULONG
* pdwResult
);
372 HDDEDATA
DdeCreateDataHandle( void* pSrc
, ULONG cb
, ULONG cbOff
,
373 HSZ hszItem
, USHORT wFmt
, USHORT afCmd
);
374 static BYTE
* DdeAccessData(HDDEDATA hData
, ULONG
* pcbDataSize
);
375 static BOOL
DdeUnaccessData(HDDEDATA hData
);
376 static BOOL
DdeFreeDataHandle(HDDEDATA hData
);
377 static HDDEDATA
DdeAddData(HDDEDATA hData
,void* pSrc
,ULONG cb
,ULONG cbOff
);
378 static ULONG
DdeGetData(HDDEDATA hData
,void* pDst
,ULONG cbMax
,ULONG cbOff
);
382 static HSZ
DdeCreateStringHandle( PSZ pStr
, int iCodePage
);
383 static ULONG
DdeQueryString(HSZ hsz
,PSZ pStr
,ULONG cchMax
,int iCPage
);
384 static BOOL
DdeFreeStringHandle( HSZ hsz
);
385 static BOOL
DdeKeepStringHandle( HSZ hsz
);
386 static int DdeCmpStringHandles(HSZ hsz1
, HSZ hsz2
);
388 // mit dieser Funktion kann geprueft werden, ob eine
389 // Applikation schon eine DDEML-Instanz angelegt hat.
390 // Die aktuelle Impl. unterstuetzt nur eine DDEML-Instanz
391 // pro Applikation (wg. synchroner Transaktionen)
392 static ImpDdeMgr
* GetImpDdeMgrInstance( HWND hWnd
);
394 // gibt TRUE zurueck, wenn mind. ein lebender HCONV
395 // von diesem DdeMgr erzeugt wurde
396 BOOL
OwnsConversationHandles();
400 inline ImpHCONV
* ImpDdeMgr::GetConvTable( ImpDdeMgrData
* pData
)
404 pRet
= (ImpHCONV
*)((ULONG
)(pData
) + pData
->nOffsConvTable
);
411 inline Transaction
* ImpDdeMgr::GetTransTable( ImpDdeMgrData
* pData
)
415 pRet
= (Transaction
*)((ULONG
)(pData
) + pData
->nOffsTransTable
);
422 inline HWND
* ImpDdeMgr::GetAppTable( ImpDdeMgrData
* pData
)
426 pRet
= (HWND
*)((ULONG
)(pData
) + pData
->nOffsAppTable
);