⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dde.cpp

📁 A*算法 A*算法 A*算法 A*算法A*算法A*算法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
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 + -