home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
-
- MODULE: SERVDATA.C
-
- PURPOSE: Maintains conversation information.
-
-
- ****************************************************************************/
-
- #include "windows.h"
-
- #include "dde.h"
- #include "server.h"
- #include <string.h>
-
- struct CONV
- {
- HWND hwndServerDDE;
- HWND hwndClientDDE;
- BOOL bInClientRequestedTerminate;
- };
-
- struct ADVISE
- {
- HWND hwndServerDDE;
- HWND hwndClientDDE;
- int nItem;
- ATOM atomItem;
- BOOL bAckRequest;
- BOOL bDeferUpdate;
- BOOL bAwaitingAck;
- HANDLE hData;
- };
-
- struct CONV Conv[CONV_MAX_COUNT];
- static int nConvCount = 0;
- static struct ADVISE Advise[ADVISE_MAX_COUNT];
- static int nAdviseCount = 0;
-
- struct ADVISE * NEAR FindAdvise(HWND, int);
- struct CONV * NEAR FindConv(HWND);
-
-
- /****************************************************************************
-
- FUNCTION: AddAdvise
-
- PURPOSE: Register a new hot or warm link to a specified client, for
- a specified server application item (1, 2, or 3).
-
- ****************************************************************************/
- BOOL AddAdvise(hwndServerDDE, hDDEAdviseOptions, atomItem, nItem)
- HWND hwndServerDDE;
- HANDLE hDDEAdviseOptions;
- ATOM atomItem;
- int nItem;
- {
- struct ADVISE * pAdvise;
- DDEADVISE _Dfar * lpDDEAdviseOptions;
- int nAdviseIndex;
-
- if (nAdviseCount >= ADVISE_MAX_COUNT)
- {
- MessageBox(hwndMain,
- "Maximum advisories exceeded",
- "Server",
- MB_ICONEXCLAMATION | MB_OK);
- return (FALSE);
- }
- if ((lpDDEAdviseOptions
- = (DDEADVISE _Dfar *)GlobalLock(hDDEAdviseOptions)) == NULL)
- return (FALSE);
-
- for (pAdvise = Advise, nAdviseIndex = 0;
- nAdviseIndex < nAdviseCount;
- pAdvise++, nAdviseIndex++)
- {
- if (pAdvise->hwndServerDDE == hwndServerDDE
- && pAdvise->nItem == nItem)
- {
- MessageBox(hwndMain,
- "Advisory (paste link) already established",
- "Server",
- MB_ICONEXCLAMATION | MB_OK);
- GlobalUnlock(hDDEAdviseOptions);
- return (FALSE);
- }
- }
-
- pAdvise = Advise + nAdviseCount++;
-
- pAdvise->hwndServerDDE = hwndServerDDE;
- pAdvise->hwndClientDDE = GetHwndClientDDE(hwndServerDDE);
- pAdvise->nItem = nItem;
- pAdvise->atomItem = atomItem;
- pAdvise->bAckRequest = lpDDEAdviseOptions->fAckReq;
- pAdvise->bDeferUpdate = lpDDEAdviseOptions->fDeferUpd;
- pAdvise->bAwaitingAck = FALSE;
-
- GlobalUnlock(hDDEAdviseOptions);
- return (TRUE);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: AddConv
-
- PURPOSE: Register a new conversation with a client window
-
- ****************************************************************************/
- BOOL AddConv(hwndServerDDE, hwndClientDDE)
- HWND hwndServerDDE;
- HWND hwndClientDDE;
- {
- struct CONV * pConv;
-
- if (nConvCount >= CONV_MAX_COUNT)
- {
- return (FALSE);
- }
-
- if (FindConv(hwndServerDDE) != NULL)
- {
- return (FALSE); /* conversation already added */
- }
-
- pConv = Conv + nConvCount++;
- pConv->hwndServerDDE = hwndServerDDE;
- pConv->hwndClientDDE = hwndClientDDE;
- pConv->bInClientRequestedTerminate = FALSE;
- return (TRUE);
- }
-
-
-
- /***********************************************************************
-
- FUNCTION: AtLeastOneConvActive
-
- PURPOSE: Used during termination of application, to
- determine whether any conversations are still active
- while the conversations are being terminated.
-
- ***********************************************************************/
- BOOL AtLeastOneConvActive()
- {
- return (nConvCount? TRUE: FALSE);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: CheckOutSentData
-
- PURPOSE: Set Awaiting Ack state to true for specified item.
-
- ****************************************************************************/
- void CheckOutSentData(hwndServerDDE, nItem, atomItem, hData)
- HWND hwndServerDDE;
- int nItem;
- ATOM atomItem;
- HANDLE hData;
- {
- struct ADVISE * pAdvise;
-
- if ((pAdvise = FindAdvise(hwndServerDDE, nItem)) == 0)
- return;
- pAdvise->bAwaitingAck = TRUE;
- pAdvise->atomItem = atomItem;
- pAdvise->hData = hData;
- return;
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: DoEditCopy
-
- PURPOSE: Copy selected data to clipboard in two formats:
- CF_TEXT and (registered) "Link" format.
-
- ****************************************************************************/
- void DoEditCopy(nItem)
- int nItem;
- {
-
- /* Format string and set clipboard data here */
- HANDLE hTextData;
- HANDLE hConvData;
- char szItemValue[ITEM_VALUE_MAX_SIZE+1];
- LPSTR lpTextData, lpConvData;
-
- if (!GetDlgItemText(hwndMain, nItem, szItemValue, ITEM_VALUE_MAX_SIZE))
- strcpy(szItemValue, " ");
-
- /* Copy item value in CF_TEXT format to global memory object */
-
- if ((hTextData
- = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)lstrlen(szItemValue)+1))==0)
- return;
- if ((lpTextData = GlobalLock(hTextData)) == NULL)
- {
- GlobalFree(hTextData);
- return;
- }
- lstrcpy(lpTextData, szItemValue);
- GlobalUnlock(hTextData);
-
- /* Copy item value in "Link" format to global memory object */
-
- if ((hConvData
- = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
- (DWORD)APP_MAX_SIZE+TOPIC_MAX_SIZE+ITEM_NAME_MAX_SIZE+4)) == 0)
- return;
- if ((lpConvData = GlobalLock(hConvData)) == NULL)
- {
- GlobalFree(hConvData);
- return;
- }
-
- /* Compose paste link string, each sub-string is null terminated */
- /* Format is <app> <null> <topic> <null> <item> <null> <null> */
- lstrcpy(lpConvData, "Server");
- lpConvData = lpConvData + lstrlen(lpConvData) + 1; /* '+1' adds null */
- lstrcpy(lpConvData, szDocName); /* topic */
- lpConvData += (lstrlen(lpConvData) + 1);
- lstrcpy(lpConvData, "item#");
- lpConvData[4] = '1' + nItem - 1;
- *(lpConvData + lstrlen(lpConvData) + 1) = 0; /* final null */
-
- GlobalUnlock(hConvData);
-
- if (OpenClipboard(hwndMain))
- {
- EmptyClipboard();
-
- SetClipboardData(CF_TEXT, hTextData);
- SetClipboardData(cfLink, hConvData);
-
- CloseClipboard();
- }
- else
- {
- GlobalFree(hTextData);
- GlobalFree(hConvData);
- }
-
- return;
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: FindAdvise
-
- PURPOSE: Find advisory data for a specific conversation item.
-
- ****************************************************************************/
- struct ADVISE * NEAR FindAdvise(hwndServerDDE, nItem)
- HWND hwndServerDDE;
- int nItem;
- {
- struct ADVISE * pAdvise;
- int nAdviseIndex;
-
- for (nAdviseIndex = 0, pAdvise = Advise;
- nAdviseIndex < nAdviseCount;
- nAdviseIndex++, pAdvise++)
- {
- if (pAdvise->hwndServerDDE == hwndServerDDE
- && pAdvise->nItem == nItem)
- {
- return (pAdvise);
- }
- }
- return (NULL);
- }
-
-
-
-
-
- /****************************************************************************
-
- FUNCTION: FindConv
-
- PURPOSE: Find the conversation for a specified server DDE window.
-
- ****************************************************************************/
- struct CONV * NEAR FindConv(hwndServerDDE)
- HWND hwndServerDDE;
- {
- struct CONV * pConv;
- int nConvIndex;
-
- for (nConvIndex = 0, pConv = Conv;
- nConvIndex < nConvCount;
- nConvIndex++, pConv++)
- {
- if (pConv->hwndServerDDE == hwndServerDDE)
- return (pConv);
- }
- return (NULL);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: GetAdviseData
-
- PURPOSE: Get advisory data for a specified conversation item.
-
- ****************************************************************************/
- BOOL GetAdviseData(hwndServerDDE, nItem, szItemName, szItemValue,
- pbDeferUpdate, pbAckRequest)
- HWND hwndServerDDE;
- int nItem;
- char * szItemName;
- char * szItemValue;
- BOOL * pbDeferUpdate;
- BOOL * pbAckRequest;
- {
- struct ADVISE * pAdvise;
-
- if ((pAdvise = FindAdvise(hwndServerDDE, nItem)) == NULL)
- return (FALSE);
- strcpy(szItemName, "Item#");
- szItemName[4] = pAdvise->nItem==1? '1': pAdvise->nItem==2? '2': '3';
- *pbDeferUpdate = pAdvise->bDeferUpdate;
- *pbAckRequest = pAdvise->bAckRequest;
- if (!GetDlgItemText(hwndMain, nItem, szItemValue, ITEM_VALUE_MAX_SIZE))
- strcpy(szItemValue," ");
-
- return (TRUE);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: GetHwndClientDDE
-
- PURPOSE: Get the hwnd of the client in conversation with a specified
- server DDE window.
-
- ****************************************************************************/
- HWND GetHwndClientDDE(hwndServerDDE)
- HWND hwndServerDDE;
- {
- struct CONV * pConv;
-
- if ((pConv = FindConv(hwndServerDDE)) == NULL)
- return (NULL);
- return (pConv->hwndClientDDE);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: GetNextAdvise
-
- PURPOSE: Find a client that needs to be notified that a value of
- a specified item (a hot or warm link item) has changed.
- Since a hot or warm link to the item may have been established
- for multiple conversations (multiple clients), this function
- is set up to step through the list of such conversations.
- Start the list by passing a NULL hwndClientDDE. To get the
- next conversation in the list, pass the previous client returned
- by this function.
-
- ****************************************************************************/
- HWND GetNextAdvise(hwndServerDDE, nItem)
- HWND hwndServerDDE;
- int nItem;
- {
- struct ADVISE * pAdvise;
- int nAdviseIndex;
-
- if (hwndServerDDE)
- {
- for (nAdviseIndex = 0, pAdvise = Advise;
- nAdviseIndex < nAdviseCount;
- nAdviseIndex++, pAdvise++)
- {
- if (pAdvise->hwndServerDDE == hwndServerDDE
- && pAdvise->nItem == nItem)
- {
- pAdvise++;
- break;
- }
- }
- if (nAdviseIndex >= nAdviseCount)
- return (NULL);
- }
- else
- {
- pAdvise = Advise;
- nAdviseIndex = 0;
- }
- for ( ; nAdviseIndex < nAdviseCount; nAdviseIndex++, pAdvise++)
- {
- if (pAdvise->nItem == nItem)
- {
- return (pAdvise->hwndServerDDE);
- }
- }
- return (NULL);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: GetNextConv
-
- PURPOSE: Get next client in list of conversations. To get the
- first hwndServerDDE in the conversation list, pass in a NULL
- value for hwndServerDDE.
-
- ****************************************************************************/
- HWND GetNextConv(hwndServerDDE)
- HWND hwndServerDDE;
- {
- struct CONV * pConv;
- int nConvIndex;
-
- if (hwndServerDDE)
- {
- for (nConvIndex = 0, pConv = Conv;
- nConvIndex < nConvCount;
- nConvIndex++, pConv++)
- {
- if (pConv->hwndServerDDE == hwndServerDDE)
- {
- if (++nConvIndex < nConvCount)
- return (++pConv)->hwndServerDDE;
- else
- return (NULL);
- }
- }
- return (NULL);
- }
- if (nConvCount > 0)
- return (Conv[0].hwndServerDDE);
- else
- return (NULL);
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: GlobalFreeSentData
-
- PURPOSE: A global memory object (hData) was sent in a WM_DDE_DATA
- message, but the client never used it. So, the server is
- responsible for freeing the object.
-
- ****************************************************************************/
- void GlobalFreeSentData(hwndServerDDE, nItem)
- HWND hwndServerDDE;
- int nItem;
- {
- struct ADVISE * pAdvise;
-
- if ((pAdvise = FindAdvise(hwndServerDDE, nItem)) == NULL)
- return;
- pAdvise->bAwaitingAck = FALSE;
- GlobalDeleteAtom(pAdvise->atomItem);
- GlobalFree(pAdvise->hData);
- return;
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: IsConvInTerminateState
-
- PURPOSE: Terminate whether conversation with specified client is
- in process of being terminated.
-
- ****************************************************************************/
- BOOL IsConvInTerminateState(hwndServerDDE)
- HWND hwndServerDDE;
- {
- struct CONV * pConv;
-
- if ((pConv = FindConv(hwndServerDDE))!=0)
- return (pConv->bInClientRequestedTerminate);
- else
- return (FALSE);
- }
-
-
- /****************************************************************************
-
- FUNCTION: RemoveAdvise
-
- PURPOSE: Cancel a hot or warm link for a specified conversation item.
- If a 0 value is specified for nItem, then all hot/warm links
- for the specified client are removed.
-
- ****************************************************************************/
- BOOL RemoveAdvise(hwndServerDDE, nItem)
- HWND hwndServerDDE;
- int nItem;
- {
- struct ADVISE * pAdvise;
- int nAdviseIndex;
- int nRemoveCount;
-
- nRemoveCount = 0;
- for (nAdviseIndex = 0, pAdvise = Advise;
- nAdviseIndex < nAdviseCount;
- nAdviseIndex++, pAdvise++)
- {
- if (nRemoveCount)
- {
- *(pAdvise-nRemoveCount) = *pAdvise;
- }
- if (pAdvise->hwndServerDDE == hwndServerDDE
- && (!nItem || pAdvise->nItem == nItem))
- {
- nRemoveCount++;
- }
-
- }
- if (nRemoveCount)
- {
- nAdviseCount -= nRemoveCount;
- return (TRUE);
- }
- else
- {
- return (FALSE);
- }
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: RemoveConv
-
- PURPOSE: Remove conversation from conversation list, and remove
- all hot/warm links associated with that conversation
- from the advisory list.
-
- ****************************************************************************/
- void RemoveConv(hwndServerDDE)
- HWND hwndServerDDE;
- {
- struct CONV * pConv;
- int nConvIndex;
- struct ADVISE * pAdvise;
- struct ADVISE * pAdviseShift;
- int nAdviseIndex;
- int nAdviseDecrement;
-
- for (nConvIndex = 0, pConv = Conv;
- nConvIndex < nConvCount;
- nConvIndex++, pConv++)
- {
- if (pConv->hwndServerDDE == hwndServerDDE)
- break;
- }
- nConvCount--;
- while (nConvIndex < nConvCount)
- {
- *pConv = *(pConv+1);
- nConvIndex++;
- pConv++;
- }
-
- /* Remove each hot/warm link */
-
- pAdviseShift = Advise;
- nAdviseDecrement = 0;
- for (nAdviseIndex = 0, pAdvise = Advise;
- nAdviseIndex < nAdviseCount;
- nAdviseIndex++, pAdvise++)
- {
- if (pAdvise->hwndServerDDE == hwndServerDDE)
- {
- nAdviseDecrement++;
- if (pAdvise->bAwaitingAck)
- { /* Destroy objects perhaps not destroyed by client */
- GlobalDeleteAtom(pAdvise->atomItem);
- GlobalFree(pAdvise->hData);
- }
- }
- else
- {
- *(pAdviseShift++) = *pAdvise;
- }
- }
- nAdviseCount -= nAdviseDecrement;
- return;
- }
-
-
-
- /****************************************************************************
-
- FUNCTION: SetConvInTerminateState
-
- PURPOSE: Set conversations's terminate state to TRUE.
-
- ****************************************************************************/
- void SetConvInTerminateState(hwndServerDDE)
- HWND hwndServerDDE;
- {
- struct CONV * pConv;
-
- if ((pConv = FindConv(hwndServerDDE))!=0)
- pConv->bInClientRequestedTerminate = TRUE;
- return;
- }
-