📄 dde.cpp
字号:
if (connection)
{
connection->m_server = server;
server->GetConnections().Append(connection);
connection->m_hConv = 0;
connection->m_topicName = topic;
DDECurrentlyConnecting = connection;
return (DDERETURN)(DWORD)true;
}
}
break;
}
case XTYP_CONNECT_CONFIRM:
{
if (DDECurrentlyConnecting)
{
DDECurrentlyConnecting->m_hConv = (WXHCONV) hConv;
DDECurrentlyConnecting = NULL;
return (DDERETURN)(DWORD)true;
}
break;
}
case XTYP_DISCONNECT:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
connection->SetConnected( false );
if (connection->OnDisconnect())
{
DDEDeleteConnection(hConv); // Delete mapping: hConv => connection
return (DDERETURN)(DWORD)true;
}
}
break;
}
case XTYP_EXECUTE:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
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);
// XTYP_EXECUTE cannot be used for arbitrary data, but only for text
if ( connection->OnExecute(connection->m_topicName,
data,
(int)len,
wxIPC_TEXT ) )
{
return (DDERETURN)(DWORD)DDE_FACK;
}
}
return (DDERETURN)DDE_FNOTPROCESSED;
}
case XTYP_REQUEST:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
wxString item_name = DDEStringFromAtom(hsz2);
int user_size = -1;
wxChar *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
HDDEDATA handle = DdeCreateDataHandle(DDEIdInst,
(LPBYTE)data,
user_size,
0,
hsz2,
wFmt,
0);
return (DDERETURN)handle;
}
}
break;
}
case XTYP_POKE:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
wxString item_name = DDEStringFromAtom(hsz2);
DWORD len = DdeGetData(hData, NULL, 0, 0);
wxChar *data = connection->GetBufferAtLeast( len );
wxASSERT_MSG(data != NULL,
_T("Buffer too small in _DDECallback (XTYP_POKE)") );
DdeGetData(hData, (LPBYTE)data, len, 0);
DdeFreeDataHandle(hData);
connection->OnPoke(connection->m_topicName,
item_name,
data,
(int)len,
(wxIPCFormat) wFmt);
return (DDERETURN)DDE_FACK;
}
else
{
return (DDERETURN)DDE_FNOTPROCESSED;
}
}
case XTYP_ADVSTART:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
wxString item_name = DDEStringFromAtom(hsz2);
return (DDERETURN)connection->
OnStartAdvise(connection->m_topicName, item_name);
}
break;
}
case XTYP_ADVSTOP:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
wxString item_name = DDEStringFromAtom(hsz2);
return (DDERETURN)connection->
OnStopAdvise(connection->m_topicName, item_name);
}
break;
}
case XTYP_ADVREQ:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection && connection->m_sendingData)
{
HDDEDATA data = DdeCreateDataHandle
(
DDEIdInst,
(LPBYTE)connection->m_sendingData,
connection->m_dataSize,
0,
hsz2,
connection->m_dataType,
0
);
connection->m_sendingData = NULL;
return (DDERETURN)data;
}
break;
}
case XTYP_ADVDATA:
{
wxDDEConnection *connection = DDEFindConnection(hConv);
if (connection)
{
wxString item_name = DDEStringFromAtom(hsz2);
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,
data,
(int)len,
(wxIPCFormat) wFmt) )
{
return (DDERETURN)(DWORD)DDE_FACK;
}
}
return (DDERETURN)DDE_FNOTPROCESSED;
}
}
return (DDERETURN)0;
}
// ----------------------------------------------------------------------------
// DDE strings and atoms
// ----------------------------------------------------------------------------
// Atom table stuff
static HSZ DDEAddAtom(const wxString& str)
{
HSZ atom = DDEAtomFromString(str);
wxAtomTable[str] = atom;
return atom;
}
static HSZ DDEGetAtom(const wxString& str)
{
wxAtomMap::iterator it = wxAtomTable.find(str);
if (it != wxAtomTable.end())
return it->second;
return DDEAddAtom(str);
}
/* 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") );
HSZ hsz = DdeCreateStringHandle(DDEIdInst, (wxChar*) s.c_str(), DDE_CP);
if ( !hsz )
{
DDELogError(_("Failed to create DDE string"));
}
return hsz;
}
static wxString DDEStringFromAtom(HSZ hsz)
{
// all DDE strings are normally limited to 255 bytes
static const size_t len = 256;
wxString s;
(void)DdeQueryString(DDEIdInst, hsz, wxStringBuffer(s, len), len, DDE_CP);
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
// ----------------------------------------------------------------------------
static void DDELogError(const wxString& s, UINT error)
{
if ( !error )
{
error = DdeGetLastError(DDEIdInst);
}
wxLogError(s + _T(": ") + DDEGetErrorMsg(error));
}
static wxString DDEGetErrorMsg(UINT error)
{
wxString err;
switch ( error )
{
case DMLERR_NO_ERROR:
err = _("no DDE error.");
break;
case DMLERR_ADVACKTIMEOUT:
err = _("a request for a synchronous advise transaction has timed out.");
break;
case DMLERR_BUSY:
err = _("the response to the transaction caused the DDE_FBUSY bit to be set.");
break;
case DMLERR_DATAACKTIMEOUT:
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,\nor an invalid instance identifier\nwas passed to a DDEML function.");
break;
case DMLERR_DLL_USAGE:
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.");
break;
case DMLERR_INVALIDPARAMETER:
err = _("a parameter failed to be validated by the DDEML.");
break;
case DMLERR_LOW_MEMORY:
err = _("a DDEML application has created a prolonged race condition.");
break;
case DMLERR_MEMORY_ERROR:
err = _("a memory allocation failed.");
break;
case DMLERR_NO_CONV_ESTABLISHED:
err = _("a client's attempt to establish a conversation has failed.");
break;
case DMLERR_NOTPROCESSED:
err = _("a transaction failed.");
break;
case DMLERR_POKEACKTIMEOUT:
err = _("a request for a synchronous poke transaction has timed out.");
break;
case DMLERR_POSTMSG_FAILED:
err = _("an internal call to the PostMessage function has failed. ");
break;
case DMLERR_REENTRANCY:
err = _("reentrancy problem.");
break;
case DMLERR_SERVER_DIED:
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.");
break;
case DMLERR_UNADVACKTIMEOUT:
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.\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);
}
return err;
}
#endif
// wxUSE_IPC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -