X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14f355c2b5c71fc7c3d680aea366582d2ac60f7b..d67fee71b8078272308e3d5601cf72c5e19e715b:/src/msw/dde.cpp?ds=sidebyside diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index 1ddd1a726d..26a13fc678 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -49,24 +49,6 @@ #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 // ---------------------------------------------------------------------------- @@ -112,6 +94,7 @@ static HSZ DDEGetAtom(const wxString& string); // string handles static HSZ DDEAtomFromString(const wxString& s); static wxString DDEStringFromAtom(HSZ hsz); +static void DDEFreeString(HSZ hsz); // error handling static wxString DDEGetErrorMsg(UINT error); @@ -194,8 +177,10 @@ extern void wxDDEInitialize() void wxDDECleanUp() { - WX_CLEAR_LIST(wxDDEClientList, wxDDEClientObjects); - WX_CLEAR_LIST(wxDDEServerList, wxDDEServerObjects); + // deleting them later won't work as DDE won't be initialized any more + wxASSERT_MSG( wxDDEServerObjects.empty() && + wxDDEClientObjects.empty(), + _T("all DDE objects should be deleted by now") ); wxAtomTable.clear(); @@ -299,26 +284,45 @@ bool wxDDEServer::Create(const wxString& server) { m_serviceName = server; - if ( !DdeNameService(DDEIdInst, DDEAtomFromString(server), (HSZ)NULL, DNS_REGISTER) ) - { - DDELogError(wxString::Format(_("Failed to register DDE server '%s'"), - server.c_str())); + HSZ hsz = DDEAtomFromString(server); + if ( !hsz ) + { return false; } - return true; + + bool success = (DdeNameService(DDEIdInst, hsz, (HSZ) NULL, DNS_REGISTER) + != NULL); + + if (!success) + { + DDELogError(wxString::Format(_("Failed to register DDE server '%s'"), + server.c_str())); + } + + DDEFreeString(hsz); + + return success; } wxDDEServer::~wxDDEServer() { - if ( !!m_serviceName ) + if ( !m_serviceName.IsEmpty() ) { - if ( !DdeNameService(DDEIdInst, DDEAtomFromString(m_serviceName), - (HSZ)NULL, DNS_UNREGISTER) ) + HSZ hsz = DDEAtomFromString(m_serviceName); + + if (hsz) { - DDELogError(wxString::Format(_("Failed to unregister DDE server '%s'"), - m_serviceName.c_str())); + if ( !DdeNameService(DDEIdInst, hsz, + (HSZ) NULL, DNS_UNREGISTER) ) + { + DDELogError(wxString::Format( + _("Failed to unregister DDE server '%s'"), + m_serviceName.c_str())); + } + + DDEFreeString(hsz); } } @@ -416,12 +420,35 @@ wxConnectionBase *wxDDEClient::MakeConnection(const wxString& WXUNUSED(host), const wxString& server, const wxString& topic) { - HCONV hConv = DdeConnect(DDEIdInst, DDEAtomFromString(server), DDEAtomFromString(topic), - (PCONVCONTEXT)NULL); + HSZ hszServer = DDEAtomFromString(server); + + if ( !hszServer ) + { + return (wxConnectionBase*) NULL; + } + + + HSZ hszTopic = DDEAtomFromString(topic); + + if ( !hszTopic ) + { + DDEFreeString(hszServer); + return (wxConnectionBase*) NULL; + } + + + HCONV hConv = ::DdeConnect(DDEIdInst, hszServer, hszTopic, + (PCONVCONTEXT) NULL); + + DDEFreeString(hszServer); + DDEFreeString(hszTopic); + + if ( !hConv ) { - DDELogError(wxString::Format(_("Failed to create connection to server '%s' on topic '%s'"), - server.c_str(), topic.c_str())); + DDELogError( wxString::Format( + _("Failed to create connection to server '%s' on topic '%s'"), + server.c_str(), topic.c_str()) ); } else { @@ -534,7 +561,8 @@ bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat format) size = wxStrlen(data) + 1; } - bool ok = DdeClientTransaction((LPBYTE)data, size, + bool ok = DdeClientTransaction((LPBYTE)data, + size * sizeof(wxChar), GetHConv(), NULL, format, @@ -571,15 +599,15 @@ wxChar *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat fo DWORD len = DdeGetData(returned_data, NULL, 0, 0); - wxChar *data = GetBufferAtLeast( len ); + wxChar *data = GetBufferAtLeast( len/sizeof(wxChar) ); wxASSERT_MSG(data != NULL, _T("Buffer too small in wxDDEConnection::Request") ); - DdeGetData(returned_data, (LPBYTE)data, len, 0); + (void) DdeGetData(returned_data, (LPBYTE)data, len, 0); - DdeFreeDataHandle(returned_data); + (void) DdeFreeDataHandle(returned_data); if (size) - *size = (int)len; + *size = (int)len/sizeof(wxChar); return data; } @@ -593,7 +621,8 @@ bool wxDDEConnection::Poke(const wxString& item, wxChar *data, int size, wxIPCFo } HSZ item_atom = DDEGetAtom(item); - bool ok = DdeClientTransaction((LPBYTE)data, size, + bool ok = DdeClientTransaction((LPBYTE)data, + size * sizeof(wxChar), GetHConv(), item_atom, format, XTYP_POKE, @@ -751,7 +780,7 @@ _DDECallback(WORD wType, { DWORD len = DdeGetData(hData, NULL, 0, 0); - wxChar *data = connection->GetBufferAtLeast( len ); + wxChar *data = connection->GetBufferAtLeast( len/sizeof(wxChar) ); wxASSERT_MSG(data != NULL, _T("Buffer too small in _DDECallback (XTYP_EXECUTE)") ); @@ -761,7 +790,7 @@ _DDECallback(WORD wType, if ( connection->OnExecute(connection->m_topicName, data, - (int)len, + (int)len/sizeof(wxChar), (wxIPCFormat) wFmt) ) { return (DDERETURN)(DWORD)DDE_FACK; @@ -791,7 +820,7 @@ _DDECallback(WORD wType, HDDEDATA handle = DdeCreateDataHandle(DDEIdInst, (LPBYTE)data, - user_size, + user_size*sizeof(wxChar), 0, hsz2, wFmt, @@ -812,7 +841,7 @@ _DDECallback(WORD wType, DWORD len = DdeGetData(hData, NULL, 0, 0); - wxChar *data = connection->GetBufferAtLeast( len ); + wxChar *data = connection->GetBufferAtLeast( len/sizeof(wxChar) ); wxASSERT_MSG(data != NULL, _T("Buffer too small in _DDECallback (XTYP_EXECUTE)") ); @@ -823,7 +852,7 @@ _DDECallback(WORD wType, connection->OnPoke(connection->m_topicName, item_name, data, - (int)len, + (int)len/sizeof(wxChar), (wxIPCFormat) wFmt); return (DDERETURN)DDE_FACK; @@ -874,7 +903,7 @@ _DDECallback(WORD wType, ( DDEIdInst, (LPBYTE)connection->m_sendingData, - connection->m_dataSize, + connection->m_dataSize*sizeof(wxChar), 0, hsz2, connection->m_dataType, @@ -899,7 +928,7 @@ _DDECallback(WORD wType, DWORD len = DdeGetData(hData, NULL, 0, 0); - wxChar *data = connection->GetBufferAtLeast( len ); + wxChar *data = connection->GetBufferAtLeast( len/sizeof(wxChar) ); wxASSERT_MSG(data != NULL, _T("Buffer too small in _DDECallback (XTYP_ADVDATA)") ); @@ -909,7 +938,7 @@ _DDECallback(WORD wType, if ( connection->OnAdvise(connection->m_topicName, item_name, data, - (int)len, + (int)len/sizeof(wxChar), (wxIPCFormat) wFmt) ) { return (DDERETURN)(DWORD)DDE_FACK; @@ -945,7 +974,10 @@ static HSZ DDEGetAtom(const wxString& str) return DDEAddAtom(str); } -// atom <-> strings +/* atom <-> strings +The returned handle has to be freed by the caller (using +(static) DDEFreeString). +*/ static HSZ DDEAtomFromString(const wxString& s) { wxASSERT_MSG( DDEIdInst, _T("DDE not initialized") ); @@ -970,6 +1002,15 @@ static wxString DDEStringFromAtom(HSZ hsz) return s; } +static void DDEFreeString(HSZ hsz) +{ + // DS: Failure to free a string handle might indicate there's + // some other severe error. + bool ok = (::DdeFreeStringHandle(DDEIdInst, hsz) != 0); + wxASSERT_MSG( ok, wxT("Failed to free DDE string handle") ); + wxUnusedVar(ok); +} + // ---------------------------------------------------------------------------- // error handling // ----------------------------------------------------------------------------