X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/edef87c8274bd4cadcccc4ff107aeb1815e48460..9d5507f7a2701395e1d5c121bd877bb9066ee6ea:/src/msw/dde.cpp diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index f33908fc4e..7604068ac6 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/dde.cpp +// Name: src/msw/dde.cpp // Purpose: DDE classes // Author: Julian Smart // Modified by: @@ -29,12 +29,14 @@ #ifndef WX_PRECOMP #include "wx/utils.h" #include "wx/app.h" + #include "wx/hashmap.h" + #include "wx/module.h" #endif -#include "wx/module.h" #include "wx/dde.h" #include "wx/intl.h" -#include "wx/hashmap.h" +#include "wx/buffer.h" +#include "wx/strconv.h" #include "wx/msw/private.h" @@ -96,7 +98,7 @@ static void DDELogError(const wxString& s, UINT error = DMLERR_NO_ERROR); // global variables // ---------------------------------------------------------------------------- -WX_DECLARE_STRING_HASH_MAP( HSZ, wxAtomMap ) +WX_DECLARE_STRING_HASH_MAP( HSZ, wxAtomMap ); static DWORD DDEIdInst = 0L; static wxDDEConnection *DDECurrentlyConnecting = NULL; @@ -300,7 +302,7 @@ bool wxDDEServer::Create(const wxString& server) wxDDEServer::~wxDDEServer() { - if ( !m_serviceName.IsEmpty() ) + if ( !m_serviceName.empty() ) { HSZ hsz = DDEAtomFromString(m_serviceName); @@ -498,7 +500,7 @@ bool wxDDEClient::DeleteConnection(WXHCONV conv) // wxDDEConnection // ---------------------------------------------------------------------------- -wxDDEConnection::wxDDEConnection(wxChar *buffer, int size) +wxDDEConnection::wxDDEConnection(void *buffer, size_t size) : wxConnectionBase(buffer, size) { m_client = NULL; @@ -545,20 +547,101 @@ bool wxDDEConnection::Disconnect() return ok; } -bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat WXUNUSED(format)) +bool +wxDDEConnection::DoExecute(const void *data, size_t size, wxIPCFormat format) { - DWORD result; - if (size < 0) + wxCHECK_MSG( format == wxIPC_TEXT || + format == wxIPC_UTF8TEXT || + format == wxIPC_UNICODETEXT, + false, + _T("wxDDEServer::Execute() supports only text data") ); + + wxMemoryBuffer buffer; + LPBYTE realData wxDUMMY_INITIALIZE(NULL); + size_t realSize wxDUMMY_INITIALIZE(0); + wxMBConv *conv = NULL; + + // Windows only supports either ANSI or UTF-16 format depending on the + // build, so we need to convert the data if it doesn't use it already +#if wxUSE_UNICODE + if ( format == wxIPC_TEXT ) + { + conv = &wxConvLibc; + } + else if ( format == wxIPC_UTF8TEXT ) + { + conv = &wxConvUTF8; + } + else // no conversion necessary for wxIPC_UNICODETEXT { - size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL + realData = (LPBYTE)data; + realSize = size; } - bool ok = DdeClientTransaction((LPBYTE)data, - size, + if ( conv ) + { + const char * const text = (const char *)data; + const size_t len = size/sizeof(char); + + realSize = conv->ToWChar(NULL, 0, text, len); + if ( realSize == wxCONV_FAILED ) + return false; + + realData = (LPBYTE)buffer.GetWriteBuf(realSize*sizeof(wchar_t)); + if ( !realData ) + return false; + + realSize = conv->ToWChar((wchar_t *)realData, realSize, text, len); + if ( realSize == wxCONV_FAILED ) + return false; + } +#else // !wxUSE_UNICODE + if ( format == wxIPC_UNICODETEXT ) + { + conv = &wxConvLibc; + } + else if ( format == wxIPC_UTF8TEXT ) + { + // we could implement this in theory but it's not obvious how to pass + // the format information and, basically, why bother -- just use + // Unicode build + wxFAIL_MSG( _T("UTF-8 text not supported in ANSI build") ); + + return false; + } + else // don't convert wxIPC_TEXT + { + realData = (LPBYTE)data; + realSize = size; + } + + if ( conv ) + { + const wchar_t * const wtext = (const wchar_t *)data; + const size_t len = size/sizeof(wchar_t); + + realSize = conv->FromWChar(NULL, 0, wtext, len); + if ( realSize == wxCONV_FAILED ) + return false; + + realData = (LPBYTE)buffer.GetWriteBuf(realSize*sizeof(char)); + if ( !realData ) + return false; + + realSize = conv->FromWChar((char*)realData, realSize, wtext, len); + if ( realSize == wxCONV_FAILED ) + return false; + } +#endif // wxUSE_UNICODE/!wxUSE_UNICODE + + DWORD result; + bool ok = DdeClientTransaction(realData, + realSize, GetHConv(), NULL, -// If the transaction specified by the wType parameter does not pass data or is XTYP_EXECUTE, -// wFmt should be zero. + // MSDN: if the transaction specified by + // the wType parameter does not pass data + // or is XTYP_EXECUTE, wFmt should be zero. 0, XTYP_EXECUTE, DDE_TIMEOUT, @@ -572,7 +655,7 @@ bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat WXUNUSED return ok; } -wxChar *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat format) +const void *wxDDEConnection::Request(const wxString& item, size_t *size, wxIPCFormat format) { DWORD result; @@ -593,7 +676,7 @@ wxChar *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat fo DWORD len = DdeGetData(returned_data, NULL, 0, 0); - wxChar *data = GetBufferAtLeast( len ); + void *data = GetBufferAtLeast(len); wxASSERT_MSG(data != NULL, _T("Buffer too small in wxDDEConnection::Request") ); (void) DdeGetData(returned_data, (LPBYTE)data, len, 0); @@ -601,18 +684,14 @@ wxChar *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat fo (void) DdeFreeDataHandle(returned_data); if (size) - *size = (int)len; + *size = (size_t)len; return data; } -bool wxDDEConnection::Poke(const wxString& item, wxChar *data, int size, wxIPCFormat format) +bool wxDDEConnection::DoPoke(const wxString& item, const void *data, size_t size, wxIPCFormat format) { DWORD result; - if (size < 0) - { - size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL - } HSZ item_atom = DDEGetAtom(item); bool ok = DdeClientTransaction((LPBYTE)data, @@ -669,16 +748,11 @@ bool wxDDEConnection::StopAdvise(const wxString& item) } // Calls that SERVER can make -bool wxDDEConnection::Advise(const wxString& item, - wxChar *data, - int size, - wxIPCFormat format) +bool wxDDEConnection::DoAdvise(const wxString& item, + const void *data, + size_t size, + wxIPCFormat format) { - if (size < 0) - { - size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL - } - HSZ item_atom = DDEGetAtom(item); HSZ topic_atom = DDEGetAtom(m_topicName); m_sendingData = data; // mrf: potential for scope problems here? @@ -695,12 +769,6 @@ bool wxDDEConnection::Advise(const wxString& item, return ok; } -bool wxDDEConnection::OnDisconnect() -{ - delete this; - return true; -} - // ---------------------------------------------------------------------------- // _DDECallback // ---------------------------------------------------------------------------- @@ -775,7 +843,7 @@ _DDECallback(WORD wType, { DWORD len = DdeGetData(hData, NULL, 0, 0); - wxChar *data = connection->GetBufferAtLeast( len ); + void *data = connection->GetBufferAtLeast(len); wxASSERT_MSG(data != NULL, _T("Buffer too small in _DDECallback (XTYP_EXECUTE)") ); @@ -783,11 +851,19 @@ _DDECallback(WORD wType, DdeFreeDataHandle(hData); -// XTYP_EXECUTE cannot be used for arbitrary data, but only for text + // XTYP_EXECUTE can be used for text only and the text is + // always in ANSI format for ANSI build and Unicode format + // in Unicode build + #if wxUSE_UNICODE + wFmt = wxIPC_UNICODETEXT; + #else + wFmt = wxIPC_TEXT; + #endif + if ( connection->OnExecute(connection->m_topicName, data, (int)len, - wxIPC_TEXT ) ) + (wxIPCFormat)wFmt) ) { return (DDERETURN)(DWORD)DDE_FACK; } @@ -804,15 +880,26 @@ _DDECallback(WORD wType, { wxString item_name = DDEStringFromAtom(hsz2); - int user_size = -1; - wxChar *data = connection->OnRequest(connection->m_topicName, - item_name, - &user_size, - (wxIPCFormat) wFmt); + size_t user_size = wxNO_LEN; + const void *data = connection->OnRequest(connection->m_topicName, + item_name, + &user_size, + (wxIPCFormat)wFmt); if (data) { - if (user_size < 0) - user_size = (wxStrlen((wxChar*)data) + 1) * sizeof(wxChar); // includes final NUL + if (user_size == wxNO_LEN) + switch (wFmt) + { + case wxIPC_TEXT: + case wxIPC_UTF8TEXT: + user_size = strlen((const char*)data) + 1; // includes final NUL + break; + case wxIPC_UNICODETEXT: + user_size = (wcslen((const wchar_t*)data) + 1) * sizeof(wchar_t); // includes final NUL + break; + default: + user_size = 0; + } HDDEDATA handle = DdeCreateDataHandle(DDEIdInst, (LPBYTE)data, @@ -837,7 +924,7 @@ _DDECallback(WORD wType, DWORD len = DdeGetData(hData, NULL, 0, 0); - wxChar *data = connection->GetBufferAtLeast( len ); + void *data = connection->GetBufferAtLeast(len); wxASSERT_MSG(data != NULL, _T("Buffer too small in _DDECallback (XTYP_POKE)") ); @@ -924,7 +1011,7 @@ _DDECallback(WORD wType, DWORD len = DdeGetData(hData, NULL, 0, 0); - wxChar *data = connection->GetBufferAtLeast( len ); + void *data = connection->GetBufferAtLeast(len); wxASSERT_MSG(data != NULL, _T("Buffer too small in _DDECallback (XTYP_ADVDATA)") ); @@ -978,7 +1065,7 @@ static HSZ DDEAtomFromString(const wxString& s) { wxASSERT_MSG( DDEIdInst, _T("DDE not initialized") ); - HSZ hsz = DdeCreateStringHandle(DDEIdInst, (wxChar*) s.c_str(), DDE_CP); + HSZ hsz = DdeCreateStringHandle(DDEIdInst, (wxChar*)s.wx_str(), DDE_CP); if ( !hsz ) { DDELogError(_("Failed to create DDE string"));