home *** CD-ROM | disk | FTP | other *** search
Wrap
///////////////////////////////////////////////////////////////////////////// /* File: mfcdde.cc Purpose: Dde class for MFC Author: Julian Smart */ ///////////////////////////////////////////////////////////////////// // Includes - For compilers that support precompilation, include "wx.h". // #include "stdafx.h" // #include "wx_utils.h" #include "mfcdde.h" #include <ddeml.h> #ifdef WIN32 #define _EXPORT #else #define _EXPORT _export #endif ///////////////////////////////////////////////////////////////////// // Function Prototypes // static CDdeConnection * DdeFindConnection(HCONV hConv); static void DdeDeleteConnection(HCONV hConv); static CDdeServer * DdeFindServer(const CString& m_sServiceName); extern "C" HDDEDATA EXPENTRY _EXPORT _DdeCallback(WORD wType, WORD wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD lData1, DWORD lData2); ///////////////////////////////////////////////////////////////////// // Add topic name to atom table before using in conversations // static HSZ DdeAddAtom(const CString& sAtomName); static HSZ DdeGetAtom(const CString& sAtomName); static void DdePrintError(void); ///////////////////////////////////////////////////////////////////// // Globals // static DWORD g_nDdeIdInst = 0L; static CMapStringToOb g_DdeAtomTable; static CObList g_DdeObjects; char * g_pDdeDefaultIpcBuffer = NULL; int g_nDdeDefaultIpcBufferSize = MAX_PATH; BOOL g_bDdeInitialized = FALSE; ///////////////////////////////////////////////////////////////////////////// /* Function: DdeInitialize Description: Return type: void Notes: */ void DdeInitialize() { if (g_bDdeInitialized) { return; } g_bDdeInitialized = TRUE; // Should insert filter flags DdeInitialize(&g_nDdeIdInst, (PFNCALLBACK)MakeProcInstance( (FARPROC)_DdeCallback, AfxGetInstanceHandle()), APPCLASS_STANDARD, 0L); } ///////////////////////////////////////////////////////////////////////////// /* Function: DdeCleanUp Description: Return type: void Notes: */ void DdeCleanUp() { if (g_nDdeIdInst != 0) { DdeUninitialize(g_nDdeIdInst); g_nDdeIdInst = 0; } if (g_pDdeDefaultIpcBuffer) { delete [] g_pDdeDefaultIpcBuffer; } } ///////////////////////////////////////////////////////////////////// // Base class Dde object (CDdeObject) // ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeObject::CDdeObject Description: Dde Object constructor - automatically adds this object to the global list of Dde objects. Return type: Argument: void Notes: */ CDdeObject::CDdeObject(void) { m_sServiceName = ""; g_DdeObjects.AddTail(this); } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeObject::~CDdeObject Description: Dde Object destructor - automatically removes this Dde object from the global list. Return type: Argument: void Notes: */ CDdeObject::~CDdeObject(void) { POSITION pos = g_DdeObjects.Find(this); if (pos) { g_DdeObjects.RemoveAt(pos); } pos = m_Connections.GetHeadPosition(); CDdeConnection *pConnection = NULL; while (pos && (pConnection = (CDdeConnection *)m_Connections.GetNext(pos))) { pConnection->OnDisconnect(); // may delete the node implicitly } // If any left after this, delete them pos = m_Connections.GetHeadPosition(); pConnection = NULL; while (pos && (pConnection = (CDdeConnection *)m_Connections.GetNext(pos))) { delete pConnection; } } ///////////////////////////////////////////////////////////////////////////// /* Function: *DdeFindConnection Description: Find a Dde connection Return type: static CDdeConnection Argument: HCONV hConv Notes: */ static CDdeConnection *DdeFindConnection(HCONV hConv) { CDdeObject *pDdeObject = NULL; POSITION pos = g_DdeObjects.GetHeadPosition(); while (pos && (pDdeObject = (CDdeObject *)g_DdeObjects.GetNext(pos))) { CDdeConnection *pConnection = pDdeObject->FindConnection(hConv); if (pConnection) { return pConnection; } } return NULL; /* wxNode *node = g_DdeObjects.First(); CDdeConnection *found = NULL; while (node && !found) { CDdeObject *object = (CDdeObject *)node->Data(); found = object->FindConnection(hConv); node = node->Next(); } return found; */ } ///////////////////////////////////////////////////////////////////////////// /* Function: DdeDeleteConnection Description: Global delete connection Return type: static void Argument: HCONV hConv Notes: */ static void DdeDeleteConnection(HCONV hConv) { CDdeObject *pDdeObject = NULL; BOOL bFound = FALSE; POSITION pos = g_DdeObjects.GetHeadPosition(); while (!bFound && pos && (pDdeObject = (CDdeObject *)g_DdeObjects.GetNext(pos))) { bFound = pDdeObject->DeleteConnection(hConv); } /* wxNode *node = g_DdeObjects.First(); BOOL bFound = FALSE; while (node && !bFound) { CDdeObject *object = (CDdeObject *)node->Data(); bFound = object->DeleteConnection(hConv); node = node->Next(); } */ } ///////////////////////////////////////////////////////////////////////////// /* Function: *CDdeObject::FindConnection Description: Finds a connection Return type: CDdeConnection Argument: HCONV hConv Notes: */ CDdeConnection *CDdeObject::FindConnection(HCONV hConv) { POSITION pos = m_Connections.GetHeadPosition(); CDdeConnection *pConnection = NULL; while (pos && (pConnection = (CDdeConnection *)m_Connections.GetNext(pos))) { if (pConnection->m_hConv == hConv) { return pConnection; } } return NULL; } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeObject::DeleteConnection Description: Only delete the entry in the map, not the actual connection Return type: BOOL Argument: HCONV hConv Notes: */ BOOL CDdeObject::DeleteConnection(HCONV hConv) { POSITION pos = m_Connections.GetHeadPosition(); POSITION oldPos = pos; CDdeConnection *pConnection = NULL; while (pos && (pConnection = (CDdeConnection *)m_Connections.GetNext(pos))) { if (pConnection->m_hConv == hConv) { m_Connections.RemoveAt(oldPos); return TRUE; } oldPos = pos; } return FALSE; } ///////////////////////////////////////////////////////////////////////////// /* Function: DdeFindServer Description: Find a server from a service name Return type: static CDdeServer Argument: const CString& m_sServiceName Notes: */ static CDdeServer *DdeFindServer(const CString& m_sServiceName) { CDdeObject *pDdeObject = NULL; POSITION pos = g_DdeObjects.GetHeadPosition(); while (pos && (pDdeObject = (CDdeObject *)g_DdeObjects.GetNext(pos))) { if (pDdeObject->m_sServiceName == m_sServiceName) { return (CDdeServer *)pDdeObject; } } return NULL; /* wxNode *node = g_DdeObjects.First(); CDdeServer *found = NULL; while (node && !found) { CDdeObject *object = (CDdeObject *)node->Data(); if (object->m_sServiceName == m_sServiceName) found = (CDdeServer *)object; else node = node->Next(); } return found; */ } ///////////////////////////////////////////////////////////////////// // Dde Server Object (CDdeServer) // ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeServer::CDdeServer Description: Return type: Argument: void Notes: */ CDdeServer::CDdeServer(void) { } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeServer::Create Description: Return type: BOOL Argument: const CString& sServerName Notes: */ BOOL CDdeServer::Create(const CString& sServerName) { m_sServiceName = sServerName; HSZ hszServiceAtom = DdeCreateStringHandle(g_nDdeIdInst, (const char *)sServerName, CP_WINANSI); if (DdeNameService(g_nDdeIdInst, hszServiceAtom, NULL, DNS_REGISTER) == 0) { DdePrintError(); return FALSE; } return TRUE; } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeServer::~CDdeServer Description: Return type: Argument: void Notes: */ CDdeServer::~CDdeServer(void) { if (m_sServiceName != "") { HSZ hszServiceAtom = DdeCreateStringHandle(g_nDdeIdInst, (const char *)m_sServiceName, CP_WINANSI); if (DdeNameService(g_nDdeIdInst, hszServiceAtom, NULL, DNS_UNREGISTER) == 0) { DdePrintError(); } } } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeServer::OnAcceptConnection Description: Return type: CDdeConnection * Argument: const CString& sTopic Notes: */ CDdeConnection *CDdeServer::OnAcceptConnection(const CString& /* sTopic */) { return new CDdeConnection; } ///////////////////////////////////////////////////////////////////// // Dde Client Object (CDdeClient) // ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeClient::CDdeClient Description: Return type: Argument: void Notes: */ CDdeClient::CDdeClient(void) { } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeClient::~CDdeClient Description: Return type: Argument: void Notes: */ CDdeClient::~CDdeClient(void) { POSITION pos = m_Connections.GetHeadPosition(); CDdeConnection *pConnection = NULL; while (pos && (pConnection = (CDdeConnection *)m_Connections.GetNext(pos))) { delete pConnection; // Deletes entry in m_Connections implicitly } } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeClient::ValidHost Description: Return type: BOOL Argument: const CString& sHostName Notes: */ BOOL CDdeClient::ValidHost(const CString& /* sHostName */) { return TRUE; } ///////////////////////////////////////////////////////////////////////////// /* Function: *CDdeClient::MakeConnection Description: Return type: CDdeConnection Argument: const CString& sHostName Argument: const CString& sServerName Argument: const CString& sTopic Notes: */ CDdeConnection *CDdeClient::MakeConnection(const CString& /* sHostName */, const CString& sServerName, const CString& sTopic) { HSZ hszServiceAtom = DdeCreateStringHandle(g_nDdeIdInst, (const char *)sServerName, CP_WINANSI); HSZ hszTopicAtom = DdeCreateStringHandle(g_nDdeIdInst, (const char *)sTopic, CP_WINANSI); HCONV hConv = DdeConnect(g_nDdeIdInst, hszServiceAtom, hszTopicAtom, (PCONVCONTEXT)NULL); if (hConv == NULL) { return NULL; } else { CDdeConnection *pConnection = OnMakeConnection(); if (pConnection) { pConnection->m_hConv = hConv; pConnection->m_sTopicName = sTopic; pConnection->m_pClient = this; m_Connections.AddTail(pConnection); return pConnection; } else { return NULL; } } } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeClient::OnMakeConnection Description: Return type: CDdeConnection * Argument: void Notes: */ CDdeConnection * CDdeClient::OnMakeConnection(void) { return new CDdeConnection; } ///////////////////////////////////////////////////////////////////// // Dde Client Object (CDdeClient) // ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::CDdeConnection Description: Return type: Argument: char *pIpcBuffer Argument: int nIpcBufferSize Notes: */ CDdeConnection::CDdeConnection(char *pIpcBuffer, int nIpcBufferSize) { if (pIpcBuffer == NULL) { if (g_pDdeDefaultIpcBuffer == NULL) { g_pDdeDefaultIpcBuffer = new char[g_nDdeDefaultIpcBufferSize]; } m_pIpcBuffer = g_pDdeDefaultIpcBuffer; m_nIpcBufferSize = g_nDdeDefaultIpcBufferSize; } else { m_pIpcBuffer = pIpcBuffer; m_nIpcBufferSize = nIpcBufferSize; } m_sTopicName = ""; m_pClient = NULL; m_pServer = NULL; m_hConv = NULL; m_pSendingData = NULL; } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::CDdeConnection Description: Return type: Argument: void Notes: */ CDdeConnection::CDdeConnection(void) { m_nTimeOut = DEFAULT_TIMEOUT; m_hConv = NULL; m_pSendingData = NULL; m_pServer = NULL; m_pClient = NULL; if (g_pDdeDefaultIpcBuffer == NULL) { g_pDdeDefaultIpcBuffer = new char[g_nDdeDefaultIpcBufferSize]; } m_pIpcBuffer = g_pDdeDefaultIpcBuffer; m_nIpcBufferSize = g_nDdeDefaultIpcBufferSize; m_sTopicName = ""; } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::~CDdeConnection Description: Return type: Argument: void Notes: */ CDdeConnection::~CDdeConnection(void) { CDdeObject *pDdeObject = NULL; if (m_pServer) { pDdeObject = m_pServer; } else { pDdeObject = m_pClient; } if (pDdeObject) { POSITION pos = pDdeObject->m_Connections.Find(this); if (pos) { pDdeObject->m_Connections.RemoveAt(pos); } } } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::Disconnect Description: Return type: BOOL Argument: void Notes: */ BOOL CDdeConnection::Disconnect(void) { DdeDeleteConnection(m_hConv); return DdeDisconnect(m_hConv); } ///////////////////////////////////////////////////////////////////// // Calls that CLIENT can make // ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::SetTimeOut Description: Return type: DWORD returns the previous timeout value Argument: DWORD nTimeOut Notes: */ DWORD CDdeConnection::SetTimeOut(DWORD nTimeOut) { DWORD nCurrentTimeOut = m_nTimeOut; m_nTimeOut = nTimeOut; return nCurrentTimeOut; } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::Execute Description: Return type: BOOL Argument: char *pData Argument: int nDataSize Argument: int nFormat Notes: */ BOOL CDdeConnection::Execute(char *pData, int nDataSize, int nFormat) { DWORD dwResult; if (nDataSize < 0) { nDataSize = strlen(pData); } nDataSize ++; return (DdeClientTransaction((LPBYTE)pData, nDataSize, m_hConv, NULL, nFormat, XTYP_EXECUTE, m_nTimeOut, &dwResult) ? TRUE : FALSE); } ///////////////////////////////////////////////////////////////////////////// /* Function: *CDdeConnection::Request Description: Return type: char Argument: const CString& sItem Argument: int *pnDataSize Argument: int nFormat Notes: */ char *CDdeConnection::Request(const CString& sItem, int *pnDataSize, int nFormat) { HSZ hszItemAtom = DdeGetAtom(sItem); HDDEDATA hDdeData = DdeClientTransaction(NULL, 0, m_hConv, hszItemAtom, nFormat, XTYP_REQUEST, m_nTimeOut, NULL); DWORD dwLength = DdeGetData(hDdeData, (LPBYTE)(m_pIpcBuffer), m_nIpcBufferSize, 0); DdeFreeDataHandle(hDdeData); if (pnDataSize) { *pnDataSize = (int)dwLength; } if (dwLength > 0) { return m_pIpcBuffer; } else { return NULL; } } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::Poke Description: Return type: BOOL Argument: const CString& sItem Argument: char *pData Argument: int nDataSize Argument: int nFormat Notes: */ BOOL CDdeConnection::Poke(const CString& sItem, char *pData, int nDataSize, int nFormat) { DWORD dwResult; if (nDataSize < 0) { nDataSize = strlen(pData); } nDataSize ++; HSZ hszItemAtom = DdeGetAtom(sItem); return (DdeClientTransaction((LPBYTE)pData, nDataSize, m_hConv, hszItemAtom, nFormat, XTYP_POKE, m_nTimeOut, &dwResult) ? TRUE : FALSE); } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::StartAdvise Description: Return type: BOOL Argument: const CString& sItem Notes: */ BOOL CDdeConnection::StartAdvise(const CString& sItem) { DWORD dwResult; HSZ hszItemAtom = DdeGetAtom(sItem); return (DdeClientTransaction(NULL, 0, m_hConv, hszItemAtom, CF_TEXT, XTYP_ADVSTART, m_nTimeOut, &dwResult) ? TRUE : FALSE); } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::StopAdvise Description: Return type: BOOL Argument: const CString& sItem Notes: */ BOOL CDdeConnection::StopAdvise(const CString& sItem) { DWORD dwResult; HSZ hszItemAtom = DdeGetAtom(sItem); return (DdeClientTransaction(NULL, 0, m_hConv, hszItemAtom, CF_TEXT, XTYP_ADVSTOP, m_nTimeOut, &dwResult) ? TRUE : FALSE); } ///////////////////////////////////////////////////////////////////// // Calls that SERVER can make // ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::Advise Description: Return type: BOOL Argument: const CString& sItem Argument: char *pData Argument: int nDataSize Argument: int nFormat Notes: */ BOOL CDdeConnection::Advise(const CString& sItem, char *pData, int nDataSize, int nFormat) { if (nDataSize < 0) { nDataSize = strlen(pData); } nDataSize ++; HSZ hszItemAtom = DdeGetAtom(sItem); HSZ hszTopicAtom = DdeGetAtom(m_sTopicName); m_pSendingData = pData; m_nSendingDataSize = nDataSize; m_nSendingDataType = nFormat; return DdePostAdvise(g_nDdeIdInst, hszTopicAtom, hszItemAtom); } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::Notify Description: Return type: void Argument: BOOL Notes: */ void CDdeConnection::Notify(BOOL /* bNotify */) { } ///////////////////////////////////////////////////////////////////////////// /* Function: CDdeConnection::OnDisconnect Description: Return type: BOOL Argument: void Notes: */ BOOL CDdeConnection::OnDisconnect(void) { delete this; return TRUE; } #define DDERETURN HDDEDATA ///////////////////////////////////////////////////////////////////////////// /* Function: _EXPORT _DdeCallback Description: Return type: HDDEDATA EXPENTRY Argument: WORD wType Argument: WORD wFmt Argument: HCONV hConv Argument: HSZ hsz1 Argument: HSZ hsz2 Argument: HDDEDATA hData Argument: DWORD lData1 Argument: DWORD lData2 Notes: */ HDDEDATA EXPENTRY _EXPORT _DdeCallback(WORD wType, WORD wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD /* lData1 */, DWORD /* lData2 */) { static CDdeConnection *pDdeCurrentlyConnecting = NULL; switch (wType) { case XTYP_CONNECT: { char pTopicBuf[100]; char pServerBuf[100]; DdeQueryString(g_nDdeIdInst, hsz1, (LPSTR)pTopicBuf, sizeof(pTopicBuf), CP_WINANSI); DdeQueryString(g_nDdeIdInst, hsz2, (LPSTR)pServerBuf, sizeof(pTopicBuf), CP_WINANSI); CDdeServer *pServer = DdeFindServer(pServerBuf); if (pServer) { CDdeConnection *pConnection = pServer->OnAcceptConnection(CString(pTopicBuf)); if (pConnection) { pConnection->m_pServer = pServer; pServer->m_Connections.AddTail(pConnection); pConnection->m_hConv = 0; pConnection->m_sTopicName = pTopicBuf; pDdeCurrentlyConnecting = pConnection; return (DDERETURN)TRUE; } } else { return (DDERETURN)0; } break; } case XTYP_CONNECT_CONFIRM: { if (pDdeCurrentlyConnecting) { pDdeCurrentlyConnecting->m_hConv = hConv; pDdeCurrentlyConnecting = NULL; return (DDERETURN)TRUE; } else { return 0; } break; } case XTYP_DISCONNECT: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection && pConnection->OnDisconnect()) { DdeDeleteConnection(hConv); // Delete mapping: hConv => pConnection return (DDERETURN)TRUE; } else { return (DDERETURN)0; } break; } case XTYP_EXECUTE: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection) { DWORD dwLength = DdeGetData(hData, (LPBYTE)(pConnection->m_pIpcBuffer), pConnection->m_nIpcBufferSize, 0); DdeFreeDataHandle(hData); if (pConnection->OnExecute(pConnection->m_sTopicName, pConnection->m_pIpcBuffer, (int)dwLength, wFmt)) { return (DDERETURN)DDE_FACK; } else { return (DDERETURN)DDE_FNOTPROCESSED; } } else { return (DDERETURN)DDE_FNOTPROCESSED; } break; } case XTYP_REQUEST: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection) { char pItemName[200]; DdeQueryString(g_nDdeIdInst, hsz2, (LPSTR)pItemName, sizeof(pItemName), CP_WINANSI); int nUserSize = -1; char *pData = pConnection->OnRequest(pConnection->m_sTopicName, CString(pItemName), &nUserSize, wFmt); if (pData) { if (nUserSize < 0) { nUserSize = strlen(pData); } HDDEDATA hDdeData = DdeCreateDataHandle(g_nDdeIdInst, (LPBYTE)pData, nUserSize + 1, 0, hsz2, wFmt, 0); return (DDERETURN)hDdeData; } else { return (DDERETURN)0; } } else { return (DDERETURN)0; } break; } case XTYP_POKE: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection) { char pItemName[200]; DdeQueryString(g_nDdeIdInst, hsz2, (LPSTR)pItemName, sizeof(pItemName), CP_WINANSI); DWORD dwLength = DdeGetData(hData, (LPBYTE)(pConnection->m_pIpcBuffer), pConnection->m_nIpcBufferSize, 0); DdeFreeDataHandle(hData); pConnection->OnPoke(pConnection->m_sTopicName, CString(pItemName), pConnection->m_pIpcBuffer, (int)dwLength, wFmt); return (DDERETURN)DDE_FACK; } else { return (DDERETURN)DDE_FNOTPROCESSED; } break; } case XTYP_ADVSTART: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection) { char pItemName[200]; DdeQueryString(g_nDdeIdInst, hsz2, (LPSTR)pItemName, sizeof(pItemName), CP_WINANSI); return (DDERETURN)pConnection->OnStartAdvise(pConnection->m_sTopicName, CString(pItemName)); } else { return (DDERETURN)0; } break; } case XTYP_ADVSTOP: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection) { char pItemName[200]; DdeQueryString(g_nDdeIdInst, hsz2, (LPSTR)pItemName, sizeof(pItemName), CP_WINANSI); return (DDERETURN)pConnection->OnStopAdvise(pConnection->m_sTopicName, CString(pItemName)); } else { return (DDERETURN)0; } break; } case XTYP_ADVREQ: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection && pConnection->m_pSendingData) { HDDEDATA hDdeData = DdeCreateDataHandle(g_nDdeIdInst, (LPBYTE)pConnection->m_pSendingData, pConnection->m_nSendingDataSize, 0, hsz2, pConnection->m_nSendingDataType, 0); pConnection->m_pSendingData = NULL; return (DDERETURN)hDdeData; } else { return (DDERETURN)NULL; } break; } case XTYP_ADVDATA: { CDdeConnection *pConnection = DdeFindConnection(hConv); if (pConnection) { char pItemName[200]; DdeQueryString(g_nDdeIdInst, hsz2, (LPSTR)pItemName, sizeof(pItemName), CP_WINANSI); DWORD dwLength = DdeGetData(hData, (LPBYTE)(pConnection->m_pIpcBuffer), pConnection->m_nIpcBufferSize, 0); DdeFreeDataHandle(hData); if (pConnection->OnAdvise(pConnection->m_sTopicName, CString(pItemName), pConnection->m_pIpcBuffer, (int)dwLength, wFmt)) { return (DDERETURN)DDE_FACK; } else { return (DDERETURN)DDE_FNOTPROCESSED; } } else { return (DDERETURN)DDE_FNOTPROCESSED; } break; } } return 0; } ///////////////////////////////////////////////////////////////////// // Atom table stuff // ///////////////////////////////////////////////////////////////////////////// /* Function: DdeAddAtom Description: Return type: static HSZ Argument: const CString& sAtomName Notes: */ static HSZ DdeAddAtom(const CString& sAtomName) { HSZ hszAtom = DdeCreateStringHandle(g_nDdeIdInst, (const char *)sAtomName, CP_WINANSI); // g_DdeAtomTable.Append(sAtomName, (CObject *)hszAtom); g_DdeAtomTable.SetAt(sAtomName, (CObject *)hszAtom); return hszAtom; } ///////////////////////////////////////////////////////////////////////////// /* Function: DdeGetAtom Description: Return type: static HSZ Argument: const CString& sAtomName Notes: */ static HSZ DdeGetAtom(const CString& sAtomName) { CObject *data = NULL; if (g_DdeAtomTable.Lookup(sAtomName, data)) { return (HSZ)data; } else { return DdeAddAtom(sAtomName); } /* wxNode *node = g_DdeAtomTable.Find(sAtomName); if (node) return (HSZ)node->Data(); else { DdeAddAtom(sAtomName); return (HSZ)(g_DdeAtomTable.Find(sAtomName)->Data()); } */ } ///////////////////////////////////////////////////////////////////////////// /* Function: DdePrintError Description: Return type: void Argument: void Notes: */ void DdePrintError(void) { char *szErrorText = NULL; switch (DdeGetLastError(g_nDdeIdInst)) { case DMLERR_ADVACKTIMEOUT: szErrorText = "A request for a synchronous advise transaction has timed out."; break; case DMLERR_BUSY: szErrorText = "The response to the transaction caused the Dde_FBUSY bit to be set."; break; case DMLERR_DATAACKTIMEOUT: szErrorText = "A request for a synchronous data transaction has timed out."; break; case DMLERR_DLL_NOT_INITIALIZED: szErrorText = "A DdeML function was called without first calling the DdeInitialize function,\n\ror an invalid instance identifier\n\rwas passed to a DdeML function."; break; case DMLERR_DLL_USAGE: szErrorText = "An application initialized as APPCLASS_MONITOR has\n\rattempted to perform a Dde transaction,\n\ror an application initialized as APPCMD_CLIENTONLY has \n\rattempted to perform server transactions."; break; case DMLERR_EXECACKTIMEOUT: szErrorText = "A request for a synchronous execute transaction has timed out."; break; case DMLERR_INVALIDPARAMETER: szErrorText = "A parameter failed to be validated by the DdeML."; break; case DMLERR_LOW_MEMORY: szErrorText = "A DdeML application has created a prolonged race condition."; break; case DMLERR_MEMORY_ERROR: szErrorText = "A memory allocation failed."; break; case DMLERR_NO_CONV_ESTABLISHED: szErrorText = "A client's attempt to establish a conversation has failed."; break; case DMLERR_NOTPROCESSED: szErrorText = "A transaction failed."; break; case DMLERR_POKEACKTIMEOUT: szErrorText = "A request for a synchronous poke transaction has timed out."; break; case DMLERR_POSTMSG_FAILED: szErrorText = "An internal call to the PostMessage function has failed. "; break; case DMLERR_REENTRANCY: szErrorText = "Reentrancy problem."; break; case DMLERR_SERVER_DIED: szErrorText = "A server-side transaction was attempted on a conversation\n\rthat was terminated by the client, or the server\n\rterminated before completing a transaction."; break; case DMLERR_SYS_ERROR: szErrorText = "An internal error has occurred in the DdeML."; break; case DMLERR_UNADVACKTIMEOUT: szErrorText = "A request to end an advise transaction has timed out."; break; case DMLERR_UNFOUND_QUEUE_ID: szErrorText = "An invalid transaction identifier was passed to a DdeML function.\n\rOnce the application has returned from an XTYP_XACT_COMPLETE callback,\n\rthe transaction identifier for that callback is no longer valid."; break; default: szErrorText = "Unrecognised error type."; break; } MessageBox(NULL, (LPCSTR)szErrorText, "Dde Error", MB_OK | MB_ICONINFORMATION); }