Example #1
0
HDDEDATA CMyServer::CustomCallback(WORD wType,
                                  WORD wFmt,
                                  HCONV hConv,
                                  HSZ hsz1,
                                  HSZ hsz2,
                                  HDDEDATA hData,
                                  DWORD dwData1,
                                  DWORD dwData2)
  {
  switch (wType)
    {
    case XTYP_ADVSTOP:
      {
      CString strTopic = StringFromHsz(hsz1);
      CDDETopic* pTopic = FindTopic(strTopic);
      if (pTopic)
        {
        pDdeExec->Dde.Lock();
        CString strItem = StringFromHsz(hsz2);
        CDDEItem* pItem = pTopic->FindItem((const char*)strItem);
        if (pItem)
          {
          pItem->RemoveConv(hConv);
          if (pItem->ConvCount()==0)
            if (pTopic->RemoveItem((const char*)strItem))
              {
              int i = pDdeExec->FindSubsData(pItem);
              if (i>=0)
                {
                pDdeExec->SubsData[i]->pItem = NULL;
                pDdeExec->XBuildMyDataLists();
//dbgpln("SubsData[%i]:NULL", i);
                }
              }
          }
        pDdeExec->Dde.Release();
        }
      break;
      }
    }
  return NULL;
  }
Example #2
0
BOOL CDDEServer::DoCallback(WORD wType,
                            WORD wFmt,
                            HCONV hConv,
                            HSZ hszTopic,
                            HSZ hszItem,
                            HDDEDATA hData,
                            HDDEDATA *phReturnData)
{
    //
    // See if we know the topic
    //

    CString strTopic = StringFromHsz(hszTopic);

    //
    // See if this is an execute request
    //

    if (wType == XTYP_EXECUTE) {

        //
        // Call the exec function to process it
        //

        Status(_T("Exec"));
        DWORD dwLength = 0;
        void* pData = ::DdeAccessData(hData, &dwLength);
        BOOL b = Exec(strTopic, pData, dwLength);
        ::DdeUnaccessData(hData);
        
        if (b) {

            *phReturnData = (HDDEDATA) DDE_FACK;
            return TRUE; // MH - Say we processed it

        }

        //
        // Either no handler or it didn't get handled by the function
        //

        Status(_T("Exec failed"));
        *phReturnData = (HDDEDATA) DDE_FNOTPROCESSED;
        return FALSE;
    }

    //
    // See if this is a connect request. Accept it if it is.
    //

    if (wType == XTYP_CONNECT) {

        if (!FindTopic(strTopic)) return FALSE; // unknown topic
        *phReturnData = (HDDEDATA) TRUE;
        return TRUE;
    }

    //
    // For any other transaction we need to be sure this is an
    // item we support and in some cases, that the format requested
    // is supported for that item.
    //

    CString strItem = StringFromHsz(hszItem);

    //
    // Now just do whatever is required for each specific transaction
    //

    BOOL b = FALSE;
    DWORD dwLength = 0;
    void* pData = NULL;

    switch (wType) {
    case XTYP_ADVSTART:

        //
        // Confirm that the supported topic/item pair is OK and
        // that the format is supported

        if (!CanAdvise(wFmt, strTopic, strItem)) {

            Status(_T("Can't advise on %s|%s"), (const TCHAR*)strTopic, (const TCHAR*)strItem);
            return FALSE;
        }

        //
        // Start an advise request.  Topic/item and format are ok.
        //

        *phReturnData = (HDDEDATA) TRUE;
        break;

    case XTYP_POKE:

        //
        // Some data for one of our items. 
        //

        pData = ::DdeAccessData(hData, &dwLength);
        b = Poke(wFmt, strTopic, strItem, pData, dwLength);
        ::DdeUnaccessData(hData);

        if (!b) {

            //
            // Nobody took the data.
            // Maybe its not a supported item or format
            //

            Status(_T("Poke %s|%s failed"), (const TCHAR*)strTopic, (const TCHAR*)strItem); 
            return FALSE;

        }

        //
        // Data at the server has changed.  See if we
        // did this ourself (from a poke) or if it's from
        // someone else.  If it came from elsewhere then post
        // an advise notice of the change.
        //

        CONVINFO ci;
        ci.cb = sizeof(CONVINFO);
        if (::DdeQueryConvInfo(hConv, (DWORD)QID_SYNC, &ci)) {

            if (! (ci.wStatus & ST_ISSELF)) {

                //
                // It didn't come from us
                //

                ::DdePostAdvise(m_dwDDEInstance,
                              hszTopic,
                              hszItem);
            }
        }

        *phReturnData = (HDDEDATA) DDE_FACK; // say we took it
        break;

    case XTYP_ADVDATA:

        //
        // A server topic/item has changed value
        //

        pData = ::DdeAccessData(hData, &dwLength);
        b = AdviseData(wFmt, hConv, strTopic, strItem, pData, dwLength);
        ::DdeUnaccessData(hData);

        if (!b) {

            //
            // Nobody took the data.
            // Maybe its not of interrest
            //

            Status(_T("AdviseData %s|%s failed"), (const TCHAR*)strTopic, (const TCHAR*)strItem); 
            *phReturnData = (HDDEDATA) DDE_FNOTPROCESSED;

        } else {

            *phReturnData = (HDDEDATA) DDE_FACK; // say we took it
        }
        break;

    case XTYP_ADVREQ:
    case XTYP_REQUEST:

        //
        // Attempt to start an advise or get the data on a topic/item
        // See if we have a request function for this item or
        // a generic one for the topic
        //
        { // scope for locals.

        CDDEAllocator allocr(m_dwDDEInstance, hszItem, wFmt, phReturnData);
        Status(_T("Request %s|%s"), (const TCHAR*)strTopic, (const TCHAR*)strItem); 
        dwLength = 0;
        if (!Request(wFmt, strTopic, strItem, allocr)) {
            // 
            // Nobody accepted the request
            // Maybe unsupported topic/item or bad format
            //

            Status(_T("Request %s|%s failed"), (LPCTSTR)strTopic, (LPCTSTR)strItem); 
            *phReturnData = NULL;
            return FALSE;

        }

        } // end locals scope
        // Data already setup via 'allocr' param, so we are done.
        break;

    default:
        break;
    }

    //
    // Say we processed the transaction in some way
    //

    return TRUE;

}
Example #3
0
HDDEDATA CDDEServer::DoWildConnect(HSZ hszTopic)
{
    //
    // See how many topics we will be returning
    //

    int iTopics = 0;
    CString strTopic = "<null>";
    if (hszTopic == NULL) {

        //
        // Count all the topics we have
        //

        iTopics = m_TopicList.GetCount();

    } else {

        //
        // See if we have this topic in our list
        //

        strTopic = StringFromHsz(hszTopic);
        CDDETopic* pTopic = FindTopic(strTopic);
        if(pTopic) {
            iTopics++;
        }
    }

    //
    // If we have no match or no topics at all, just return
    // NULL now to refuse the connect
    //

    if (!iTopics) {
        Status(_T("Wild connect to %s refused"), (const TCHAR*)strTopic);
        return (HDDEDATA) NULL;
    }

    //
    // Allocate a chunk of DDE data big enough for all the HSZPAIRS
    // we'll be sending back plus space for a NULL entry on the end
    //

    HDDEDATA hData = ::DdeCreateDataHandle(m_dwDDEInstance,
                                  NULL,
                                  (iTopics + 1) * sizeof(HSZPAIR),
                                  0,
                                  NULL,
                                  0,
                                  0);

    //
    // Check we actually got it.
    //

    if (!hData) return (HDDEDATA) NULL;

    HSZPAIR* pHszPair = (PHSZPAIR) DdeAccessData(hData, NULL);

    //
    // Copy the topic data
    //

    if (hszTopic == NULL) {

        //
        // Copy all the topics we have (includes the system topic)
        //

        POSITION pos = m_TopicList.GetHeadPosition();
        while (pos) {

            CDDETopic* pTopic = m_TopicList.GetNext(pos);
            pHszPair->hszSvc = ::DdeCreateStringHandle(m_dwDDEInstance,
                                                       (TCHAR*)(const TCHAR*)m_strServiceName,
                                                       DDE_STRING_CODEPAGE);
            pHszPair->hszTopic = ::DdeCreateStringHandle(m_dwDDEInstance,
                                                         (TCHAR*)(const TCHAR*)pTopic->m_strName,
                                                         DDE_STRING_CODEPAGE);

            pHszPair++;
        }

    } else {

        //
        // Just copy the one topic asked for
        //

        pHszPair->hszSvc = m_hszServiceName;
        pHszPair->hszTopic = hszTopic;

        pHszPair++;

    }

    //
    // Put the terminator on the end
    //

    pHszPair->hszSvc = NULL;
    pHszPair->hszTopic = NULL;

    //
    // Finished with the data block
    //

    ::DdeUnaccessData(hData);

    //
    // Return the block handle
    //

    return hData;
}