📄 dde.cpp
字号:
bool wxDDEServer::DeleteConnection(WXHCONV conv)
{
wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst();
while (node)
{
wxDDEConnection *connection = node->GetData();
if (connection->m_hConv == conv)
{
m_connections.Erase(node);
return true;
}
else
{
node = node->GetNext();
}
}
return false;
}
// ----------------------------------------------------------------------------
// wxDDEClient
// ----------------------------------------------------------------------------
wxDDEClient::wxDDEClient()
{
wxDDEInitialize();
wxDDEClientObjects.Append(this);
}
wxDDEClient::~wxDDEClient()
{
wxDDEClientObjects.DeleteObject(this);
wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst();
while (node)
{
wxDDEConnection *connection = node->GetData();
delete connection; // Deletes the node implicitly (see ~wxDDEConnection)
node = m_connections.GetFirst();
}
}
bool wxDDEClient::ValidHost(const wxString& /* host */)
{
return true;
}
wxConnectionBase *wxDDEClient::MakeConnection(const wxString& WXUNUSED(host),
const wxString& server,
const wxString& topic)
{
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()) );
}
else
{
wxDDEConnection *connection = (wxDDEConnection*) OnMakeConnection();
if (connection)
{
connection->m_hConv = (WXHCONV) hConv;
connection->m_topicName = topic;
connection->m_client = this;
m_connections.Append(connection);
return connection;
}
}
return (wxConnectionBase*) NULL;
}
wxConnectionBase *wxDDEClient::OnMakeConnection()
{
return new wxDDEConnection;
}
wxDDEConnection *wxDDEClient::FindConnection(WXHCONV conv)
{
wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst();
wxDDEConnection *found = NULL;
while (node && !found)
{
wxDDEConnection *connection = node->GetData();
if (connection->m_hConv == conv)
found = connection;
else node = node->GetNext();
}
return found;
}
// Only delete the entry in the map, not the actual connection
bool wxDDEClient::DeleteConnection(WXHCONV conv)
{
wxDDEConnectionList::compatibility_iterator node = m_connections.GetFirst();
while (node)
{
wxDDEConnection *connection = node->GetData();
if (connection->m_hConv == conv)
{
m_connections.Erase(node);
return true;
}
else node = node->GetNext();
}
return false;
}
// ----------------------------------------------------------------------------
// wxDDEConnection
// ----------------------------------------------------------------------------
wxDDEConnection::wxDDEConnection(wxChar *buffer, int size)
: wxConnectionBase(buffer, size)
{
m_client = NULL;
m_server = NULL;
m_hConv = 0;
m_sendingData = NULL;
}
wxDDEConnection::wxDDEConnection()
: wxConnectionBase()
{
m_hConv = 0;
m_sendingData = NULL;
m_server = NULL;
m_client = NULL;
}
wxDDEConnection::~wxDDEConnection()
{
Disconnect();
if (m_server)
m_server->GetConnections().DeleteObject(this);
else
m_client->GetConnections().DeleteObject(this);
}
// Calls that CLIENT can make
bool wxDDEConnection::Disconnect()
{
if ( !GetConnected() )
return true;
DDEDeleteConnection(GetHConv());
bool ok = DdeDisconnect(GetHConv()) != 0;
if ( !ok )
{
DDELogError(_T("Failed to disconnect from DDE server gracefully"));
}
SetConnected( false ); // so we don't try and disconnect again
return ok;
}
bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat WXUNUSED(format))
{
DWORD result;
if (size < 0)
{
size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
}
bool ok = DdeClientTransaction((LPBYTE)data,
size,
GetHConv(),
NULL,
// 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,
&result) != 0;
if ( !ok )
{
DDELogError(_T("DDE execute request failed"));
}
return ok;
}
wxChar *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat format)
{
DWORD result;
HSZ atom = DDEGetAtom(item);
HDDEDATA returned_data = DdeClientTransaction(NULL, 0,
GetHConv(),
atom, format,
XTYP_REQUEST,
DDE_TIMEOUT,
&result);
if ( !returned_data )
{
DDELogError(_T("DDE data request failed"));
return NULL;
}
DWORD len = DdeGetData(returned_data, NULL, 0, 0);
wxChar *data = GetBufferAtLeast( len );
wxASSERT_MSG(data != NULL,
_T("Buffer too small in wxDDEConnection::Request") );
(void) DdeGetData(returned_data, (LPBYTE)data, len, 0);
(void) DdeFreeDataHandle(returned_data);
if (size)
*size = (int)len;
return data;
}
bool wxDDEConnection::Poke(const wxString& item, wxChar *data, int 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,
size,
GetHConv(),
item_atom, format,
XTYP_POKE,
DDE_TIMEOUT,
&result) != 0;
if ( !ok )
{
DDELogError(_("DDE poke request failed"));
}
return ok;
}
bool wxDDEConnection::StartAdvise(const wxString& item)
{
DWORD result;
HSZ atom = DDEGetAtom(item);
bool ok = DdeClientTransaction(NULL, 0,
GetHConv(),
atom, CF_TEXT,
XTYP_ADVSTART,
DDE_TIMEOUT,
&result) != 0;
if ( !ok )
{
DDELogError(_("Failed to establish an advise loop with DDE server"));
}
return ok;
}
bool wxDDEConnection::StopAdvise(const wxString& item)
{
DWORD result;
HSZ atom = DDEGetAtom(item);
bool ok = DdeClientTransaction(NULL, 0,
GetHConv(),
atom, CF_TEXT,
XTYP_ADVSTOP,
DDE_TIMEOUT,
&result) != 0;
if ( !ok )
{
DDELogError(_("Failed to terminate the advise loop with DDE server"));
}
return ok;
}
// Calls that SERVER can make
bool wxDDEConnection::Advise(const wxString& item,
wxChar *data,
int 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?
m_dataSize = size;
// wxIPC_PRIVATE does not succeed, so use text instead
m_dataType = format == wxIPC_PRIVATE ? wxIPC_TEXT : format;
bool ok = DdePostAdvise(DDEIdInst, topic_atom, item_atom) != 0;
if ( !ok )
{
DDELogError(_("Failed to send DDE advise notification"));
}
return ok;
}
bool wxDDEConnection::OnDisconnect()
{
delete this;
return true;
}
// ----------------------------------------------------------------------------
// _DDECallback
// ----------------------------------------------------------------------------
#define DDERETURN HDDEDATA
HDDEDATA EXPENTRY _EXPORT
_DDECallback(WORD wType,
WORD wFmt,
HCONV hConv,
HSZ hsz1,
HSZ hsz2,
HDDEDATA hData,
DWORD WXUNUSED(lData1),
DWORD WXUNUSED(lData2))
{
switch (wType)
{
case XTYP_CONNECT:
{
wxString topic = DDEStringFromAtom(hsz1),
srv = DDEStringFromAtom(hsz2);
wxDDEServer *server = DDEFindServer(srv);
if (server)
{
wxDDEConnection *connection =
(wxDDEConnection*) server->OnAcceptConnection(topic);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -