void CNetDDESvrApp::OnAdvise(CDDELink* pLink, const CDDEData* pData) { ASSERT(pData != NULL); // Ignore Advise, if during an Advise Start. if (pLink == NULL) return; CDDEConv* pConv = pLink->Conversation(); CBuffer oData = pData->GetBuffer(); // Find the links' value in the cache. CLinkValue* pValue = m_oLinkCache.Find(pConv, pLink); // Discard duplicate updates. if ((App.m_bDiscardDups) && (pValue != NULL) && (pValue->m_oLastValue == oData)) { if (App.m_bTraceUpdates) App.Trace(TXT("DDE_ADVISE: %s %s (ignored)"), pConv->Service(), pLink->Item()); return; } // Create a cache entry, if a new link. if (pValue == NULL) pValue = m_oLinkCache.Create(pConv, pLink); ASSERT(pValue != NULL); // Update links' cached value. pValue->m_oLastValue = oData; pValue->m_tLastUpdate = CDateTime::Current(); // Create advise packet. HCONV hConv = pConv->Handle(); CBuffer oBuffer; CMemStream oStream(oBuffer); oStream.Create(); oStream.Write(&hConv, sizeof(hConv)); oStream << pLink->Item(); oStream << (uint32) pLink->Format(); oStream << oData; oStream << true; oStream.Close(); CNetDDEPacket oPacket(CNetDDEPacket::DDE_ADVISE, oBuffer); // Notify all NetDDEClients... for (size_t i = 0; i < m_aoConnections.Size(); ++i) { CNetDDESvrSocket* pConnection = m_aoConnections[i]; // Ignore, if connection severed. if (!pConnection->IsOpen()) continue; // Connection references link? if (pConnection->IsLinkUsed(pLink)) { try { if (App.m_bTraceUpdates) { uint nFormat = pLink->Format(); CString strData; if (nFormat == CF_TEXT) strData = oData.ToString(ANSI_TEXT); else if (nFormat == CF_UNICODETEXT) strData = oData.ToString(UNICODE_TEXT); else strData = CClipboard::FormatName(nFormat); App.Trace(TXT("DDE_ADVISE: %s %s [%s]"), pConv->Service(), pLink->Item(), strData); } // Send advise message. pConnection->SendPacket(oPacket); // Update stats. ++m_nPktsSent; } catch (CSocketException& e) { App.Trace(TXT("SOCKET_ERROR: %s"), e.twhat()); } } } }
void CNetDDESvrApp::OnDDEPoke(CNetDDESvrSocket& oConnection, CNetDDEPacket& oReqPacket) { ASSERT(oReqPacket.DataType() == CNetDDEPacket::DDE_POKE); bool bResult = false; HCONV hConv; uint32 nConvID; CString strItem; uint32 nFormat; CBuffer oData; // Decode message. CMemStream oStream(oReqPacket.Buffer()); oStream.Open(); oStream.Seek(sizeof(CNetDDEPacket::Header)); oStream.Read(&hConv, sizeof(hConv)); oStream >> nConvID; oStream >> strItem; oStream >> nFormat; oStream >> oData; oStream.Close(); if (App.m_bTraceRequests) { CString strData; if (nFormat == CF_TEXT) strData = oData.ToString(ANSI_TEXT); else if (nFormat == CF_UNICODETEXT) strData = oData.ToString(UNICODE_TEXT); else strData = CClipboard::FormatName(nFormat); App.Trace(TXT("DDE_POKE: %s %s [%s]"), strItem, CClipboard::FormatName(nFormat), strData); } try { // Locate the conversation. CDDECltConv* pConv = m_pDDEClient->FindConversation(hConv); if (pConv != NULL) { // Call DDE to do the poke. pConv->Poke(strItem, nFormat, oData.Buffer(), oData.Size()); bResult = true; } } catch (CDDEException& e) { App.Trace(TXT("DDE_ERROR: %s"), e.twhat()); } // Create response message. CBuffer oRspBuffer; CMemStream oRspStream(oRspBuffer); oRspStream.Create(); oRspStream << bResult; oRspStream.Close(); // Send response message. CNetDDEPacket oRspPacket(CNetDDEPacket::DDE_POKE, oReqPacket.PacketID(), oRspBuffer); oConnection.SendPacket(oRspPacket); // Update stats. ++m_nPktsSent; }