diff --git a/docs/changes.txt b/docs/changes.txt index 16cb9613f5..404da6917a 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -124,6 +124,10 @@ All (GUI): - Allow changing tooltip text for button allowing to enter a new string in wxPGArrayEditorDialog. +wxMSW: + +- Fix passing Unicode strings via wxIPC when using DDE. + 3.1.2: (released 2018-12-10) ---------------------------- diff --git a/include/wx/msw/dde.h b/include/wx/msw/dde.h index 91fdd06f96..a7cd04ccda 100644 --- a/include/wx/msw/dde.h +++ b/include/wx/msw/dde.h @@ -70,7 +70,6 @@ public: WXHCONV m_hConv; const void* m_sendingData; int m_dataSize; - wxIPCFormat m_dataType; wxDECLARE_NO_COPY_CLASS(wxDDEConnection); wxDECLARE_DYNAMIC_CLASS(wxDDEConnection); diff --git a/samples/ipc/server.cpp b/samples/ipc/server.cpp index 25a4420cc1..8058eb983a 100644 --- a/samples/ipc/server.cpp +++ b/samples/ipc/server.cpp @@ -268,7 +268,11 @@ void MyServer::Advise() { const wxDateTime now = wxDateTime::Now(); - m_connection->Advise(m_connection->m_advise, now.Format()); + m_connection->Advise + ( + m_connection->m_advise, + wxString::FromUTF8("\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82") + ); const wxString s = now.FormatTime() + " " + now.FormatDate(); m_connection->Advise(m_connection->m_advise, s.mb_str(), wxNO_LEN); diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index ccea317306..11199fad2f 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -748,12 +748,20 @@ bool wxDDEConnection::DoAdvise(const wxString& item, size_t size, wxIPCFormat format) { + // Unfortunately we currently always use the same CF_TEXT in StartAdvise() + // but allow calling Advise() with different formats. This doesn't map well + // to the DDE API, so the price to pay for it is that we need to send the + // actual format used as part of the data, even if this means making + // another copy of it. + wxCharBuffer buf; + buf.extend(size + 1); + *buf.data() = format; + memcpy(buf.data() + 1, data, size); + HSZ item_atom = DDEGetAtom(item); HSZ topic_atom = DDEGetAtom(m_topicName); - m_sendingData = data; // mrf: potential for scope problems here? - m_dataSize = size; - // wxIPC_PRIVATE does not succeed, so use text instead - m_dataType = format == wxIPC_PRIVATE ? wxIPC_TEXT : format; + m_sendingData = buf.data(); + m_dataSize = size + 1; bool ok = DdePostAdvise(DDEIdInst, topic_atom, item_atom) != 0; if ( !ok ) @@ -986,11 +994,12 @@ _DDECallback(UINT wType, connection->m_dataSize, 0, hsz2, - connection->m_dataType, + wFmt, 0 ); connection->m_sendingData = NULL; + connection->m_dataSize = 0; return (DDERETURN)data; } @@ -1008,18 +1017,21 @@ _DDECallback(UINT wType, DWORD len = DdeGetData(hData, NULL, 0, 0); - void *data = connection->GetBufferAtLeast(len); + BYTE* const data = static_cast(connection->GetBufferAtLeast(len)); wxASSERT_MSG(data != NULL, wxT("Buffer too small in _DDECallback (XTYP_ADVDATA)") ); - DdeGetData(hData, (LPBYTE)data, len, 0); + DdeGetData(hData, data, len, 0); DdeFreeDataHandle(hData); + + // Our code in DoAdvise() prepends the actual format of the + // data as the first byte, extract it back now. if ( connection->OnAdvise(connection->m_topicName, item_name, - data, - (int)len, - (wxIPCFormat) wFmt) ) + data + 1, + (int)len - 1, + (wxIPCFormat)*data) ) { return (DDERETURN)(DWORD)DDE_FACK; }