📄 dde_stuf.cpp
字号:
while (pCurItem != NULL)
{
if (strcmp (aName, pCurItem->GetName ()) == 0) return pCurItem;
pCurItem = (C_DDE_Item*)GetNext ();
}
return NULL;
}
//-------------------------------------------------------------------------------------
// Function: GetItemWithHandle
// This function returns a pointer to an item in this topic's item list whose
// name string handle matches the given name, or NULL if no items match.
C_DDE_Item* C_DDE_Topic::GetItemWithHandle (HSZ hszName)
{
#ifdef MT_DEBUG_MODE
char str[32];
DdeQueryString (idInstance, hszName, str, 30, CP_DDESERV);
TakeDebugNote ("Looking for item with handle %08X named \"%s\"\n",
(int)hszName, str);
#endif
// Go through the data item list, until we find the one we want
C_DDE_Item* pCurItem = (C_DDE_Item*)GetHead ();
while (pCurItem != NULL)
{
if (DdeCmpStringHandles (hszName, pCurItem->GetStringHandle ()) == 0)
return pCurItem;
pCurItem = (C_DDE_Item*)GetNext ();
}
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Topic not found.\n");
#endif
return NULL;
}
//-------------------------------------------------------------------------------------
// Function: SendAdviseData
// This function calls the SendAdviseData() methods for all the items in the
// topic's item list to give them a chance to check if their data has been
// changed and if it has, to send an advise message to DDEML saying it changed.
bool C_DDE_Topic::SendAdviseData (void)
{
// Go through the data item list, asking every item we find to check for changes
C_DDE_Item* pCurItem = (C_DDE_Item*) GetHead ();
while (pCurItem != NULL)
{
pCurItem->SendAdviseData ();
pCurItem = (C_DDE_Item*) GetNext ();
}
return true;
}
//-------------------------------------------------------------------------------------
// Function: PokeChangedData
// This function calls the PokeChangedData() methods for all the items in the
// topic's item list to give them a chance to check if their data has been
// changed and if it has, to send the changed data to servers which need it.
bool C_DDE_Topic::PokeChangedData (HCONV aConversation)
{
// Go through the data item list, asking every item we find to check for changes
C_DDE_Item* pCurItem = (C_DDE_Item*) GetHead ();
while (pCurItem != NULL)
{
pCurItem->PokeChangedData (aConversation);
pCurItem = (C_DDE_Item*) GetNext ();
}
return true;
}
//-------------------------------------------------------------------------------------
// Function: StartAdviseLinks
// This function tells all the items which belong to this topic to initiate
// advise links to a server so that the server can automatically update the
// data in these items if the server's copy of the data changes.
void C_DDE_Topic::StartAdviseLinks (HCONV aConversation)
{
C_DDE_Item* pCurItem = (C_DDE_Item*) GetHead ();
while (pCurItem != NULL)
{
pCurItem->StartAdviseLink (aConversation);
pCurItem = (C_DDE_Item*) GetNext ();
}
}
//-------------------------------------------------------------------------------------
// Function: EndAdviseLinks
// This function tells each item in the list to break its advise link, if one
// has been set up.
void C_DDE_Topic::EndAdviseLinks (HCONV aConversation)
{
C_DDE_Item* pCurItem = (C_DDE_Item*) GetHead ();
while (pCurItem != NULL)
{
pCurItem->EndAdviseLink (aConversation);
pCurItem = (C_DDE_Item*) GetNext ();
}
}
//=====================================================================================
// Class: C_DDE_Manager
// This class encapsulates that part of the DDE interface code which is common to
// both the DDE server and DDE client objects. This includes holding basic DDE
// registration information and managing lists of topics and items.
//=====================================================================================
//-------------------------------------------------------------------------------------
// Constructor: C_DDE_Manager
// This constructor just initializes a few variables.
C_DDE_Manager::C_DDE_Manager (void) : CBasicList ()
{
ReadyToRegister = false; // Don't register with DDEML until ready
NumTopics = 0;
NumConnections = 0;
}
//-------------------------------------------------------------------------------------
// Destructor: C_DDE_Manager
// The DDE manager contains a list of topics, and the topics contain items; all
// these things use dynamically allocated memory. We free up their memory now
// by deleting the topics; the topics' destructors delete all the items.
C_DDE_Manager::~C_DDE_Manager (void)
{
C_DDE_Topic* pTemp;
C_DDE_Topic* pCurTopic = (C_DDE_Topic*) GetHead ();
while (pCurTopic != NULL)
{
pTemp = pCurTopic;
pCurTopic = (C_DDE_Topic*) GetNext ();
delete (pTemp);
}
}
//-------------------------------------------------------------------------------------
// Function: Register_DDE
// The registration of the client or server's items and topics must be done in
// the DDEML thread, not the user thread; but it must be done after the user has
// set up the topics and items. This function sets a flag telling the DDE thread
// that it's time to register the topic and item names and stuff with DDEML now.
void C_DDE_Manager::Register_DDE (void)
{
ReadyToRegister = true;
}
//-------------------------------------------------------------------------------------
// Function: GetTopicWithName
// This function returns a pointer to a topic in the topic list whose name
// matches the given name. If no item matches, it returns NULL.
C_DDE_Topic* C_DDE_Manager::GetTopicWithName (const char* aName)
{
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Looking for topic \"%s\"\n", aName);
#endif
// Go through the topic list until we find the one we want or run out of topics
C_DDE_Topic* pCurTopic = (C_DDE_Topic*)GetHead ();
while (pCurTopic != NULL)
{
if (strcmp (aName, pCurTopic->GetName ()) == 0) return pCurTopic;
pCurTopic = (C_DDE_Topic*)GetNext ();
}
// If we get here, we didn't find any matching topics
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Topic not found.\n");
#endif
return NULL;
}
//-------------------------------------------------------------------------------------
// Function: GetTopicWithHandle
// If there is a topic in the list with the given DDE name string handle, this
// function returns a pointer to it. If not, this function returns NULL.
C_DDE_Topic* C_DDE_Manager::GetTopicWithHandle (HSZ hszName)
{
#ifdef MT_DEBUG_MODE
char str[32];
DdeQueryString (idInstance, hszName, str, 30, CP_DDESERV);
TakeDebugNote ("Looking for topic with handle %08X named \"%s\"\n",
(int)hszName, str);
#endif
// Go through the data item list, until we find the one we want
C_DDE_Topic* pCurTopic = (C_DDE_Topic*)GetHead ();
while (pCurTopic != NULL)
{
// If we've found the right one, return a pointer to it; if not, keep looking
if (DdeCmpStringHandles (hszName, pCurTopic->GetStringHandle ()) == 0)
return pCurTopic;
pCurTopic = (C_DDE_Topic*)GetNext ();
}
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Topic not found.\n");
#endif
return NULL;
}
//-------------------------------------------------------------------------------------
// Function: GetItemWithName
// This function returns a pointer to an item whose name matches the given name.
// The items are kept in the topics' item lists, so this function has to ask each
// of the topics if it has the item. If no item matches, it returns NULL.
C_DDE_Item* C_DDE_Manager::GetItemWithName (const char* aName)
{
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Looking for item \"%s\"\n", aName);
#endif
// Go through the data item list, until we find the one we want
C_DDE_Item* pItem;
C_DDE_Topic* pCurTopic = (C_DDE_Topic*)GetHead ();
while (pCurTopic != NULL)
{
if ((pItem = pCurTopic->GetItemWithName (aName)) != NULL)
return pItem;
pCurTopic = (C_DDE_Topic*)GetNext ();
}
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Item not found.\n");
#endif
return NULL;
}
//-------------------------------------------------------------------------------------
// Function: GetItemWithHandle
// If there is an item belonging to a topic in the topic list with the given DDE
// name string handle, this function returns a pointer to it. If not, this
// function returns NULL.
C_DDE_Item* C_DDE_Manager::GetItemWithHandle (HSZ hszName)
{
#ifdef MT_DEBUG_MODE
char str[32];
DdeQueryString (idInstance, hszName, str, 30, CP_DDESERV);
TakeDebugNote ("Looking for item with handle %08X named \"%s\"\n",
(int)hszName, str);
#endif
// Go through the data item list, until we find the one we want
C_DDE_Item* pItem;
C_DDE_Topic* pCurTopic = (C_DDE_Topic*)GetHead ();
while (pCurTopic != NULL)
{
// If we've found the right one, return a pointer to it; if not, keep looking
if ((pItem = pCurTopic->GetItemWithHandle (hszName)) != NULL)
return pItem;
pCurTopic = (C_DDE_Topic*)GetNext ();
}
#ifdef MT_DEBUG_MODE
TakeDebugNote ("Item not found.\n");
#endif
return NULL;
}
//-------------------------------------------------------------------------------------
// Function: AddTopic
// This function adds a new topic to the DDE manager's topic list. The topic is
// just put on the end of the list because there's no particular order.
C_DDE_Topic* C_DDE_Manager::AddTopic (const char* aName)
{
C_DDE_Topic* pNew = new C_DDE_Topic (aName);
CBasicList::Insert ((void*)pNew);
NumTopics++;
return (pNew);
}
//=====================================================================================
// Class: C_DDE_Server
// This class encapsulates a DDE server. When set up by the user's program, it
// will maintain a database of variables whose values can be queried by a client
// program. DDE clients will be able to read and set the values of the data by
// making REQUEST and POKE type DDE transactions.
//=====================================================================================
//-------------------------------------------------------------------------------------
// Constructor: C_DDE_Server
// This constructor is called to create a DDE server object. It actually just
// creates a new thread within which the DDEML system can run, and the thread's
// main function calls Initialize() to set up the DDEML so that the server will
// be ready to begin communicating with clients.
C_DDE_Server::C_DDE_Server (const char* aName) : C_DDE_Manager ()
{
// Set the pointer to this object so that the DDEML callback can find it
The_DDE_Server = this;
// Set the flag so thread won't stop, then create a new thread for DDEML
DDE_ServerTimeToStop = false;
HANDLE hThread = CreateThread (NULL, 0, DDE_ServerThreadFunction, NULL, 0,
&dwThreadId);
if (hThread == NULL)
MessageBox (NULL, "Cannot create thread", "DDE Error", MB_OK | MB_ICONSTOP);
// Save the service name in a character string and initialize other variables
ServiceName = new char[strlen (aName) + 1];
strcpy (ServiceName, aName);
phszPair = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -