home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_C
/
CENVIW9.ZIP
/
DDECLI.LIB
< prev
next >
Wrap
Text File
|
1994-03-08
|
18KB
|
448 lines
// DDEcli.lib - Library for common Client portion of DDE functions.
// ver.1
//
//***** struct ddeSession: Structure to define a session
// Many of the following functions refer to the parameters of a dde
// session in some or all elements of a ddeSession structure, which
// contains the following members (along with other non-documented
// members that should be of no concern):
// .Application: string - DDE Server application name
// .Topic: string - DDE Server string
// .hwndClient: int - Window handle of the DDE client
// .hwndServer: int - Window handle of the DDE server
// .TerminateFunction: string - function to call when other party terminates
//
//
//***** ServerDirectory(): Get the handle for this window
// SYNTAX: int ServerDirectory(string Application,string Topic,struct[] ServerList)
// WHERE: Application: DDE Server application string, or NULL for ALL
// Topic: DDE Server Topic, or NULL for ALL
// ServerList: array created for each entry. Array elements are:
// .Application - Returned application name
// .Topic - Returned Topic name
// RETURN: Count of elements in ServerList
// MODIFY: Modifies ServerList to be an array. Undefined if returns 0.
//
//
//**** ConnectToServer(): Initialize (as client) session with server
// SYNTAX: bool ConnectToServer(struct ddeSession)
// WHERE: ddeSession with these parameters:
// .Application: DDE Server application string, or NULL for ALL
// .Topic: DDE Server Topic, or NULL for ALL
// RETURN: Returns True if server found, else False
// MODIFY: Sets the following fields if successful
// .Application: DDE Server application string returned by Server
// .Topic: DDE Server Topic returned by server
// .hwndClient: unique window handle
// .hwndServer: (probably) unique window handle
//
//
//**** DisconnectFromServer(): Terminate client connection with server
// SYNTAX: void DisconnectFromServer(struct ddeSession)
//
//
// NOTE: If more than one server responds to the posting for Application:Topic,
// only the first connection will be maintained.
// TerminateFunction: Name of a function to call if the server should
// terminate this connection without us asking it to. If NULL
// then function not called. Called like this:
// TerminateFunction(ddeSession)
// RETURN: Return ServerHandle, which is the handle of the server connected
// to. This ServerHandle
//
//
//**** RequestDataFromServer()
// SYNTAX: string RequestDataFromServer(struct ddeSession,string Item[,int Timeout])
//
// RETURN: NULL if no data for this item or if connection failed, else ascii
// string is the data for this item
//
//
//**** DataLinkToServer()
// SYNTAX: bool DataLinkToServer(struct ddeSession,string Item,
// string NewDataFunction,bool SendData[,var OtherVar[,int Timeout]])
// WHERE: NewDataFunction is of the form:
// void NewDataFunction(ddeSession,string Item,string Data,var OtherVar)
//
// NOTE: In the format without NewDataFunction, then server data is retrieved
// with DataLinkGetNext()
//
//**** DefDataLinkToServer()
// SYNTAX: bool DefDataLinkToServer(struct ddeSession,string Item[,var OtherVar[,int Timeout]])
//
//
//**** DefDataLinkGet()
// SYNTAX: string DefDataLinkGet(struct ddeSession,string Item[,bool WaitForData[,var OtherVar]])
// WHERE: Item: string to get data for. If NULL then get any Item. If !defined then
// retrieve any item AND set Item to the string retrieved
// WaitForData: True to wait until data arrives, else return immediately whether
// data available or not. Default TRUE
// OtherVar: Same var passed in DefDataLinkToServer()
//
//
//**** DataUnlink(ddeSession[,Item[,int Timeout]])
//
// Item is NULL to terminate ALL hotlinks
//
//
//**** DdeExecute()
// SYNTAX: bool DdeExecute(struct ddeSession,string Commands[,int Timeout])
//
#include <DDE.lib>
#define WM_NCDESTROY 0x0082
DDELibClientFunction(hwnd,msg,wParm,lParm,pddeSession)
{
if ( WM_DESTROY == msg ) {
// if there is still a connection, then end links and post terminate message
if ( defined(pddeSession.hwndServer) ) {
DataUnlink(pddeSession);
PostMessage(pddeSession.hwndServer,WM_DDE_TERMINATE,hwnd,0);
}
undefine(pddeSession.hwndServer);
undefine(pddeSession.HotLink);
return;
}
// skip any messages that aren't for this session from our server while
// we're waiting for a message (except for WM_DDE_INITIATE)
if ( !defined(pddeSession.hwndServer) || wParm != pddeSession.hwndServer ) {
if ( WM_DDE_INITIATE != pddeSession.PostedMessage )
return;
}
switch ( msg ) {
case WM_DDE_ACK:
if ( WM_DDE_INITIATE == pddeSession.PostedMessage ) {
if ( defined(pddeSession.hwndServer) ) {
// already found a serer, so terminate this new connection
PostMessage(wParm,WM_DDE_TERMINATE,hwnd,0);
} else {
// We have a connection!
ClientWmDdeAckInitiate(pddeSession,wParm,LoWord(lParm),HiWord(lParm));
}
return(0);
} else {
lDdeAck = WordToDdeAck(LoWord(lParm));
switch ( pddeSession.PostedMessage ) {
case WM_DDE_UNADVISE:
// unadvise message was accepted
case WM_DDE_REQUEST:
// dang, data wasn't found
pddeSession.ItemAtom = HiWord(lParm);
pddeSession.PostedMessage = 0;
return(0);
case WM_DDE_ADVISE:
// check that it's the same name we're looking for
if ( !stricmp(GetAtomString(HiWord(lParm)),pddeSession.Item) ) {
// this is the message response to our advise link request
pddeSession.PostedMessage = 0;
pddeSession.MakeLinkSuccess = lDdeAck.fAck;
return(0);
}
break;
case WM_DDE_EXECUTE:
if ( HiWord(lParm) == pddeSession.hCommand ) {
pddeSession.ExecuteSuccess = lDdeAck.fAck;
pddeSession.PostedMessage = 0;
return(0);
}
break;
}
}
break;
case WM_DDE_DATA:
ClientWmDdeData(pddeSession,LoWord(lParm),HiWord(lParm));
return 0;
case WM_DDE_TERMINATE:
PostMessage(wParm,WM_DDE_TERMINATE,hwnd,0);
if ( defined(pddeSession.TerminateFunction) ) {
function(pddeSession.TerminateFunction,pddeSession);
DataUnlink(pddeSession);
}
undefine(pddeSession.hwndServer);
undefine(pddeSession.HotLink);
pddeSession.PostedMessage = 0;
return 0;
}
}
ClientWmDdeData(pddeSession,hDdeData,aItem)
{
// Get ascii name of the data item
lItem = GetAtomString(aItem);
if ( hDdeData )
lDdeData = DdeDataHandleToStructure(hDdeData);
// Initialize DDeAck structure
lDdeAck.bAppReturnedCode = 0;
lDdeAck.fBusy = FALSE;
lDdeAck.fAck = FALSE;
// Is this in response to WM_DDE_REQUEST, or is it a link
lRequested = WM_DDE_REQUEST == pddeSession.PostedMessage
&& !stricmp(lItem,pddeSession.Item)
&& hDdeData && CF_TEXT == lDdeData.cfFormat;
if ( lRequested ) {
pddeSession.PostedMessage = 0;
pddeSession.Data = lDdeData.Value;
lDdeAck.fAck = TRUE ;
// Save atom to be deleted when done
pddeSession.ItemAtom = aItem;
} else {
// check if we are in link mode, and so may be looking for warm or hot link
if ( defined(ddeSession.HotLink)
&& ( !hDdeData || CF_TEXT == lDdeData.cfFormat ) ) {
for ( lIndex = GetArraySpan(ddeSession.HotLink); 0 <= lIndex; lIndex-- ) {
if ( !stricmp(ddeSession.HotLink[lIndex].Item,lItem) ) {
lHotLink = ddeSession.HotLink[lIndex];
lDdeAck.fAck = TRUE;
break;
}
}
}
}
// Acknowledge if necessary
if ( lDdeData.fAckReq ) {
wStatus = DdeAckToWord(lDdeAck);
if ( !PostMessage(wParam,WM_DDE_ACK,pddeSession.hwndClient,wStatus,aItem) ) {
GlobalFree (hDdeData) ;
if ( !lRequested ) GlobalDeleteAtom(aItem);
return;
}
} else
if ( !lRequested ) GlobalDeleteAtom(aItem);
// Clean up
if ( lDdeData.fRelease || !lDdeAck.fAck )
GlobalFree (hDdeData) ;
if ( defined(lHotLink) ) {
function( lHotLink.NewDataFunction,pddeSession, lHotLink.Item,
hDdeData ? lDdeData.Value : NULL, lHotLink.OtherVar );
}
}
ClientWmDdeAckInitiate(pddeSession,pServerHandle,pAtomApp,pAtomTopic)
{
pddeSession.hwndServer = pServerHandle;
pddeSession.Application = GetAtomString(pAtomApp);
pddeSession.Topic = GetAtomString(pAtomTopic);
}
ConnectToServer(pddeSession)
{
undefine(pddeSession.hwndServer);
pddeSession.PostedMessage = 0;
pddeSession.hwndClient = MakeWindow(DDELibMainHwnd,NULL,"DDELibClientFunction",
NULL,WS_CHILD,0,0,0,0,NULL,pddeSession);
if ( pddeSession.hwndClient ) {
// try to connect to server
csAtomApp = pddeSession.Application ? GlobalAddAtom(pddeSession.Application) : 0 ;
csAtomTop = pddeSession.Topic ? GlobalAddAtom(pddeSession.Topic) : 0 ;
// Send message to all windows to initiate DDE connection
Multitask(False);
pddeSession.PostedMessage = WM_DDE_INITIATE;
SendMessage(0xFFFF,WM_DDE_INITIATE,pddeSession.hwndClient,csAtomApp,csAtomTop);
pddeSession.PostedMessage = 0;
MultiTask(True);
// undo atoms that were made
if ( csAtomApp ) GlobalDeleteAtom(csAtomApp);
if ( csAtomTop ) GlobalDeleteAtom(csAtomTop);
if ( !defined(pddeSession.hwndServer) ) {
// connection didn't work, and so remove the window
BreakWindow(pddeSession.hwndClient);
}
}
return( defined(pddeSession.hwndServer) );
}
DisconnectFromServer(pddeSession)
{
// client session. Simply close the client window
BreakWindow(pddeSession.hwndClient);
}
RequestDataFromServer(pddeSession,pItem,pTimeout)
{
pddeSession.ItemAtom = GlobalAddAtom(pItem);
pddeSession.Item = pItem;
pddeSession.Data = NULL;
Multitask(False);
if ( defined(pddeSession.hwndServer)
&& PostMessage(pddeSession.hwndServer,pddeSession.PostedMessage = WM_DDE_REQUEST,
pddeSession.hwndClient,CF_TEXT,pddeSession.ItemAtom) )
DoPostedDDEMessage(pddeSession,2 < va_arg() ? pTimeout : DEFAULT_TIMEOUT );
pddeSession.PostedMessage = 0;
Multitask(True);
GlobalDeleteAtom(pddeSession.ItemAtom);
undefine( pddeSession.Item );
return(pddeSession.Data);
}
DataLinkToServer(pddeSession,pItem,pNewDataFunction,pSendData,pOtherVar,pTimeout)
{
bool lSuccess = False; // assume failure
pddeSession.ItemAtom = GlobalAddAtom(pItem);
pddeSession.Item = pItem;
lDdeAdvise.fAckReq = TRUE ;
lDdeAdvise.fDeferUpd = pSendData ? FALSE : TRUE ;
lDdeAdvise.cfFormat = CF_TEXT ;
hDdeAdvise = DdeAdviseStuctureToHandle(lDdeAdvise);
Multitask(False);
if ( defined(pddeSession.hwndServer) ) {
// This link will be added to the end of the HotLink array
pddeSession.MakeLinkSuccess = False; // assume failure
if ( PostMessage(pddeSession.hwndServer,pddeSession.PostedMessage = WM_DDE_ADVISE,
pddeSession.hwndClient,hDdeAdvise,pddeSession.ItemAtom) )
DoPostedDDEMessage(pddeSession,5 < va_arg() ? pTimeout : DEFAULT_TIMEOUT );
pddeSession.PostedMessage = 0;
if ( pddeSession.MakeLinkSuccess ) {
lSuccess = True;
lLinkIndex = defined(ddeSession.HotLink) ? 1 + GetArraySpan(ddeSession.HotLink): 0 ;
strcpy( ddeSession.HotLink[lLinkIndex].Item, pItem );
strcpy( ddeSession.HotLink[lLinkIndex].NewDataFunction, pNewDataFunction );
ddeSession.HotLink[lLinkIndex].OtherVar = pOtherVar;
}
undefine(pddeSession.MakeLinkSuccess);
}
Multitask(True);
if ( !lSuccess )
GlobalFree(hDdeAdvise);
GlobalDeleteAtom(pddeSession.ItemAtom);
undefine( pddeSession.Item );
return(lSuccess);
}
DefDataLinkToServer(pddeSession,pItem,pOtherVar,pTimeout)
{
switch( va_arg() ) {
case 2: return DataLinkToServer(pddeSession,pItem,"DefaultNewDataFunction",TRUE,0);
case 3: return DataLinkToServer(pddeSession,pItem,"DefaultNewDataFunction",TRUE,pOtherVar);
case 4: return DataLinkToServer(pddeSession,pItem,"DefaultNewDataFunction",TRUE,pOtherVar,pTimeout);
}
abort(); // should'nt get here
}
DataUnlink(pddeSession,pItem,pTimeout)
{
// find this link in current array
if ( defined(pddeSession.HotLink) ) {
lItem = ( 1 == va_arg() ) ? NULL : pItem ;
MultiTask(False);
if ( !lItem ) {
undefine(pddeSession.HotLink);
undefine(pddeSession.DefaultReceiveList);
} else {
lArraySpan = GetArraySpan(pddeSession.HotLink);
for ( lIndex = lArraySpan; 0 <= lIndex; lIndex-- ) {
if ( !stricmp(lItem,pddeSession.HotLink[lIndex].Item) ) {
if ( !strcmp(pddeSession.HotLink[lIndex].NewDataFunction,"DefaultNewDataFunction") ) {
// this is a default data function; remove waiting instances
while ( DefDataLinkGet(pddeSession,lItem,False) ) ;
}
// remove this element from array, and shrink the rest down
if ( 0 == lArraySpan )
undefine(pddeSession.HotLink);
else {
while ( lIndex++ < lArraySpan )
pddeSession.HotLink[lIndex-1] = pddeSession.HotLink[lIndex];
SetArraySpan(pddeSession.HotLink,lArraySpan-1);
}
break;
}
}
}
if ( !lItem || 0 <= lIndex ) {
// send server message to stop advising about this item
pddeSession.ItemAtom = lItem ? GlobalAddAtom(lItem) : 0;
pddeSession.Item = lItem;
if ( defined(pddeSession.hwndServer) ) {
if ( PostMessage(pddeSession.hwndServer,pddeSession.PostedMessage = WM_DDE_UNADVISE,
pddeSession.hwndClient,CF_TEXT,pddeSession.ItemAtom) )
DoPostedDDEMessage(pddeSession,2 < va_arg() ? pTimeout : DEFAULT_TIMEOUT );
pddeSession.PostedMessage = 0;
}
if ( pddeSession.ItemAtom )
GlobalDeleteAtom(pddeSession.ItemAtom);
}
}
Multitask(True);
}
DefaultNewDataFunction(pddeSession,pItem,pData,pOtherVar)
{ // add this new data to the end of maintained DefaultReceiveList
if ( pData ) {
// add this new data to the end of the list
lIndex = defined(pddeSession.DefaultReceiveList)
? 1 + GetArraySpan(pddeSession.DefaultReceiveList) : 0 ;
strcpy(pddeSession.DefaultReceiveList[lIndex].Item,pItem);
strcpy(pddeSession.DefaultReceiveList[lIndex].Data,pData);
pddeSession.DefaultReceiveList[lIndex].OtherVar = pOtherVar;
}
}
DefDataLinkGet(pddeSession,pItem,pWaitForData,pOtherVar)
{
lData = NULL; // assume failure
lWaitForData = 2 < va_arg() ? pWaitForData : TRUE ;
do {
// Find Item in our list of received data
MultiTask(False);
if ( defined(pddeSession.DefaultReceiveList) ) {
lReceiveCount = 1 + GetArraySpan(pddeSession.DefaultReceiveList);
for ( li = 0; li < lReceiveCount; li++ ) {
if ( !defined(pItem) || !pItem
|| !stricmp(pItem,pddeSession.DefaultReceiveList[li].Item) ) {
lData = pddeSession.DefaultReceiveList[li].Data;
if ( 3 < va_arg() ) pOtherVar = pddeSession.DefaultReceiveList[li].OtherVar;
if ( !defined(pItem) ) pItem = pddeSession.DefaultReceiveList[li].Item;
// remove this data from the DefaultReceiveList, and compact array
for ( lj = li + 1; lj < lReceiveCount; lj++ )
pddeSession.DefaultReceiveList[lj-1] = pddeSession.DefaultReceiveList[lj];
if ( 0 == --lReceiveCount )
undefine(pddeSession.DefaultReceiveList);
else
SetArraySpan(pddeSession.DefaultReceiveList,lReceiveCount-1);
break;
}
}
}
MultiTask(True);
} while ( !lData && lWaitForData && defined(pddeSession.hwndServer) && DoWindows() );
return lData;
}
DdeExecute(pddeSession,pCommands,pTimeout)
{
lCommandLen = 1 + strlen(pCommands);
pddeSession.ExecuteSuccess = False; // assume failure
assert( pddeSession.hCommand = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,lCommandLen) );
poke(GlobalLock(pddeSession.hCommand),pCommands,lCommandLen);
GlobalUnlock(pddeSession.hCommand);
Multitask(False);
if ( defined(pddeSession.hwndServer) ) {
if ( PostMessage(pddeSession.hwndServer,pddeSession.PostedMessage = WM_DDE_EXECUTE,
pddeSession.hwndClient,0,pddeSession.hCommand) )
DoPostedDDEMessage(pddeSession,2 < va_arg() ? pTimeout : DEFAULT_TIMEOUT );
pddeSession.PostedMessage = 0;
}
Multitask(True);
// if it worked then hCommand will have been set to 0
GlobalFree(pddeSession.hCommand);
return pddeSession.ExecuteSuccess;
}