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

📄 dde_stuf.cpp

📁 a program that generates a pulse-width modulated (PWM)signal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:

//-------------------------------------------------------------------------------------
//  Destructor:  ~C_DDE_Server
//      This destructor frees the memory used by the DDE server and any item objects
//      which it might have created.

C_DDE_Server::~C_DDE_Server (void)
    {
    int Timeout;                            //  Counts "time" for thread to finish

    //  Tell the DDE thread that it's time to exit now and close its window
    DDE_ServerTimeToStop = true;

    //  Delete the server/topic pair array and service name
    if (phszPair != NULL) delete [] phszPair;
    delete [] ServiceName;

    //  We should wait until the DDE thread has exited before going any further
    for (Timeout = 0L; Timeout < MAX_TIMEOUT; Timeout++)
        {
        Sleep (20);
        if (DDE_ServerThreadDone == true) break;
        }

    //  If the wait loop timed out, the wait for the DDE thread to exit was too long
    if (Timeout >= MAX_TIMEOUT)
        MessageBox (NULL, "DDE server thread not exiting on time", "DDE Warning",
                    MB_OK | MB_ICONEXCLAMATION);
    }


//-------------------------------------------------------------------------------------
//  Function:  Initialize
//      The DDE server's constructor starts up a thread, and the thread function calls
//      this function to initialize the DDEML system from within the newly started
//      thread.

void C_DDE_Server::Initialize (void)
    {
    //  Try to initialize DDE and get an instance handle
    idInstance = 0L;
    DdeInitialize ((LPDWORD)&idInstance, (PFNCALLBACK)DdeServerCallback,
                   APPCMD_FILTERINITS, 0L);

    //  Check for DDE errors and complain if any are found
    DDE_CheckForError (idInstance);

    //  Create string handle for service name; call user's function to create topic
    //  and item string handles
    hszService = DdeCreateStringHandle (idInstance, ServiceName, CP_DDESERV);
    if (hszService == 0L) DDE_CheckForError (idInstance);

    #ifdef MT_DEBUG_MODE
        TakeDebugNote ("Registering service \"%s\", handle %08X\n",
                       ServiceName, (int)hszService);
    #endif

    //  Register the service name.  This allows DDEML messages to come to this server
    DdeNameService (idInstance, hszService, NULL, DNS_REGISTER);
    DDE_CheckForError (idInstance);

    //  Register each of the topic names; the topic's registration function calls
    //  the registration functions of each of the items too
    C_DDE_Topic* pCurTopic = (C_DDE_Topic*) GetHead ();
    while (pCurTopic != NULL)
        {
        pCurTopic->Register (idInstance);
        pCurTopic = (C_DDE_Topic*) GetNext ();
        }
    }


//-------------------------------------------------------------------------------------
//  Function:  Uninitialize
//      The DDE server's destructor tells the DDE thread to call this function.  This
//      function then uninitializes the DDEML system.

void C_DDE_Server::Uninitialize (void)
    {
    #ifdef MT_DEBUG_MODE
        TakeDebugNote ("Uninitializing DDEML system\n");
    #endif

    if (idInstance != 0L)
        DdeUninitialize (idInstance);       //  Shut down the DDE server if it's up

    The_DDE_Server = NULL;                  //  Un-set the callback's pointer
    }


//-------------------------------------------------------------------------------------
//  Function:  SendAdviseData
//      This function tells all the topics owned by this server to tell all the items
//      which they own to update their advise-linked data.  If any of the items' data
//      has changed, the items will inform the client of the change of data.

bool C_DDE_Server::SendAdviseData (void)
    {
    //  Go through the topic list, asking every topic we find to do an update
    C_DDE_Topic* pTopic = (C_DDE_Topic*) GetHead ();
    while (pTopic != NULL)
        {
        pTopic->SendAdviseData ();
        pTopic = (C_DDE_Topic*) GetNext ();
        }

    return true;
    }


//-------------------------------------------------------------------------------------
//  Function:  SetServiceName
//      This function allows the user to specify the service name.

void C_DDE_Server::SetServiceName (const char* aName)
    {
    //  Un-register the previously registered service name
    DdeNameService (idInstance, hszService, NULL, DNS_UNREGISTER);

    //  Create a new string handle for the service name and register it
    hszService = DdeCreateStringHandle (idInstance, aName, CP_DDESERV);
    if (hszService == 0L) DDE_CheckForError (idInstance);

    DdeNameService (idInstance, hszService, NULL, DNS_REGISTER);
    DDE_CheckForError (idInstance);
    }


