X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5bd3a2da9573f270564cd035e0cfbf6902cf8750..4fa47e5643f13065af4269fd9a87b40e57d48c5f:/src/msw/dde.cpp diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index 0d084650d7..6cf22d6b56 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -37,6 +37,8 @@ #include "wx/module.h" #include "wx/dde.h" +#include "wx/intl.h" + #include "wx/msw/private.h" @@ -44,10 +46,32 @@ #include #include +#ifdef __WXWINE__ +#define PCONVCONTEXT CONVCONTEXT* +#endif + #if defined(__TWIN32__) || defined(__GNUWIN32_OLD__) #include "wx/msw/gnuwin32/extra.h" #endif +// some compilers headers don't define this one (mingw32) +#ifndef DMLERR_NO_ERROR + #define DMLERR_NO_ERROR (0) + + // this one is also missing from some mingw32 headers, but there is no way + // to test for it (I know of) - the test for DMLERR_NO_ERROR works for me, + // but is surely not the right thing to do + extern "C" + HDDEDATA STDCALL DdeClientTransaction(LPBYTE pData, + DWORD cbData, + HCONV hConv, + HSZ hszItem, + UINT wFmt, + UINT wType, + DWORD dwTimeout, + LPDWORD pdwResult); +#endif // no DMLERR_NO_ERROR + // ---------------------------------------------------------------------------- // macros and constants // ---------------------------------------------------------------------------- @@ -109,8 +133,6 @@ static wxList wxAtomTable(wxKEY_STRING); static wxList wxDDEClientObjects; static wxList wxDDEServerObjects; -char *DDEDefaultIPCBuffer = NULL; -int DDEDefaultIPCBufferSize = 0; static bool DDEInitialized = FALSE; // ---------------------------------------------------------------------------- @@ -169,13 +191,21 @@ extern void wxDDEInitialize() void wxDDECleanUp() { + wxDDEClientObjects.DeleteContents(TRUE); + wxDDEClientObjects.Clear(); + wxDDEClientObjects.DeleteContents(FALSE); + + wxDDEServerObjects.DeleteContents(TRUE); + wxDDEServerObjects.Clear(); + wxDDEServerObjects.DeleteContents(FALSE); + + wxAtomTable.Clear(); + if ( DDEIdInst != 0 ) { DdeUninitialize(DDEIdInst); DDEIdInst = 0; } - - delete [] DDEDefaultIPCBuffer; } // ---------------------------------------------------------------------------- @@ -290,6 +320,7 @@ wxDDEServer::~wxDDEServer() { wxDDEConnection *connection = (wxDDEConnection *)node->Data(); wxNode *next = node->Next(); + connection->SetConnected(false); connection->OnDisconnect(); // May delete the node implicitly node = next; } @@ -378,8 +409,7 @@ wxConnectionBase *wxDDEClient::MakeConnection(const wxString& WXUNUSED(host), (PCONVCONTEXT)NULL); if ( !hConv ) { - DDELogError(wxString::Format(_("Failed to create connection to " - "server '%s' on topic '%s'"), + DDELogError(wxString::Format(_("Failed to create connection to server '%s' on topic '%s'"), server.c_str(), topic.c_str())); } else @@ -439,21 +469,9 @@ bool wxDDEClient::DeleteConnection(WXHCONV conv) // wxDDEConnection // ---------------------------------------------------------------------------- -wxDDEConnection::wxDDEConnection(char *buffer, int size) +wxDDEConnection::wxDDEConnection(wxChar *buffer, int size) + : wxConnectionBase(buffer, size) { - if (buffer == NULL) - { - if (DDEDefaultIPCBuffer == NULL) - DDEDefaultIPCBuffer = new char[DDEDefaultIPCBufferSize]; - m_bufPtr = DDEDefaultIPCBuffer; - m_bufSize = DDEDefaultIPCBufferSize; - } - else - { - m_bufPtr = buffer; - m_bufSize = size; - } - m_client = NULL; m_server = NULL; @@ -462,20 +480,17 @@ wxDDEConnection::wxDDEConnection(char *buffer, int size) } wxDDEConnection::wxDDEConnection() + : wxConnectionBase() { m_hConv = 0; m_sendingData = NULL; m_server = NULL; m_client = NULL; - if (DDEDefaultIPCBuffer == NULL) - DDEDefaultIPCBuffer = new char[DDEDefaultIPCBufferSize]; - - m_bufPtr = DDEDefaultIPCBuffer; - m_bufSize = DDEDefaultIPCBufferSize; } wxDDEConnection::~wxDDEConnection() { + Disconnect(); if (m_server) m_server->GetConnections().DeleteObject(this); else @@ -485,6 +500,9 @@ wxDDEConnection::~wxDDEConnection() // Calls that CLIENT can make bool wxDDEConnection::Disconnect() { + if ( !GetConnected() ) + return true; + DDEDeleteConnection(GetHConv()); bool ok = DdeDisconnect(GetHConv()) != 0; @@ -493,6 +511,8 @@ bool wxDDEConnection::Disconnect() DDELogError(_T("Failed to disconnect from DDE server gracefully")); } + SetConnected( false ); // so we don't try and disconnect again + return ok; } @@ -511,6 +531,7 @@ bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat format) XTYP_EXECUTE, DDE_TIMEOUT, &result) != 0; + if ( !ok ) { DDELogError(_T("DDE execute request failed")); @@ -519,9 +540,10 @@ bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat format) return ok; } -char *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat format) +wxChar *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat format) { DWORD result; + HSZ atom = DDEGetAtom(item); HDDEDATA returned_data = DdeClientTransaction(NULL, 0, @@ -537,14 +559,19 @@ char *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat form return NULL; } - DWORD len = DdeGetData(returned_data, (LPBYTE)m_bufPtr, m_bufSize, 0); + DWORD len = DdeGetData(returned_data, NULL, 0, 0); + + wxChar *data = GetBufferAtLeast( len ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in wxDDEConnection::Request") ); + DdeGetData(returned_data, (LPBYTE)data, len, 0); DdeFreeDataHandle(returned_data); if (size) *size = (int)len; - return m_bufPtr; + return data; } bool wxDDEConnection::Poke(const wxString& item, wxChar *data, int size, wxIPCFormat format) @@ -621,7 +648,7 @@ bool wxDDEConnection::Advise(const wxString& item, HSZ item_atom = DDEGetAtom(item); HSZ topic_atom = DDEGetAtom(m_topicName); - m_sendingData = data; + m_sendingData = data; // mrf: potential for scope problems here? m_dataSize = size; m_dataType = format; @@ -694,10 +721,14 @@ _DDECallback(WORD wType, case XTYP_DISCONNECT: { wxDDEConnection *connection = DDEFindConnection(hConv); - if (connection && connection->OnDisconnect()) + if (connection) { - DDEDeleteConnection(hConv); // Delete mapping: hConv => connection - return (DDERETURN)(DWORD)TRUE; + connection->SetConnected( false ); + if (connection->OnDisconnect()) + { + DDEDeleteConnection(hConv); // Delete mapping: hConv => connection + return (DDERETURN)(DWORD)TRUE; + } } break; } @@ -708,13 +739,18 @@ _DDECallback(WORD wType, if (connection) { - DWORD len = DdeGetData(hData, - (LPBYTE)connection->m_bufPtr, - connection->m_bufSize, - 0); + DWORD len = DdeGetData(hData, NULL, 0, 0); + + wxChar *data = connection->GetBufferAtLeast( len ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in _DDECallback (XTYP_EXECUTE)") ); + + DdeGetData(hData, (LPBYTE)data, len, 0); + DdeFreeDataHandle(hData); + if ( connection->OnExecute(connection->m_topicName, - connection->m_bufPtr, + data, (int)len, (wxIPCFormat) wFmt) ) { @@ -734,14 +770,14 @@ _DDECallback(WORD wType, wxString item_name = DDEStringFromAtom(hsz2); int user_size = -1; - char *data = connection->OnRequest(connection->m_topicName, + wxChar *data = connection->OnRequest(connection->m_topicName, item_name, &user_size, (wxIPCFormat) wFmt); if (data) { if (user_size < 0) - user_size = wxStrlen(data) + 1; + user_size = wxStrlen((wxChar*)data) + 1; HDDEDATA handle = DdeCreateDataHandle(DDEIdInst, (LPBYTE)data, @@ -764,15 +800,19 @@ _DDECallback(WORD wType, { wxString item_name = DDEStringFromAtom(hsz2); - DWORD len = DdeGetData(hData, - (LPBYTE)connection->m_bufPtr, - connection->m_bufSize, - 0); + DWORD len = DdeGetData(hData, NULL, 0, 0); + + wxChar *data = connection->GetBufferAtLeast( len ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in _DDECallback (XTYP_EXECUTE)") ); + + DdeGetData(hData, (LPBYTE)data, len, 0); + DdeFreeDataHandle(hData); connection->OnPoke(connection->m_topicName, item_name, - connection->m_bufPtr, + data, (int)len, (wxIPCFormat) wFmt); @@ -847,14 +887,18 @@ _DDECallback(WORD wType, { wxString item_name = DDEStringFromAtom(hsz2); - DWORD len = DdeGetData(hData, - (LPBYTE)connection->m_bufPtr, - connection->m_bufSize, - 0); + DWORD len = DdeGetData(hData, NULL, 0, 0); + + wxChar *data = connection->GetBufferAtLeast( len ); + wxASSERT_MSG(data != NULL, + _T("Buffer too small in _DDECallback (XTYP_ADVDATA)") ); + + DdeGetData(hData, (LPBYTE)data, len, 0); + DdeFreeDataHandle(hData); if ( connection->OnAdvise(connection->m_topicName, item_name, - connection->m_bufPtr, + data, (int)len, (wxIPCFormat) wFmt) ) { @@ -898,7 +942,7 @@ static HSZ DDEAtomFromString(const wxString& s) { wxASSERT_MSG( DDEIdInst, _T("DDE not initialized") ); - HSZ hsz = DdeCreateStringHandle(DDEIdInst, s, DDE_CP); + HSZ hsz = DdeCreateStringHandle(DDEIdInst, (wxChar*) s.c_str(), DDE_CP); if ( !hsz ) { DDELogError(_("Failed to create DDE string")); @@ -952,10 +996,10 @@ static wxString DDEGetErrorMsg(UINT error) err = _("a request for a synchronous data transaction has timed out."); break; case DMLERR_DLL_NOT_INITIALIZED: - err = _("a DDEML function was called without first calling the DdeInitialize function,\n\ror an invalid instance identifier\n\rwas passed to a DDEML function."); + err = _("a DDEML function was called without first calling the DdeInitialize function,\nor an invalid instance identifier\nwas passed to a DDEML function."); break; case DMLERR_DLL_USAGE: - err = _("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."); + err = _("an application initialized as APPCLASS_MONITOR has\nattempted to perform a DDE transaction,\nor an application initialized as APPCMD_CLIENTONLY has \nattempted to perform server transactions."); break; case DMLERR_EXECACKTIMEOUT: err = _("a request for a synchronous execute transaction has timed out."); @@ -985,7 +1029,7 @@ static wxString DDEGetErrorMsg(UINT error) err = _("reentrancy problem."); break; case DMLERR_SERVER_DIED: - err = _("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."); + err = _("a server-side transaction was attempted on a conversation\nthat was terminated by the client, or the server\nterminated before completing a transaction."); break; case DMLERR_SYS_ERROR: err = _("an internal error has occurred in the DDEML."); @@ -994,7 +1038,7 @@ static wxString DDEGetErrorMsg(UINT error) err = _("a request to end an advise transaction has timed out."); break; case DMLERR_UNFOUND_QUEUE_ID: - err = _("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."); + err = _("an invalid transaction identifier was passed to a DDEML function.\nOnce the application has returned from an XTYP_XACT_COMPLETE callback,\nthe transaction identifier for that callback is no longer valid."); break; default: err.Printf(_("Unknown DDE error %08x"), error);