Fix passing Unicode strings via wxIPC when using DDE
wxIPC API doesn't map well onto DDE, as we don't have wxIPCFormat parameter in StartAdvise() but do allow specifying the format when calling Advise() itself, whereas DDE requires specifying the format when establishing the advise loop and the data always must use this format later. Because of this, we have to pass the actual format with the data itself instead of relying on DDE formats support. This has the advantage of allowing wxIPC_UTF8TEXT to work, while previously it didn't and couldn't, as DDE only supports the standard (or custom, but registered) clipboard formats and it wasn't one of them. Of course, this also has a disadvantage of having to make another copy of the data, but this seems unavoidable. This change allow Advise() overload taking wxString to work, including for non-ASCII strings, as shown by the update to the IPC sample. It also makes wxDDEConnection::m_dataType unnecessary, as we must always use the format passed to DDE callback anyhow when handling XTYP_ADVREQ. Closes #17900.
This commit is contained in:
@@ -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)
|
||||
----------------------------
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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<BYTE*>(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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user