//-------------------------------------------------------------------------------------
//  Function:  ConnectClient
//      A client somewhere has requested a connection with a server, and the client
//      has specified a service name and a topic name in which it's interested.  If
//      the service and topic names match names supported by this server, hook on up.

HDDEDATA C_DDE_Server::ConnectClient (HSZ hsz1, HSZ hsz2)
    {
    //  If the service name matches, look for a match in each of the topic names
    if (hszService == hsz2)
        {
        C_DDE_Topic* pCurTopic = (C_DDE_Topic*)GetHead ();
        while (pCurTopic != NULL)
            {
            if (hsz1 == pCurTopic->GetStringHandle ()) return (HDDEDATA)TRUE;
            pCurTopic = (C_DDE_Topic*)GetNext ();
            }
        }

    //  Oh well, nothing matched
    return (HDDEDATA)FALSE;
    }


//-------------------------------------------------------------------------------------
//  Function:  WildConnect
//      If a client object is sniffing around trying to find all the service and/or
//      topic names supported by applications running on the system, the DDEML
//      callback will call this function.  It returns an array of service name/topic
//      name pairs which are supported by this server and match any given names.

HDDEDATA C_DDE_Server::WildConnect (HSZ hsz1, HSZ hsz2)
    {
    //  If the client's looking for this service name or any service name, fill the
    //  array of pairs of service and topic names and add a NULL/NULL pair at the end
    if ((hsz2 == hszService) || (hsz2 == NULL))
        {
        int nTopic = 0;                     //  Index for array of service/topic pairs

        //  Create or re-create array of handle pairs to hold service and topic names
        if (phszPair != NULL) delete [] phszPair;
        phszPair = new HSZPAIR[NumTopics + 1];

        for (C_DDE_Topic* pCurTopic = (C_DDE_Topic*)GetHead (); pCurTopic != NULL;
            pCurTopic = (C_DDE_Topic*)GetNext ())
            {
            //  Only create a pair of names for the list if the topic name matches
            if ((hsz1 == NULL) || (hsz1 == pCurTopic->GetStringHandle ()))
                {
                phszPair[nTopic].hszSvc = hszService;
                phszPair[nTopic].hszTopic = pCurTopic->GetStringHandle ();
                nTopic++;
                }
            }
        //  Add a pair of NULL service and topic names to mark the end of the list
        phszPair[nTopic].hszSvc = (HSZ)NULL;
        phszPair[nTopic].hszTopic = (HSZ)NULL;
        return (HDDEDATA)DdeCreateDataHandle (idInstance, (LPBYTE)phszPair,
                (NumTopics + 1) * sizeof (HSZPAIR), 0L, 0, CF_TEXT, 0);
        }

    //  If the service name is wrong, don't send back any information about topics
    return (HDDEDATA)FALSE;
    }


//-------------------------------------------------------------------------------------
//  Function:  RequestData
//      This function responds to a client application which has sent an XTYP_REQUEST
//      message through DDE to the server.  It looks for a data item whose topic and
//      item names match those given.  If it finds one, it formats the data in text
//      clipboard format and returns a handle to it.  If no topic and data names match
//      then this function returns the not-processed code.

HDDEDATA C_DDE_Server::RequestData (WORD wFormat, HSZ hsz1, HSZ hsz2)
    {
    static char DataString[256];            //  Place to store string sent to DDEML

    //  This server only supports the CF_TEXT format
    if (wFormat != CF_TEXT) return (HDDEDATA)DDE_FNOTPROCESSED;

    //  Look for a topic whose name is the same as that the client's looking for
    C_DDE_Topic* TheTopic;
    if ((TheTopic = GetTopicWithHandle (hsz1)) != NULL)
        {
        //  Look for an item belonging to that topic with the correct item name
        C_DDE_Item* TheItem;
        if ((TheItem = TheTopic->GetItemWithHandle (hsz2)) != NULL)
            {
            //  We found the right item - convert its data to a string and send it
            strcpy (DataString, TheItem->DataToString ());
            #ifdef MT_DEBUG_MODE
                TakeDebugNote ("Sending data \"%s\"\n", DataString);
            #endif
            return (HDDEDATA)DdeCreateDataHandle (idInstance, (LPBYTE)DataString,
                                       strlen (DataString) + 1, 0L, hsz2, CF_TEXT, 0);
            }
        }

    //  If the names don't match, return the code for "I can't do it"
    return (HDDEDATA)DDE_FNOTPROCESSED;
    }


//-------------------------------------------------------------------------------------
//  Function:  PokeData
//      This function responds to a client application which has sent an XTYP_POKE
//      message through DDE to the server.  It looks for a data item whose topic and
//      item names match those given.  If it finds one, it gets the data which was
//      sent, saves that data in the local data item, and returns an acknowledgement.
//      If the topic and data names don't match, then this function returns the
//      not-processed code and doesn't mess with the local copy of the data.

HDDEDATA C_DDE_Server::PokeData (WORD wFormat, HSZ hsz1, HSZ hsz2, HDDEDATA hData)
    {
    static char DataBuffer[256];            //  Place to keep text strings with data

    //  This server only supports the CF_TEXT format
    if (wFormat != CF_TEXT) return (HDDEDATA)DDE_FNOTPROCESSED;

    //  Look for a topic whose name is the same as that the client's looking for
    C_DDE_Topic* TheTopic;
    if ((TheTopic = GetTopicWithHandle (hsz1)) != NULL)
        {
        //  Look for an item belonging to that topic with the correct item name
        C_DDE_Item* TheItem;
        if ((TheItem = TheTopic->GetItemWithHandle (hsz2)) != NULL)
            {
            //  We found the right item; read the data which it gave us and save it
            DdeGetData (hData, (LPBYTE)DataBuffer, 254L, 0L);
            TheItem->StringToData (DataBuffer);
            #ifdef MT_DEBUG_MODE
                TakeDebugNote ("Receiving poked data \"%s\"\n", DataBuffer);
            #endif
            return (HDDEDATA)DDE_FACK;
            }
        }

    //  If the names don't match, return the code for "I can't do it"
    return (HDDEDATA)DDE_FNOTPROCESSED;
    }


//-------------------------------------------------------------------------------------
//  Function:  AdviseStart
//      This function responds to a client's XTYP_ADVSTART message.  It looks for an
//      item with the correct item and topic names which can be linked to the client
//      and if it finds one, it sends back a message to indicate the link is working.

HDDEDATA C_DDE_Server::AdviseStart (WORD wFormat, HSZ hsz1, HSZ hsz2)
    {
    //  This server only supports the CF_TEXT format
    if (wFormat != CF_TEXT) return (HDDEDATA)FALSE;

    //  Look for a topic whose name is the same as that the client's looking for
    C_DDE_Topic* TheTopic;
    if ((TheTopic = GetTopicWithHandle (hsz1)) != NULL)
        {
        //  Look for an item belonging to that topic with the correct item name
        C_DDE_Item* TheItem;
        if ((TheItem = TheTopic->GetItemWithHandle (hsz2)) != NULL)
            {
            //  We found the right item; tell the client we can support it unless it
            //  has already been advise-linked
            if (TheItem->IsAdviseLinked () == false)
                {
                TheItem->AdviseLink ();
                #ifdef MT_DEBUG_MODE
                    TakeDebugNote ("Setting up advise link on item \"%s\"\n",
                                   TheItem->GetName ());
                #endif
                return (HDDEDATA)TRUE;
                }
            }
        }
    //  If we get here, the item the client wants isn't supported
    #ifdef MT_DEBUG_MODE
        TakeDebugNote ("Cannot do advise link on item %08X\n", hsz2);
    #endif
    return (HDDEDATA)FALSE;
    }


//-------------------------------------------------------------------------------------
//  Function:  AdviseRequest
//      This function responds to a client's XTYP_ADVREQ message.  The client is
//      asking for some data; if the request is acceptable (format, topic and item)
//      then send the data to the client.  If not, send it a virtual raspberry.

HDDEDATA C_DDE_Server::AdviseRequest (WORD wFormat, HSZ hsz1, HSZ hsz2)
    {
    static char DataString[256];            //  Place to store string sent to DDEML

    //  This server only supports the CF_TEXT format
    if (wFormat != CF_TEXT) return (HDDEDATA)FALSE;

    //  Look for a topic whose name is the same as that the client's looking for
    C_DDE_Topic* TheTopic;
    if ((TheTopic = GetTopicWithHandle (hsz1)) != NULL)
        {
        //  Look for an item belonging to that topic with the correct item name

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -